www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DB ORM

reply Jonas Drewsen <jdrewsen nospam.com> writes:
Just stumbled upon this db orm for c++ that uses the gcc frontend to 
rewrite c++ code to make classes suitable for database access.

http://www.codesynthesis.com/products/odb/

They are using pragmas to accomplish this. I guess an equally good 
implementation in D would use custom attributes for this once (if) they 
are supported.

/Jonas
Aug 09 2011
next sibling parent simendsjo <simendsjo gmail.com> writes:
On 09.08.2011 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
I would think/hope Ds compile-time reflection should be able to do this without compiler support (haven't checked the link). Having user defined properties would help a lot too.
Aug 09 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-08-09 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
I'm pretty sure you can create an ORM library like that with what we already have in D today. If needed, mixins can be used like custom attributes, but it will look very ugly. -- /Jacob Carlborg
Aug 09 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-08-09 14:19, Jacob Carlborg wrote:
 On 2011-08-09 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
I'm pretty sure you can create an ORM library like that with what we already have in D today. If needed, mixins can be used like custom attributes, but it will look very ugly.
I can also add that I think D can do a lot better job than C++ with this ODB library. I think it would be possible to do this: class Person : Model {} And let the super class get all info from the database, just like ActiveRecord in Ruby on Rails. -- /Jacob Carlborg
Aug 09 2011
parent reply Robert McGinley <mcginley.robert gmail.com> writes:
I think a better model to follow would be SQL alchemy which allows you to te=
st the tables or "declaratively" set columns as attributes of the model.

Rob

Sent from my iPad

On Aug 9, 2011, at 8:32 AM, Jacob Carlborg <doob me.com> wrote:

 On 2011-08-09 14:19, Jacob Carlborg wrote:
 On 2011-08-09 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.
=20
 http://www.codesynthesis.com/products/odb/
=20
 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.
=20
 /Jonas
=20 I'm pretty sure you can create an ORM library like that with what we already have in D today. If needed, mixins can be used like custom attributes, but it will look very ugly.
=20 I can also add that I think D can do a lot better job than C++ with this O=
DB library. I think it would be possible to do this:
=20
 class Person : Model {}
=20
 And let the super class get all info from the database, just like ActiveRe=
cord in Ruby on Rails.
=20
 --=20
 /Jacob Carlborg
Aug 09 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-08-09 15:07, Robert McGinley wrote:
 I think a better model to follow would be SQL alchemy which allows you to test
the tables or "declaratively" set columns as attributes of the model.
You mean that the columns of a table should be declared as attributes of the corresponding class? Hmm, I don't know, I like that Rails way.
 Rob

 Sent from my iPad

 On Aug 9, 2011, at 8:32 AM, Jacob Carlborg<doob me.com>  wrote:

 On 2011-08-09 14:19, Jacob Carlborg wrote:
 On 2011-08-09 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
I'm pretty sure you can create an ORM library like that with what we already have in D today. If needed, mixins can be used like custom attributes, but it will look very ugly.
I can also add that I think D can do a lot better job than C++ with this ODB library. I think it would be possible to do this: class Person : Model {} And let the super class get all info from the database, just like ActiveRecord in Ruby on Rails. -- /Jacob Carlborg
-- /Jacob Carlborg
Aug 09 2011
parent Robert McGinley <mcginley.robert gmail.com> writes:
Ya, I like that way too. SQL alchemy allows you to also do it the rails way
also.  The declarative stuff is for more explicit models. It is also good
for when there is a db table for which you don't want to load all the
columns. Granted those use cases aren't as common. So the point may be
moot.... And why does apple think it can correct my grammar. Grr.

Rob

On Tuesday, August 9, 2011, Jacob Carlborg <doob me.com> wrote:
 On 2011-08-09 15:07, Robert McGinley wrote:
 I think a better model to follow would be SQL alchemy which allows you to
test the tables or "declaratively" set columns as attributes of the model.
 You mean that the columns of a table should be declared as attributes of
the corresponding class? Hmm, I don't know, I like that Rails way.
 Rob

 Sent from my iPad

 On Aug 9, 2011, at 8:32 AM, Jacob Carlborg<doob me.com>  wrote:

 On 2011-08-09 14:19, Jacob Carlborg wrote:
 On 2011-08-09 09:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/ <
http://www.codesynthesis.com/products/odb/>
 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if)
