January 05, 2016
On Mon, 04 Jan 2016 16:59:47 +0000, Piotrek wrote:
> SQL is no magic.

True. You could equivalently have a string containing valid D code, accompanied by CTFE parsers that will determine which indices to use. This has typically been considered an antipattern. It tends to work poorly with refactoring tools, for instance, and there's an assumption that string literals are data and not code.

C#'s system of lambda expressions that you can access as expression trees keeps the benefits of writing everything in the same language.
January 05, 2016
On 2016-01-05 05:16, Chris Wright wrote:

> Not proposing language changes was an intentional feature, not a mistake.

Then you obviously can't use the operators. You would have to fall back to methods:

Person.where!(e => e.name.eq("John"));

-- 
/Jacob Carlborg
January 05, 2016
On Monday, 4 January 2016 at 20:38:46 UTC, Andrei Alexandrescu wrote:
> On 01/04/2016 01:25 PM, Russel Winder via Digitalmars-d wrote:
[snip]
> What is Boost.Sprint? I haven't heard of it, and can't find it. Thanks! -- Andrei

I think he miss-typed or miss-remembered. It is Boost.Spirit.

http://boost-spirit.com/home/

January 05, 2016
On Tue, 05 Jan 2016 09:26:16 +0100, Jacob Carlborg wrote:

> On 2016-01-05 05:16, Chris Wright wrote:
> 
>> Not proposing language changes was an intentional feature, not a mistake.
> 
> Then you obviously can't use the operators. You would have to fall back to methods:
> 
> Person.where!(e => e.name.eq("John"));

Which some people call a DSL, and DSLs were, I understand, something we were trying to avoid. You get far less readability than you do with plain D or a SQL string.

Plus side, you spend no time parsing, but it took less than a millisecond to parse your SQL query in the first place, and most SQL databases allow you to cache prepared statements.
January 05, 2016
On Tuesday, 5 January 2016 at 08:26:16 UTC, Jacob Carlborg wrote:
> On 2016-01-05 05:16, Chris Wright wrote:
>
>> Not proposing language changes was an intentional feature, not a mistake.
>
> Then you obviously can't use the operators. You would have to fall back to methods:
>
> Person.where!(e => e.name.eq("John"));

i love how things can become so complex in this community. i am a web developer so i am going to talk in terms of simplicity.

as russel said, with SQLAlchemy (python library) operators are overloaded and we can do DBSession.query(User).filter(User.first_name == "Jacob", User.age > 27). this will generate the following query:

"SELECT * FROM users u WHERE u.first_name = 'Jacob' AND u.age > 27" and will let the DB handle the rest.

but as a web developer, i don't mind if i have to type User.where("first_name = ? AND age > 27", request.POST.get('name')). this will generate the same query above. i added the question mark to say the parameters should be escaped properly.

guys, what we need is a DB abstraction supporting PostgreSQL, MySQL and other major database systems and we need it yesterday. let's not make things more complex than they are and build up this thing.

p.s. this is not a reply to jacob, just his post was the one i clicked reply for. :-)
January 05, 2016
On Tuesday, 5 January 2016 at 22:12:05 UTC, Mengu wrote:
> guys, what we need is a DB abstraction supporting PostgreSQL, MySQL and other major database systems and we need it yesterday. let's not make things more complex than they are and build up this thing.

What is needed isn't a DB abstraction, but a language that makes elegant programming abstractions easy to implement for a wide variety of problem areas.

You can do DB abstractions in any language... No point in having a thread about it if anything goes. Just do 2-3 different prototypes and select the best ones. No discussion needed...


January 06, 2016
On 2016-01-05 18:32, Chris Wright wrote:

> Which some people call a DSL, and DSLs were, I understand, something we
> were trying to avoid. You get far less readability than you do with plain
> D or a SQL string.

The above is plain D. Not sure what you're referring to. And a DSL is usually used to increase readability.

Andrei and Walter want to avoid expression templates, not a DSL, as far as I understand it.

-- 
/Jacob Carlborg
January 06, 2016
On Tuesday, 5 January 2016 at 22:12:05 UTC, Mengu wrote:
> but as a web developer, i don't mind if i have to type User.where("first_name = ? AND age > 27", request.POST.get('name')). this will generate the same query above. i added the question mark to say the parameters should be escaped properly.

As a web developer, I _do_ care, though. For one, I shouldn't have to know how the fields are called in the database. But more importantly, it isn't composable: in the general case, you can not write e.g.

    User.joins("other_table ON ...").where("first_name = ? ...");

and expect it to work, because `first_name` could be ambiguous. This in turn means that you can't create abstractions, for example:

    auto users = User
                 .onlyMale
                 .where(["birthday": Date.today])
                 .orderBy!(User.firstName);

Here your query would have to know how male and female users are represented in your database, e.g. by an integer, a lowercase 'm', an uppercase 'M'... Such lack of abstraction can quickly make your codebase unmaintainable.
January 06, 2016
On Monday, 4 January 2016 at 17:36:20 UTC, Piotrek wrote:
> Thanks! So at least one more soul believing that D can approach the SQL expressiveness in db domain.
>
> Cheers
> Piotrek

Some time ago I had the same idea as yours. IMHO, no D to SQL is really needed for this, and the same goes for relational databases. My idea was to initially build a DB as library, using graph databases as starting point, where the metadata is defined only one time in the code. The query methods must allow easy access not only to the data, but also to the relations defined from object to object. As a starting point you must be able to do something like this:

// Stores are where the data is saved
auto localStore = FileStore!Endian.littleEndian( "some_file_name" ); // Local file

// load() and save() on objects of type User uses this store.
User.setDefaultStore( localStore );

User user = new User();

user.name = "John";
user.password = sha1( "password" );

// Uses the default store
auto localId = user.save();
// Uses the store specified as argument
auto otherId = user.save( someOtherStore );

// load the object from the default store
User localUser = User.load( localId );
// load the object from the network store
User otherUser = User.load( someOtherStore, otherId );

// Ideally users where the last login is older than one year using the networkStore
auto oldUsers = User.all( someOtherStore )
  .filterUsing!(User.lastLogin, (lastLogin) => lastLogin < ( now - 1.year ) );

// Select the first user that match userName and hashedPassword in the default store, with a challenge-response login
auto loginUser = User.all.
  .filterUsing!(User.name, (name) => name == userName )
  .filterUsing!(User.password, (pass) => hmac( pass, key ) == hashedPassword )
  .onlyOne();

Gianni Pisetta
January 07, 2016
On Mon, 2016-01-04 at 15:39 -0500, Andrei Alexandrescu via Digitalmars- d wrote:
> On 01/04/2016 01:28 PM, Russel Winder via Digitalmars-d wrote:
> > Rusts macros show it can be done well.
> 
> Do you have a few examples handy? Thanks. -- Andrei

Will do but it may be next week. Sorry, but medical stuff…
-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder