www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Rails-like Model in D (making it "automagical")

reply Chris Miller <lordSaurontheGreat gmail.com> writes:
I've been throwing ideas around in my head for my pet project, ConYard
(http://www.fsdev.net/wiki/conyard), and I'm not sure how to implement this in
D.  I don't really know how to implement it in any language, so I thought I'd
ask for some advice.

I want to create a model system similar to, though perhaps not necessarily as
"automagical" as the models from Ruby on Rails.  I want a system that the
programmer can extend to create a database-independent object that serializes
to a database.  The problem I'm grappling with is how to make it so that the
user doesn't have to hand-code everything, and can make the implementation more
readable.

I'm not sure how to handle the model's fields.  I want the fields to be D
types, eg. char[] and int and float and all that.  I also want for those types
to serialize to the SQL database, without the user having to write all that
nonsense by hand.

I need a way to somehow flag a field in a model as an element that needs to be
serialized to a database.  From there it's fairly simple work of writing code
that makes SQL statements based on input.  It's so simple, it scares me into
over complicating it.

I'm not sure how to start about this.  I was thinking of some kind of static
this () statement that the user has to fill in, and somehow "register" all the
elements (that'll be in the database).  Then calls to functions that push/pull
data to/from the database could call another function that the user doesn't
have to touch, which takes all those elements from the model instance and
generates the SQL queries (or uses a previously generated one) to make the data
move.

It still seems like a lot of overhead to me, like a lot of boring stuff that
the programmer has to type in all the time.  Imagine a library where you have
to do something annoying like registerElement(IntElement(this.myfield)); in a
static constructor all the time?  (IntElement would be some kind of element
class that would know how to take a D int and make it to a SQL int, and then
you could possibly write your own to take types that you make and translate
them into SQL types, or serializations that fit into SQL types, etc).

There must be a better way.  I've scanned through the D 1.00 specification
document a few times and come up dry.  If anyone has any suggestions of things
I might try, or even examples of techniques that I could use, I'd really
appreciate it!
Mar 23 2008
next sibling parent reply Bjoern <nanali nospam-wanadoo.fr> writes:
So, you have a year of time and are interrested to implement a RAD 
system around enterprise patterns ?  :)

Rails :
As you know Rails is based on the active record pattern.
I found it remarkable that all "actice record" implementations (I know 
about) are script based. Ruby, Groovy, PHP.

I am sceptical regarding a pure D implementation. Maybe embedding MiniD 
   is a reasonable solution.

But you want RAD / DWT / Tango :

My advice is a) not to use the active record pattern and b) wait for DWT 
3.4  // google SWT 3.4 databinding

To create a RAD you have to bind the GUI elements like entry fields, 
checkboxes etc. to a db entity. (at least)
IMO The only reasonable solution is using the MVC pattern. Beside, it is 
not nessesary to sepereate View Controler.
In other words the good ol' Subject-Observer pattern. I can imagine that 
  probabely Tango's Signal-Slot can be used too. (Have to think about)

What to use instead of active record ?
DAO Data Access Objects, have a look at the Java implementation. or 
google for Java DAO

In general DAO is build arround the 1) Singleton pattern and 2) the 
factory pattern. (IMO the prototype pattern is the better choice)
DDBI is somewhat similar.

Consider code generation . In other words you need a tool to scan the DB 
System tables and generate D source code - classes which implement ORM 
using the factory method pattern (ORM ->object relational mapping).