they
 are supported.

 /Jonas
I'm pretty sure you can create an ORM library like that with what we already have in D today. If needed, mixins can be used like custom attributes, but it will look very ugly.
I can also add that I think D can do a lot better job than C++ with this
ODB library. I think it would be possible to do this:
 class Person : Model {}

 And let the super class get all info from the database, just like
ActiveRecord in Ruby on Rails.
 --
 /Jacob Carlborg
-- /Jacob Carlborg
Aug 09 2011
prev sibling next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 09/08/2011 08:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
How ugly! My (far from complete, but good enough to demonstrate what D can do) ORM is far simpler than that: https://github.com/mrmonday/serenity (actually a web framework, includes an incomplete ORM) ---- struct Post { ulong id; DateTime dt; string title; string content; } Persister!Post posts; // Append a post posts ~= Post(0, someDateTime, "A title", "Some content"); foreach (post; posts[0..5]) { // Iterate over the first 5 posts } post[3] = posts[2]; ---- All SQL is generated at compile time, and the backend database is called directly - that's less overhead than you'd get from a typical scripting language accessing a database directly (no need to convert between types first). -- Robert http://octarineparrot.com/
Aug 09 2011
parent jdrewsen <jdrewsen nospam.com> writes:
Den 09-08-2011 21:15, Robert Clipsham skrev:
 On 09/08/2011 08:30, Jonas Drewsen wrote:
 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
How ugly! My (far from complete, but good enough to demonstrate what D can do) ORM is far simpler than that: https://github.com/mrmonday/serenity (actually a web framework, includes an incomplete ORM) ---- struct Post { ulong id; DateTime dt; string title; string content; } Persister!Post posts; // Append a post posts ~= Post(0, someDateTime, "A title", "Some content"); foreach (post; posts[0..5]) { // Iterate over the first 5 posts } post[3] = posts[2]; ---- All SQL is generated at compile time, and the backend database is called directly - that's less overhead than you'd get from a typical scripting language accessing a database directly (no need to convert between types first).
Very nice. I have to give that a look for sure. /Jonas
Aug 09 2011
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
Jonas Drewsen Wrote:

 Just stumbled upon this db orm for c++ that uses the gcc frontend to 
 rewrite c++ code to make classes suitable for database access.
 
 http://www.codesynthesis.com/products/odb/
 
 They are using pragmas to accomplish this. I guess an equally good 
 implementation in D would use custom attributes for this once (if) they 
 are supported.
 
 /Jonas
If there's no mapping, that's bad. A database is a product on its own. It doesn't have to be what you'd like it to be. Objects can correspond to tables quite vaguely. The database may have tricky legacy conventions you don't want to have in your code directly. What about deletion and creation if you have hierarchy of types and objects? What if and object is split between joined tables? Inner joined or left joined.
Aug 09 2011
parent Jonas Drewsen <jdrewsen nospam.com> writes:
On 10/08/11 06.47, Kagamin wrote:
 Jonas Drewsen Wrote:

 Just stumbled upon this db orm for c++ that uses the gcc frontend to
 rewrite c++ code to make classes suitable for database access.

 http://www.codesynthesis.com/products/odb/

 They are using pragmas to accomplish this. I guess an equally good
 implementation in D would use custom attributes for this once (if) they
 are supported.

 /Jonas
