So during last week I had the flu. A pretty nasty one at that. While that stopped me pretty much programming during it, it did allow me to gain a new perspective on things.
I took another look at Cmsed's status. And I found the user authentication lacking. That the generation of javascript also quite lacking.
To fix this I completed the query generation of data models. I haven't precisely tested it live, but I believe if it doesn't work correctly it can be made to.
Further a few fixes for routes javascript generation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module cmsed.test.models.book; | |
import cmsed.base; | |
import dvorm; | |
@dbName("Books3") | |
class Book3 { | |
@dbId | |
@dbName("") | |
Book3Id key = new Book3Id; | |
@dbDefaultValue("0") | |
ubyte edition; | |
void t() {} | |
@dbIgnore | |
string something; | |
mixin OrmModel!Book3; | |
} | |
class Book3Id { | |
@dbId { | |
@dbName("id") | |
string isbn; | |
} | |
} | |
class Page3 { | |
@dbId | |
@dbName("_id") | |
string id; | |
@dbName("book") | |
@dbActualModel!(Book3, "key") | |
Book3Id book = new Book3Id; | |
mixin OrmModel!Page3; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://localhost:8080/public/js/models/books3 | |
var Books3 = Class({ | |
constructor: function(_id, edition) { | |
this._id = _id === undefined ? "" : _id; | |
this.edition = Number(edition === undefined ? "0" : edition); | |
}, | |
save: function() { | |
var this_ = this; | |
new Ajax.Request("/.svc/Books3/" + this._id, { | |
method: "POST", | |
parameters: { | |
_id: this_._id | |
}, | |
onSuccess: function(event) { | |
onSaveOfObject(this_, event); | |
}, | |
onFailure: function(event) { | |
onFailureToSaveObject(this_, event); | |
} | |
}); | |
}, | |
remove: function() { | |
var this_ = this; | |
new Ajax.Request("/.svc/Books3/" + this._id, { | |
method: "DELETE", | |
onSuccess: function(event) { | |
onDeleteOfObject(this_, event); | |
}, | |
onFailure: function(event) { | |
onFailureToDeleteObject(this_, event); | |
} | |
}); | |
} | |
}); | |
Books3.prototype.findOne = function(_id) { | |
var ret = new Ajax.Request("/.svc/Books3/" + _id, { | |
method: "GET", | |
asynchronous: false | |
}); | |
ret = ret.responseJSON(); | |
return new Books3(ret._id); | |
}; | |
Books3.prototype.query = function() { | |
return { | |
props: { | |
_id_eq: undefined, | |
_id_neq: undefined, | |
_id_lt: undefined, | |
_id_lte: undefined, | |
_id_mt: undefined, | |
_id_mte: undefined, | |
_id_like: undefined, | |
edition_eq: undefined, | |
edition_neq: undefined, | |
edition_lt: undefined, | |
edition_lte: undefined, | |
edition_mt: undefined, | |
edition_mte: undefined, | |
edition_like: undefined | |
}, | |
offset: undefined, | |
maxAmount: undefined, | |
find: function () { | |
this_ = this; | |
var ret = new Ajax.Request("/.svc/Books3/", { | |
method: "POST", | |
parameters: { | |
_id_eq: this_.props._id_eq, | |
_id_neq: this_.props._id_neq, | |
_id_lt: this_.props._id_lt, | |
_id_lte: this_.props._id_lte, | |
_id_mt: this_.props._id_mt, | |
_id_mte: this_.props._id_mte, | |
_id_like: this_.props._id_like, | |
edition_eq: this_.props.edition_eq, | |
edition_neq: this_.props.edition_neq, | |
edition_lt: this_.props.edition_lt, | |
edition_lte: this_.props.edition_lte, | |
edition_mt: this_.props.edition_mt, | |
edition_mte: this_.props.edition_mte, | |
edition_like: this_.props.edition_like, | |
__offset: this_.offset, | |
__maxAmount: this_.maxAmount | |
}, | |
onSuccess: function (event) { | |
}, | |
onFailure: function (event) { | |
} | |
}); | |
ret = ret.responseJSON(); | |
} | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module cmsed.test.routes.test; | |
import cmsed.base; | |
import cmsed.test.models; | |
import vibe.d : Json; | |
@jsRouteName("test_route") | |
class Test : OORoute { | |
@RouteFunction(RouteType.Get, "/") | |
void index() { | |
http_response.writeBody(""); | |
} | |
@RouteFunction(RouteType.Get, "/myindex", "index") | |
bool myindex() { | |
return true; | |
} | |
@RouteGroup(null, "/.svc") { | |
mixin RestfulRoute!(RestfulProtection.All, Book3, Page3); | |
} | |
@RouteFunction(RouteType.Get, "/someargs") | |
void someArgs(string a, string b) { | |
http_response.writeBody(a ~ ", " ~ b); | |
} | |
@RouteFunction(RouteType.Get, "/mytext") | |
string myText() { | |
return "Hello World!"; | |
} | |
@RouteFunction(RouteType.Get, "/myjson") | |
Json myJson() { | |
Json ret = Json.emptyObject(); | |
ret["Hello"] = Json("World!"); | |
return ret; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://localhost:8080/public/js/routes/test_route | |
function index() { | |
var ret = new Ajax.Request("/", { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function myindex() { | |
var ret = new Ajax.Request("/myindex", { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataBook3Get(key) { | |
var ret = new Ajax.Request("/.svc" + "/Books3" + "/" + key, { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataBook3Query(_id_eq, _id_neq, _id_mt, _id_lt, _id_mte, _id_lte, _id_like, edition_eq, edition_neq, edition_mt, edition_lt, edition_mte, edition_lte, edition_like, __maxAmount, __offset) { | |
var ret = new Ajax.Request("/.svc" + "/Books3", { | |
method: "post", | |
parameters: { | |
"_id_eq": _id_eq, | |
"_id_neq": _id_neq, | |
"_id_mt": _id_mt, | |
"_id_lt": _id_lt, | |
"_id_mte": _id_mte, | |
"_id_lte": _id_lte, | |
"_id_like": _id_like, | |
"edition_eq": edition_eq, | |
"edition_neq": edition_neq, | |
"edition_mt": edition_mt, | |
"edition_lt": edition_lt, | |
"edition_mte": edition_mte, | |
"edition_lte": edition_lte, | |
"edition_like": edition_like, | |
"__maxAmount": __maxAmount, | |
"__offset": __offset | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataBook3Create(_id, edition) { | |
var ret = new Ajax.Request("/.svc" + "/Books3", { | |
method: "put", | |
parameters: { | |
"_id": _id, | |
"edition": edition | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataBook3Modify(key, _id, edition) { | |
var ret = new Ajax.Request("/.svc" + "/Books3" + "/" + key, { | |
method: "post", | |
parameters: { | |
"_id": _id, | |
"edition": edition | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataBook3Delete(key) { | |
var ret = new Ajax.Request("/.svc" + "/Books3" + "/" + key, { | |
method: "delete", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataPage3Get(key) { | |
var ret = new Ajax.Request("/.svc" + "/Page3" + "/" + key, { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataPage3Query(_id_eq, _id_neq, _id_mt, _id_lt, _id_mte, _id_lte, _id_like, book_id_eq, book_id_neq, book_id_mt, book_id_lt, book_id_mte, book_id_lte, book_id_like, __maxAmount, __offset) { | |
var ret = new Ajax.Request("/.svc" + "/Page3", { | |
method: "post", | |
parameters: { | |
"_id_eq": _id_eq, | |
"_id_neq": _id_neq, | |
"_id_mt": _id_mt, | |
"_id_lt": _id_lt, | |
"_id_mte": _id_mte, | |
"_id_lte": _id_lte, | |
"_id_like": _id_like, | |
"book_id_eq": book_id_eq, | |
"book_id_neq": book_id_neq, | |
"book_id_mt": book_id_mt, | |
"book_id_lt": book_id_lt, | |
"book_id_mte": book_id_mte, | |
"book_id_lte": book_id_lte, | |
"book_id_like": book_id_like, | |
"__maxAmount": __maxAmount, | |
"__offset": __offset | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataPage3Create(_id, book_id) { | |
var ret = new Ajax.Request("/.svc" + "/Page3", { | |
method: "put", | |
parameters: { | |
"_id": _id, | |
"book_id": book_id | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataPage3Modify(key, _id, book_id) { | |
var ret = new Ajax.Request("/.svc" + "/Page3" + "/" + key, { | |
method: "post", | |
parameters: { | |
"_id": _id, | |
"book_id": book_id | |
} | |
}); | |
return ret.responseText() | |
} | |
function handleRestfulDataPage3Delete(key) { | |
var ret = new Ajax.Request("/.svc" + "/Page3" + "/" + key, { | |
method: "delete", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function someArgs(a, b) { | |
var ret = new Ajax.Request("/someargs", { | |
method: "get", | |
parameters: { | |
"a": a, | |
"b": b | |
} | |
}); | |
return ret.responseText() | |
} | |
function myText() { | |
var ret = new Ajax.Request("/mytext", { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} | |
function myJson() { | |
var ret = new Ajax.Request("/myjson", { | |
method: "get", | |
parameters: { | |
} | |
}); | |
return ret.responseText() | |
} |
To help with the javascript, as its quite 'large' I ported a minifier to D from. It was quite a nice one and worked first time surprisingly. However because of it being PHP it meant I had to live deduct its types and fix them as required. Also it was quite a nasty surprise to discover that it was designed for not just ASCII this meant changing everything to wchar/wstring. In turn making conversion a bit of a hassle.
Its available by default for static javascript files during a release build. There is nothing to configure or disable with regards to it.
Yesterday I worked upon a very new (unplanned) feature that being policies for users and groups. It means that you have the ability to apply rules to groups and specific users at runtime. A policy is essentially just a name. However a policy can be applied to a user/group but disabled if for some reason it was wanted.
Today I was working upon two projects. My actors for D (Dakka) and Cmsed again. Unfortunately some weird bugs came up with Dvorm so that had to be fixed.
For Cmsed adding of a base for database storage of all nodes being operated was added. This will be used by Dakka to know what other nodes are out there. The specific capabilities will be pushed into configuration later.
For Dakka I begun by fixing up a bug or two that was left over from previous testing involving pack-d. Next was to begin work on support for remote calls to other nodes. Initially and as of this writing there is no security being pushed over it. Considering that this system should be secured within a private server network its not of a top priority. However it shouldn't be too hard thanks to Vibe.
At this point Dakka needs to make remotes work is two parts. Queues to handle getting requests/responses via sockets. Lastly a load distributor. I have a very clever and simple trick. First when connect a time packet will be sent to compare times on each system. This is an offset. For every request after it, it'll be negated off the value. Every two iterations of the socket's loop a new time packet will be sent and hence checked. Once it gets too high it'll be considered read only in terms of new addresses till it gets down again.
Once Dakka has working node communication for remotes I will consider it feature complete. And hence will go up on github. Furthermore it'll be integrated into Cmsed. And with that some really neat features for larger web services will become available.
What I'll probably do is add support for managing docker containers (think VMs). Which would have some rather nice side effects like easily building a web service to do compilation.
There is something bothering me however. Its about Dvorm. Not so much what it does now, but what it should probably do. The whole idea of not currently supporting relational databases really really scares me. And each design I have to solve this doesn't fit right. So I'm coming to the conclusion that there is no way I can personally take care of the differences between the databases. I'm also worried that a lot of code I write using queries really should be e.g. inner joins if it were sql. And the current query syntax doesn't support this. But I have the relationship UDA's so in theory it should be possible to do:
.query().id_eq("123456789").get_prop();
Instead of:
.query().id_eq("123456789").findAll()[0].prop.getType();
Type of deal. With quite a bit of user created code in that.
One other syntax I would like to support:
ChildType.query().timeSet_lt(oneHourAgo).findAll_parentTypeProp which would:
For every child that is older than one hour return its parents value based upon its value in property.
But this is just some ramblings at like half past four in the morning of some crazy ideas I have floating around.
No comments:
Post a Comment