The best source reagarding real world pattern is :
http://www.dofactory.com/Patterns/Patterns.aspx
(C# code. Allmost a piece of cake to port)

Sorry, for this unstructured message, but actually I have nearly zero 
time for programming. Bjoern






Chris Miller schrieb:
 I've been throwing ideas around in my head for my pet project, ConYard
(http://www.fsdev.net/wiki/conyard), and I'm not sure how to implement this in
D.  I don't really know how to implement it in any language, so I thought I'd
ask for some advice.
 
 I want to create a model system similar to, though perhaps not necessarily as
"automagical" as the models from Ruby on Rails.  I want a system that the
programmer can extend to create a database-independent object that serializes
to a database.  The problem I'm grappling with is how to make it so that the
user doesn't have to hand-code everything, and can make the implementation more
readable.
 
 I'm not sure how to handle the model's fields.  I want the fields to be D
types, eg. char[] and int and float and all that.  I also want for those types
to serialize to the SQL database, without the user having to write all that
nonsense by hand.
 
 I need a way to somehow flag a field in a model as an element that needs to be
serialized to a database.  From there it's fairly simple work of writing code
that makes SQL statements based on input.  It's so simple, it scares me into
over complicating it.
 
 I'm not sure how to start about this.  I was thinking of some kind of static
this () statement that the user has to fill in, and somehow "register" all the
elements (that'll be in the database).  Then calls to functions that push/pull
data to/from the database could call another function that the user doesn't
have to touch, which takes all those elements from the model instance and
generates the SQL queries (or uses a previously generated one) to make the data
move.
 
 It still seems like a lot of overhead to me, like a lot of boring stuff that
the programmer has to type in all the time.  Imagine a library where you have
to do something annoying like registerElement(IntElement(this.myfield)); in a
static constructor all the time?  (IntElement would be some kind of element
class that would know how to take a D int and make it to a SQL int, and then
you could possibly write your own to take types that you make and translate
them into SQL types, or serializations that fit into SQL types, etc).
 
 There must be a better way.  I've scanned through the D 1.00 specification
document a few times and come up dry.  If anyone has any suggestions of things
I might try, or even examples of techniques that I could use, I'd really
appreciate it!

Mar 24 2008
next sibling parent Bjoern <nanali nospam-wanadoo.fr> writes:
DAO Java :
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

at the eof the document you'll find a ref. to the  :
Factory Method [GoF] and Abstract Factory [GoF]

You can use the link in the prev. msg. to see a real world implementation;
hth Bjoern
Mar 24 2008
prev sibling parent reply Frank Benoit <keinfarbton googlemail.com> writes:
Bjoern schrieb:
 But you want RAD / DWT / Tango :
 
 My advice is a) not to use the active record pattern and b) wait for DWT 
 3.4  // google SWT 3.4 databinding

Data binding is a JFace technology. "JFace Data Binding 1.0 was releaseed with Eclipse 3.3" http://www.eclipse.org/swt/R3_4/new_and_noteworthy.html http://wiki.eclipse.org/index.php/JFace_Data_Binding I don't see how this is a requirement or even related to a "Rail-like Model in D" ? So, why "wait for DWT 3.4" ?
Mar 24 2008
parent Bjoern <nanali nospam-wanadoo.fr> writes:
Frank Benoit schrieb:
 Bjoern schrieb:
 But you want RAD / DWT / Tango :

 My advice is a) not to use the active record pattern and b) wait for 
 DWT 3.4  // google SWT 3.4 databinding

Data binding is a JFace technology. "JFace Data Binding 1.0 was releaseed with Eclipse 3.3" http://www.eclipse.org/swt/R3_4/new_and_noteworthy.html

 http://wiki.eclipse.org/index.php/JFace_Data_Binding

....The core concepts behind the project are Observables and Bindings. We provide IObservable implementations for SWT, JFace, and JavaBeans.... end quote Means IMO : Binding interfaces have to be be stripped out.
 
 I don't see how this is a requirement or even related to a "Rail-like 
 Model in D" ? So, why "wait for DWT 3.4" ?
 