If there's no mapping, that's bad. A database is a product on its own. It doesn't have to be what you'd like it to be. Objects can correspond to tables quite vaguely. The database may have tricky legacy conventions you don't want to have in your code directly. What about deletion and creation if you have hierarchy of types and objects? What if and object is split between joined tables? Inner joined or left joined.
I'm not sure I understand. Are you against using DB ORMs in general? ORM is certainly not a perfect mapping of a database and have plenty of shortcomings. Deletion and creation of hierarchies is actually handled by some ORMs and there are ways to handle joins as well. I've not actively used the C++ ORM myself but have been using python storm, ruby active record etc. Most of them really makes your code more lean and readable. In the special cases where a simple mapping is not enough (performance or feature wise) you can always fall back to standard SQL queries. /Jonas
Aug 09 2011
prev sibling parent reply zhang <bitworld qq.com> writes:
About ORM, 
the Python has SQLObject (http://sqlobject.org/), 
the Java has Hibernate (http://www.hibernate.org/), 

(http://msdn.microsoft.com/en-us/data/aa937723).

The D maybe also need one. Glad to see someone being interesting in this.
----------
Zhang <bitworld qq.com>
Aug 10 2011
next sibling parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
zhang wrote:
 About ORM,
 the Python has SQLObject (http://sqlobject.org/),
 the Java has Hibernate (http://www.hibernate.org/),

(http://msdn.microsoft.com/en-us/data/aa937723).

 The D maybe also need one. Glad to see someone being interesting in this.
I think D needs user defined attributes first.
Aug 10 2011
next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 10.08.2011, 16:01 Uhr, schrieb Piotr Szturmaj <bncrbme jadamspam.pl>:

 zhang wrote:
 About ORM,
 the Python has SQLObject (http://sqlobject.org/),
 the Java has Hibernate (http://www.hibernate.org/),

 (http://msdn.microsoft.com/en-us/data/aa937723).

 The D maybe also need one. Glad to see someone being interesting in  
 this.
I think D needs user defined attributes first.
When I think about all the attributes I set on fields in Java code for Hibernate you may actually be right. Even without inheritance and more arcane stuff I would expect to be able to define some relations between objects/tables, so associated data can be fetched either eagerly or lazily. Where lazily is the minimum, because eager may just as well load the whole database into memory. Then you get into the trouble of having n-to-m associations and the need for a cache. I believe it is a lot of work for a single person to create something of the quality of Hibernate. An intermediate step may be appropriate, where all the automatic glue is still done by the programmer. Caching, associations, inheritance and the like. The "Persister" looks to me like just that and with the CTFE abilities it could not have less overhead which is a selling point.
Aug 10 2011
parent reply zhang <bitworld qq.com> writes:
 I think D needs user defined attributes first.
About attribute, here is an example: class ClassA { private int m_data; property int data() { return m_data; } property int data(int value) { return m_data = value; } } int main(string[] args) { ClassA aClass = new ClassA(); aClass.data = 22; writefln("%d", aClass.data); return 0; } ======================== integer type can be defined as "Int?" or "Nullable<int>".
 I believe it is a lot of work for a single person to create something of  
 the quality of Hibernate. An intermediate step may be appropriate, where  
 all the automatic glue is still done by the programmer.
Have some guys started the first step works? ---------- Zhang <bitworld qq.com>
Aug 11 2011
next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 11.08.2011, 14:10 Uhr, schrieb zhang <bitworld qq.com>:

 I believe it is a lot of work for a single person to create something of
 the quality of Hibernate. An intermediate step may be appropriate, where
 all the automatic glue is still done by the programmer.
Have some guys started the first step works?
There is Robert "mrmonday" Clipsham's "serenity" web framework: https://github.com/mrmonday/serenity It uses all the compile-time goodies in D so you can for example write a foreach that fetches and iterates over rows 1 to 20 in your table. In your program the rows are represented as D structs (or objects?).
Aug 11 2011
prev sibling next sibling parent reply Graham Fawcett <fawcett uwindsor.ca> writes:
On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:

 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Aug 11 2011
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Graham Fawcett wrote.
 On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:

 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Alternatively you just use a class to wrap the value: template Nullable(T){ static if(is(T == class)) alias T Nullable; else class Nullable{T v; alias v this;} } The benefit of this approach is that you don't have to invent new ways to test for null values.
Aug 11 2011
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Thu, 11 Aug 2011 15:32:20 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:

 Graham Fawcett wrote.
 On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:

 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Alternatively you just use a class to wrap the value: template Nullable(T){ static if(is(T == class)) alias T Nullable; else class Nullable{T v; alias v this;} } The benefit of this approach is that you don't have to invent new ways to test for null values.
Or, you know, a simple pointer? Avoids some of the overhead of the class solution. -- Simen
Aug 11 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
Simen Kjaeraas wrote:
 On Thu, 11 Aug 2011 15:32:20 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:

 Graham Fawcett wrote.
 On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:

 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Alternatively you just use a class to wrap the value: template Nullable(T){ static if(is(T == class)) alias T Nullable; else class Nullable{T v; alias v this;} } The benefit of this approach is that you don't have to invent new ways to test for null values.
Or, you know, a simple pointer? Avoids some of the overhead of the class solution. -- Simen
Well, sure. :) But he was specifically asking for a nullable reference akin to what you get in I don't see how it is useful anyways.
Aug 11 2011
prev sibling parent reply zhang <bitworld qq.com> writes:
 Graham Fawcett wrote.
 On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:

 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Alternatively you just use a class to wrap the value: template Nullable(T){ static if(is(T == class)) alias T Nullable; else class Nullable{T v; alias v this;} } The benefit of this approach is that you don't have to invent new ways to test for null values.
That's it. So, the nullable basic type is not a problem. Thanks. ---------- Zhang <bitworld qq.com>
Aug 12 2011
parent kennytm <kennytm gmail.com> writes:
zhang <bitworld qq.com> wrote:
 Graham Fawcett wrote.
 On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:
 
 I think D needs user defined attributes first.
About attribute, here is an example: .... the nullable integer type can be defined as "Int?" or "Nullable<int>".
You don't need attributes for that: you can just define a "struct Nullable(T)" that wraps the value, and provides a way to express a null value. struct Person { int ID; // required Nullable!int age; // optional ... } void foo(Person p) { if (p.age.isNull) ... else writeln(p.age + 100); } Graham
Alternatively you just use a class to wrap the value: template Nullable(T){ static if(is(T == class)) alias T Nullable; else class Nullable{T v; alias v this;} } The benefit of this approach is that you don't have to invent new ways to test for null values.
That's it. So, the nullable basic type is not a problem. Thanks. ---------- Zhang <bitworld qq.com>
There used to be std.typecons.Nullable, but was disabled. Can you please check if there's any improvements to https://github.com/D-Programming-Language/phobos/pull/153?
Aug 12 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-08-11 14:10, zhang wrote:
 I think D needs user defined attributes first.
About attribute, here is an example: class ClassA { private int m_data; property int data() { return m_data; } property int data(int value) { return m_data = value; } } int main(string[] args) { ClassA aClass = new ClassA(); aClass.data = 22; writefln("%d", aClass.data); return 0; } ======================== integer type can be defined as "Int?" or "Nullable<int>".
You mean to indicate the attribute doesn't have a value? -- /Jacob Carlborg
Aug 11 2011
parent reply zhang <bitworld qq.com> writes:
 You mean to indicate the attribute doesn't have a value?
Yes, the field of a table can be null in DB. ---------- Zhang <bitworld qq.com>
Aug 12 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-08-12 14:59, zhang wrote:
 You mean to indicate the attribute doesn't have a value?
Yes, the field of a table can be null in DB. ---------- Zhang<bitworld qq.com>
I think you can declare new types for the types found in the database, like String, Integer, Date and so on. You could put additional useful methods on them and allow null as well. -- /Jacob Carlborg
Aug 12 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Piotr Szturmaj:

 I think D needs user defined attributes first.
In past discussions I have seen three or more different ideas of what 'user defined attributes' need to be in D: - A person has suggested for them to be like Python decorators, this means function templates that take a function and wrap it in some way; - For me they are better thought as small extensions to the type system, to implement new simple things, mostly using static introspection. So I suggest you to write down what kind of user defined attributes you want in D, their semantics, usage and syntax. Bye, bearophile
Aug 10 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-10 16:01, Piotr Szturmaj wrote:
 zhang wrote:
 About ORM,
 the Python has SQLObject (http://sqlobject.org/),
 the Java has Hibernate (http://www.hibernate.org/),

 (http://msdn.microsoft.com/en-us/data/aa937723).

 The D maybe also need one. Glad to see someone being interesting in this.
I think D needs user defined attributes first.
User defined attributes would be really nice but I'm quite certain that it would work without user defined attributes. Worst case scenario template mixins could be used to simulate attributes. -- /Jacob Carlborg
Aug 10 2011
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
zhang wrote:
 The D maybe also need one. Glad to see someone being interesting in
 this.
You might want to look at class DataObject in database.d here: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff It's pretty minimal but it covers the cases that irk me most and should work with columns built from joins (at least on mysql).
Aug 10 2011