I am wrong with "waiting for 3.4." Sorry :( However, this discussion also touches DWT event-handling. (your msg on Digitalmars.dwt) and it seems to me that the suggested implementation is working well even in case that you have to deal with new, binding- related events. As said,not much time for programming. I am restaurating my "farm" and the barnes
Mar 24 2008
prev sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Chris Miller wrote:
 I've been throwing ideas around in my head for my pet project, ConYard
(http://www.fsdev.net/wiki/conyard), and I'm not sure how to implement this in
D.  I don't really know how to implement it in any language, so I thought I'd
ask for some advice.
 
 I want to create a model system similar to, though perhaps not necessarily as
"automagical" as the models from Ruby on Rails.  I want a system that the
programmer can extend to create a database-independent object that serializes
to a database.  The problem I'm grappling with is how to make it so that the
user doesn't have to hand-code everything, and can make the implementation more
readable.
 
 I'm not sure how to handle the model's fields.  I want the fields to be D
types, eg. char[] and int and float and all that.  I also want for those types
to serialize to the SQL database, without the user having to write all that
nonsense by hand.
 
 I need a way to somehow flag a field in a model as an element that needs to be
serialized to a database.  From there it's fairly simple work of writing code
that makes SQL statements based on input.  It's so simple, it scares me into
over complicating it.
 
 I'm not sure how to start about this.  I was thinking of some kind of static
this () statement that the user has to fill in, and somehow "register" all the
elements (that'll be in the database).  Then calls to functions that push/pull
data to/from the database could call another function that the user doesn't
have to touch, which takes all those elements from the model instance and
generates the SQL queries (or uses a previously generated one) to make the data
move.
 
 It still seems like a lot of overhead to me, like a lot of boring stuff that
the programmer has to type in all the time.  Imagine a library where you have
to do something annoying like registerElement(IntElement(this.myfield)); in a
static constructor all the time?  (IntElement would be some kind of element
class that would know how to take a D int and make it to a SQL int, and then
you could possibly write your own to take types that you make and translate
them into SQL types, or serializations that fit into SQL types, etc).
 
 There must be a better way.  I've scanned through the D 1.00 specification
document a few times and come up dry.  If anyone has any suggestions of things
I might try, or even examples of techniques that I could use, I'd really
appreciate it!

Ruby ( and Python ) both have run-time reflection built in to their language. D does not. I would suggest to you that emulating RAD programming with a language which does not have built-in support for run-time reflection will be a very hard task for you to accomplish.
Mar 24 2008
parent Lars Ivar Igesund <larsivar igesund.net> writes:
Edward Diener wrote:

 Chris Miller wrote:
 I've been throwing ideas around in my head for my pet project, ConYard
 (http://www.fsdev.net/wiki/conyard), and I'm not sure how to implement
 this in D.  I don't really know how to implement it in any language, so I
 thought I'd ask for some advice.
 
 I want to create a model system similar to, though perhaps not
 necessarily as "automagical" as the models from Ruby on Rails.  I want a
 system that the programmer can extend to create a database-independent
 object that serializes to a database.  The problem I'm grappling with is
 how to make it so that the user doesn't have to hand-code everything, and
 can make the implementation more readable.
 
 I'm not sure how to handle the model's fields.  I want the fields to be D
 types, eg. char[] and int and float and all that.  I also want for those
 types to serialize to the SQL database, without the user having to write
 all that nonsense by hand.
 
 I need a way to somehow flag a field in a model as an element that needs
 to be serialized to a database.  From there it's fairly simple work of
 writing code that makes SQL statements based on input.  It's so simple,
 it scares me into over complicating it.
 
 I'm not sure how to start about this.  I was thinking of some kind of
 static this () statement that the user has to fill in, and somehow
 "register" all the elements (that'll be in the database).  Then calls to
 functions that push/pull data to/from the database could call another
 function that the user doesn't have to touch, which takes all those
 elements from the model instance and generates the SQL queries (or uses a
 previously generated one) to make the data move.
 
 It still seems like a lot of overhead to me, like a lot of boring stuff
 that the programmer has to type in all the time.  Imagine a library where
 you have to do something annoying like
 registerElement(IntElement(this.myfield)); in a static constructor all
 the time?  (IntElement would be some kind of element class that would
 know how to take a D int and make it to a SQL int, and then you could
 possibly write your own to take types that you make and translate them
 into SQL types, or serializations that fit into SQL types, etc).
 
 There must be a better way.  I've scanned through the D 1.00
 specification document a few times and come up dry.  If anyone has any
 suggestions of things I might try, or even examples of techniques that I
 could use, I'd really appreciate it!

Ruby ( and Python ) both have run-time reflection built in to their language. D does not. I would suggest to you that emulating RAD programming with a language which does not have built-in support for run-time reflection will be a very hard task for you to accomplish.

Not a terribly hard thing to get around, given the correct tools. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Mar 24 2008