Re: Database interface design - was how to build up the library.

2011-10-07 Thread Andrei Alexandrescu

On 10/07/11 15:00, Piotr Szturmaj wrote:

Andrei Alexandrescu wrote:

On 10/7/11 12:02 PM, Piotr Szturmaj wrote:

Did you see http://pszturmaj.github.com/ddb/db.html ? It maps tuples,
structs and arrays in similar manner.


I did. Looks good. Why do you need DBRow? You could simply use
Variant[], the given struct, or Tuple directly.


Sure, that's a good idea. I used DBRow because I wanted generic
set/setNull for any of its base types, but it could be done with
function templates anyway...

The only thing that makes DBRow useful is opIndex access to Variant[]
fields, like row["field"].


Oh that makes sense, thanks.

Andrei


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Piotr Szturmaj

Andrei Alexandrescu wrote:

On 10/7/11 12:02 PM, Piotr Szturmaj wrote:

Did you see http://pszturmaj.github.com/ddb/db.html ? It maps tuples,
structs and arrays in similar manner.


I did. Looks good. Why do you need DBRow? You could simply use
Variant[], the given struct, or Tuple directly.


Sure, that's a good idea. I used DBRow because I wanted generic 
set/setNull for any of its base types, but it could be done with 
function templates anyway...


The only thing that makes DBRow useful is opIndex access to Variant[] 
fields, like row["field"].


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Andrei Alexandrescu

On 10/7/11 1:27 PM, Steve Teale wrote:

Andrei,

So if I'm understanding you correctly, if structs are used, and there's a 
database
change, then the app has to be rebuilt.


Yes. Touched to update the structs and rebuilt.


If Variants, then only the app's config
file has to be updated (or the app can look in the database to get such
information) - have I got this right?


Yah. The exact behavior depends on the assumption the app makes about 
the resultset. Consider:


auto result = db.sql(queryString);
enforce(result.front[0].type == typeid(double));
...

In this case you'd pretty much need to touch the code if the queryString 
returns something else than a double in the first column.



Andrei


Re: how to build up the library..

2011-10-07 Thread Jacob Carlborg

On 2011-10-07 15:34, Adam Ruppe wrote:

What's the big advantage of

Person.find_all_by_name_and_age("Joe", 15)

over

db.query("select * from people where name = ? and age = ?", "Joe", 15);



The latter is much easier to write in the library and you retain all
the flexibility of sql itself if needed.


I guess it just depends on what you like. I prefer to use the first 
example. One advantage the first example could have would be to validate 
the column names. If it already knows the column names it won't have to 
query the database if the column names don't match.


Of course it should always be possible to execute raw sql queries, like 
that last example.


I suggest you take a look at the documentation for ActiveRecord, just to 
get a feel for the API: 
http://guides.rubyonrails.org/active_record_querying.html


--
/Jacob Carlborg


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Jacob Carlborg

On 2011-10-07 16:11, Steve Teale wrote:

I'm thinking that for each database that gets covered there will
need to be two modules, like:

etc.c.mysql
etc.mysqld

The etc.c.xxx modules would be completely different between databases -
just translations of the necessary header files. The xxxd modules
would be as similar as possible consistent with allowing the strong
points of individual database systems to show through, and the weak
points of others to be avoided. I don't think all should be reduced
to some LCD.

These modules should attempt to make a good range of capabilities
available to the D programmer, but they not have to be all encompassing.
Those users who want to do really fancy things can drop back to the
low-level interface. They should probably have the following capabilities:

1) Establishing and closing database connections.

2) The capability to execute literal SQL statements - execSQL()
if you like. Some of these will generate result sets, of which more below.

3) The capability to create prepared statements with in and out
parameters and association of the parameters with a source, and
then to execute these. This breaks down into several components/
capabilities, which could be labeled:

3a) createPreparedStatement() - marshal parameters, associate them
with a sourceand have the server prepare the statement.

3b) execStatement() - for those SQL statements that don't have a
result set.

3c) execStatementIncremental()/getNext() - execute the prepared statement,
then fetch the result rows one at a time into some kind of result set.

3d) execStatementAll() - execute the prepared statement and get all
the resulting rows into some kind of result set.

3e) (maybe) execScalar() - do the whole sequence prepare, execute,
and get a single value result set placed into a D variable.

3f) (maybe) execStoredProcedure() - another 'do the whole thing'
capability TBD.

It is when we come to the nature of the result sets that there is
likely to be dissent. I favor arrays of structs, but we should
probably do arrays of arrays of variants too for those situations
where structures can't be sorted out at compile time. There needs
to be some symmetry between what is used here, and what can be used
as input to operations such as a prepared insert. It is of course
vital that this part of each middle layer produce exactly the same
kind of results. Otherwise the top layer could become difficult.

On top of this set of two modules for each database, I envisage a
higher-level module - etc.dbops - that provides a bunch of convenience
templates for various common database operations, spanning the databases.
Once the middle layer is in place, this top layer should be relatively
easy to implement. It should be noted though that all these database
wrappers will be monstrously difficult to test.

I am at the point with MySQL where I can get the result of a plain
old query into an array of a checked structure type. I have the
prepared statement stuff, and know how the result will be created from
a prepared query (the execStatementAll() case) - I just have to plow
through a bit more binding and fetching.

This is probably rather general and vague, but I would like to get
comments so we can iterate toward a practical design.

Thanks
Steve


I don't know if this will be necessary to have a special function for 
but it would be nice to be able to get batches of results from a query. 
Or this might be solved by the range interface.


--
/Jacob Carlborg


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Adam Ruppe
Sean Kelly wote:
> Does your Row equate to the ResultSet above?

Fairly similar.

Mine looks something like this:

interface ResultSet {
// name for associative array to result index
int getFieldIndex(string field);
string[] fieldNames();

bool empty();
Row front();
void popFront();
int length();
}

struct Row {
// the actual column is returned as a string - probably should
// change that, but mysql, postgres, and sqlite all offered that
// and it works for me, so I went with it
string opIndex(size_t idx) {}
string opIndex(string columnName) {}
int opApply(...) {}

private string[] data;
}



Then, each of the database implementations use that little
ResultSet interface  to feed Row structs back to the user code.


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Sean Kelly
On Oct 7, 2011, at 11:27 AM, Steve Teale wrote:

> Andrei,
> 
> So if I'm understanding you correctly, if structs are used, and there's a 
> database
> change, then the app has to be rebuilt. If Variants, then only the app's 
> config
> file has to be updated (or the app can look in the database to get such
> information) - have I got this right?

I'd say yes, though qualify this by saying that a properly designed app will 
target only views and stored procedures, which insulate the app from schema 
changes.

Re: Database interface design - was how to build up the library.

2011-10-07 Thread Sean Kelly
On Oct 7, 2011, at 10:14 AM, Adam Ruppe wrote:

> In my database.d, I used a database row struct to provide both
> integer and key based indexes.

Funny… I have a ResultSet object which contains an array of Column objects.  
Here's the basic idea:

class ResultSet {
static class Column {
int index();
string name();
int size();
int length();
void[] data();
bool opEquals(NullValue);
T as(T)(); // return raw if T matches underlying or call to!(T) on 
field as appropriate
}

size_t numCols();
bool nextResultSet();
bool next();
bool prev();
bool first();
bool last();
void update(); // SQLSetPos(rowNumber=0)
Column opIndex(size_t);
// easy enough to add opIndex(string)
}

Does your Row equate to the ResultSet as above?

Re: Database interface design - was how to build up the library.

2011-10-07 Thread Steve Teale
Andrei,

So if I'm understanding you correctly, if structs are used, and there's a 
database
change, then the app has to be rebuilt. If Variants, then only the app's config
file has to be updated (or the app can look in the database to get such
information) - have I got this right?

Steve


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Sean Kelly
On Oct 7, 2011, at 8:46 AM, Andrei Alexandrescu wrote:

> On 10/7/11 9:11 AM, Steve Teale wrote:
>> I'm thinking that for each database that gets covered there will
>> need to be two modules, like:
>> 
>> etc.c.mysql
>> etc.mysqld
>> 
>> The etc.c.xxx modules would be completely different between databases -
>> just translations of the necessary header files. The xxxd modules
>> would be as similar as possible consistent with allowing the strong
>> points of individual database systems to show through, and the weak
>> points of others to be avoided. I don't think all should be reduced
>> to some LCD.
> 
> Well we may be hasty to go that way. The driver-based approach works well for 
> other languages and APIs - why wouldn't it work for us? The differences 
> across different DBMSs would be mostly in the SQL support, not the basic APIs.

It may be worth targeting ODBC early on as well, since that would get the API 
working for pretty much everything.  Then targeting a DBMS-specific API would 
be an optimization step rather than a necessary one.


>> These modules should attempt to make a good range of capabilities
>> available to the D programmer, but they not have to be all encompassing.
>> Those users who want to do really fancy things can drop back to the
>> low-level interface. They should probably have the following capabilities:
>> 
>> 1) Establishing and closing database connections.
> 
> Sounds good. Since DB connections are a precious resource, there must be a 
> RAII struct holding them. The functions below may be members of it.

The way I've done this before is via reference counting, since the connection 
handle often has to be held by all related statements, resultsets, etc.  Would 
scope(exit) be sufficient to provide RAII functionality here?


>> 3) The capability to create prepared statements with in and out
>> parameters and association of the parameters with a source, and
>> then to execute these. This breaks down into several components/
>> capabilities, which could be labeled:
>> 
>> 3a) createPreparedStatement() - marshal parameters, associate them
>> with a sourceand have the server prepare the statement.
>> 
>> 3b) execStatement() - for those SQL statements that don't have a
>> result set.
>> 
>> 3c) execStatementIncremental()/getNext() - execute the prepared statement,
>> then fetch the result rows one at a time into some kind of result set.
> 
> Here's where the range interface might be used. We might simply have 
> execStatement() that returns an input range. If the statement produced no 
> rows, the range will be empty. No need for distinguishing execStatement() and 
> execStatementIncremental().

Absolutely, though things may be a bit tricky here.  It's possible for a SQL 
query to return multiple resultsets, each of which is ideally represented by a 
range.


>> 3d) execStatementAll() - execute the prepared statement and get all
>> the resulting rows into some kind of result set.
> 
> This is not a primitive, but instead a convenience function that should be 
> used with caution and only for queries known to be small. I agree that it's 
> good to have.
> 
>> 3e) (maybe) execScalar() - do the whole sequence prepare, execute,
>> and get a single value result set placed into a D variable.
> 
> That's convenient for e.g. "SELECT COUNT(*) FROM table WHERE condition", 
> which people run all the time.
> 
>> 3f) (maybe) execStoredProcedure() - another 'do the whole thing'
>> capability TBD.
> 
> Well wouldn't that just execute a special SQL a la "CALL procedure"?

A stored procedure can have a return value and multiple resultsets, I believe.  
Certainly one or the other anyway.  I think SPs are covered by the other query 
methods, though perhaps someone can think of a QOI feature that would benefit 
from a special call.


>> It is when we come to the nature of the result sets that there is
>> likely to be dissent. I favor arrays of structs, but we should
>> probably do arrays of arrays of variants too for those situations
>> where structures can't be sorted out at compile time. There needs
>> to be some symmetry between what is used here, and what can be used
>> as input to operations such as a prepared insert. It is of course
>> vital that this part of each middle layer produce exactly the same
>> kind of results. Otherwise the top layer could become difficult.
> 
> I'd like arrays of structs too but we must acknowledge that most databases 
> people use will be large, in which case loading the whole thing eagerly takes 
> a lot of RAM and potentially wastes time. So arrays are out except for e.g. 
> convenience functions - but then we already have array() that converts an 
> arbitrary input range into an array.
> 
> Now, regarding the "structs" part, I'd like that too when the schema is 
> statically known. Two issues:
> 
> 1. MFC had at a point a wizard that generated one struct per resultset. It 
> was an absolute maintenance disaster and they recanted by offering 
> dynamically-bou

Re: Database interface design - was how to build up the library.

2011-10-07 Thread Steve Teale
Andrei,

I've actually already got that in a way. Before I attempt to populate fields 
into
a struct, the struct is checked to see if it conforms to the field properties.

Steve


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Adam Ruppe
In my database.d, I used a database row struct to provide both
integer and key based indexes.


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Andrei Alexandrescu

On 10/7/11 12:02 PM, Piotr Szturmaj wrote:

Andrei Alexandrescu wrote:

1. MFC had at a point a wizard that generated one struct per resultset.
It was an absolute maintenance disaster and they recanted by offering
dynamically-bound result sets. The lesson there is that defining a
struct for each query won't likely play out, so we better use
Tuple!(ColType1, ColType2, ...). A possible API would be:

auto db = std.database.connect("cdb.mysql");
auto rows = db.sql!(double, ulong)
("SELECT SUM(x), COUNT(x) FROM table");
// We know that rows is a range of Tuple!(double, ulong).
writeln("Sum is ", rows.front[0], " count is ", rows.front[1]);

Cool beans. I'd love to use such an API!
Andrei


Did you see http://pszturmaj.github.com/ddb/db.html ? It maps tuples,
structs and arrays in similar manner.


I did. Looks good. Why do you need DBRow? You could simply use 
Variant[], the given struct, or Tuple directly.


Andrei


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Piotr Szturmaj

Andrei Alexandrescu wrote:

1. MFC had at a point a wizard that generated one struct per resultset.
It was an absolute maintenance disaster and they recanted by offering
dynamically-bound result sets. The lesson there is that defining a
struct for each query won't likely play out, so we better use
Tuple!(ColType1, ColType2, ...). A possible API would be:

auto db = std.database.connect("cdb.mysql");
auto rows = db.sql!(double, ulong)
("SELECT SUM(x), COUNT(x) FROM table");
// We know that rows is a range of Tuple!(double, ulong).
writeln("Sum is ", rows.front[0], " count is ", rows.front[1]);

Cool beans. I'd love to use such an API!
Andrei


Did you see http://pszturmaj.github.com/ddb/db.html ? It maps tuples, 
structs and arrays in similar manner.


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Andrei Alexandrescu

On 10/7/11 11:51 AM, Steve Teale wrote:

Andrei,

The suggestion in your penultimate paragraph is what I'm trying to get started.

Maybe the answer to the problem with structs may lie somewhere in std.typecons 
in
combination with the field discovery features supported by most databases. If we
can manufacture the struct to suit the circumstances, then we've cracked it! I'm
probably talking rubbish - Friday night, couple of beers.


No can do. This is a hard wall. Structs must be defined during 
compilation. Database structure can be discovered at run time.


What you can do, however, is that you pass a struct type to store a row 
in the resultset and at runtime the fields of the struct are matched 
dynamically with the fields in the rowset. That is doable and useful.



I will attempt top start a new thread - [std.database] - your 10 cents worth?


http://www.youtube.com/watch?v=lmUZGdi7Ty4


Andrei



Re: Database interface design - was how to build up the library.

2011-10-07 Thread Steve Teale
Andrei,

The suggestion in your penultimate paragraph is what I'm trying to get started.

Maybe the answer to the problem with structs may lie somewhere in std.typecons 
in
combination with the field discovery features supported by most databases. If we
can manufacture the struct to suit the circumstances, then we've cracked it! I'm
probably talking rubbish - Friday night, couple of beers.

I will attempt top start a new thread - [std.database] - your 10 cents worth?

Thanks
Steve


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Alex Rønne Petersen

On 07-10-2011 16:11, Steve Teale wrote:

I'm thinking that for each database that gets covered there will
need to be two modules, like:

etc.c.mysql
etc.mysqld

The etc.c.xxx modules would be completely different between databases -
just translations of the necessary header files. The xxxd modules
would be as similar as possible consistent with allowing the strong
points of individual database systems to show through, and the weak
points of others to be avoided. I don't think all should be reduced
to some LCD.

These modules should attempt to make a good range of capabilities
available to the D programmer, but they not have to be all encompassing.
Those users who want to do really fancy things can drop back to the
low-level interface. They should probably have the following capabilities:

1) Establishing and closing database connections.

2) The capability to execute literal SQL statements - execSQL()
if you like. Some of these will generate result sets, of which more below.

3) The capability to create prepared statements with in and out
parameters and association of the parameters with a source, and
then to execute these. This breaks down into several components/
capabilities, which could be labeled:

3a) createPreparedStatement() - marshal parameters, associate them
with a sourceand have the server prepare the statement.

3b) execStatement() - for those SQL statements that don't have a
result set.

3c) execStatementIncremental()/getNext() - execute the prepared statement,
then fetch the result rows one at a time into some kind of result set.

3d) execStatementAll() - execute the prepared statement and get all
the resulting rows into some kind of result set.

3e) (maybe) execScalar() - do the whole sequence prepare, execute,
and get a single value result set placed into a D variable.

3f) (maybe) execStoredProcedure() - another 'do the whole thing'
capability TBD.

It is when we come to the nature of the result sets that there is
likely to be dissent. I favor arrays of structs, but we should
probably do arrays of arrays of variants too for those situations
where structures can't be sorted out at compile time. There needs
to be some symmetry between what is used here, and what can be used
as input to operations such as a prepared insert. It is of course
vital that this part of each middle layer produce exactly the same
kind of results. Otherwise the top layer could become difficult.

On top of this set of two modules for each database, I envisage a
higher-level module - etc.dbops - that provides a bunch of convenience
templates for various common database operations, spanning the databases.
Once the middle layer is in place, this top layer should be relatively
easy to implement. It should be noted though that all these database
wrappers will be monstrously difficult to test.

I am at the point with MySQL where I can get the result of a plain
old query into an array of a checked structure type. I have the
prepared statement stuff, and know how the result will be created from
a prepared query (the execStatementAll() case) - I just have to plow
through a bit more binding and fetching.

This is probably rather general and vague, but I would like to get
comments so we can iterate toward a practical design.

Thanks
Steve


Just a note on module naming: mysqld is misleading - it could mean 
"mysql daemon". I would recommend just calling it mysql and calling the 
C interface etc.c.mysqlc or something like this.


- Alex


Re: Database interface design - was how to build up the library.

2011-10-07 Thread Andrei Alexandrescu

On 10/7/11 9:11 AM, Steve Teale wrote:

I'm thinking that for each database that gets covered there will
need to be two modules, like:

etc.c.mysql
etc.mysqld

The etc.c.xxx modules would be completely different between databases -
just translations of the necessary header files. The xxxd modules
would be as similar as possible consistent with allowing the strong
points of individual database systems to show through, and the weak
points of others to be avoided. I don't think all should be reduced
to some LCD.


Well we may be hasty to go that way. The driver-based approach works 
well for other languages and APIs - why wouldn't it work for us? The 
differences across different DBMSs would be mostly in the SQL support, 
not the basic APIs.



These modules should attempt to make a good range of capabilities
available to the D programmer, but they not have to be all encompassing.
Those users who want to do really fancy things can drop back to the
low-level interface. They should probably have the following capabilities:

1) Establishing and closing database connections.


Sounds good. Since DB connections are a precious resource, there must be 
a RAII struct holding them. The functions below may be members of it.



2) The capability to execute literal SQL statements - execSQL()
if you like. Some of these will generate result sets, of which more below.


Great.


3) The capability to create prepared statements with in and out
parameters and association of the parameters with a source, and
then to execute these. This breaks down into several components/
capabilities, which could be labeled:

3a) createPreparedStatement() - marshal parameters, associate them
with a sourceand have the server prepare the statement.

3b) execStatement() - for those SQL statements that don't have a
result set.

3c) execStatementIncremental()/getNext() - execute the prepared statement,
then fetch the result rows one at a time into some kind of result set.


Here's where the range interface might be used. We might simply have 
execStatement() that returns an input range. If the statement produced 
no rows, the range will be empty. No need for distinguishing 
execStatement() and execStatementIncremental().



3d) execStatementAll() - execute the prepared statement and get all
the resulting rows into some kind of result set.


This is not a primitive, but instead a convenience function that should 
be used with caution and only for queries known to be small. I agree 
that it's good to have.



3e) (maybe) execScalar() - do the whole sequence prepare, execute,
and get a single value result set placed into a D variable.


That's convenient for e.g. "SELECT COUNT(*) FROM table WHERE condition", 
which people run all the time.



3f) (maybe) execStoredProcedure() - another 'do the whole thing'
capability TBD.


Well wouldn't that just execute a special SQL a la "CALL procedure"?


It is when we come to the nature of the result sets that there is
likely to be dissent. I favor arrays of structs, but we should
probably do arrays of arrays of variants too for those situations
where structures can't be sorted out at compile time. There needs
to be some symmetry between what is used here, and what can be used
as input to operations such as a prepared insert. It is of course
vital that this part of each middle layer produce exactly the same
kind of results. Otherwise the top layer could become difficult.


I'd like arrays of structs too but we must acknowledge that most 
databases people use will be large, in which case loading the whole 
thing eagerly takes a lot of RAM and potentially wastes time. So arrays 
are out except for e.g. convenience functions - but then we already have 
array() that converts an arbitrary input range into an array.


Now, regarding the "structs" part, I'd like that too when the schema is 
statically known. Two issues:


1. MFC had at a point a wizard that generated one struct per resultset. 
It was an absolute maintenance disaster and they recanted by offering 
dynamically-bound result sets. The lesson there is that defining a 
struct for each query won't likely play out, so we better use 
Tuple!(ColType1, ColType2, ...). A possible API would be:


auto db = std.database.connect("cdb.mysql");
auto rows = db.sql!(double, ulong)
("SELECT SUM(x), COUNT(x) FROM table");
// We know that rows is a range of Tuple!(double, ulong).
writeln("Sum is ", rows.front[0], " count is ", rows.front[1]);

Cool beans. I'd love to use such an API!

2. Statically-bound tuples work only when we know the query beforehand. 
We need to cater for resultsets of unknown column count and types. The 
question here is whether we traffic in untyped memory a la ubyte[] or 
some variant type. I favor Variant because it's efficient, accommodates 
any SQL type easily, and is convenient to use.



On top of this set of two modules for each database, I envisage a
higher-level module - etc.dbops - that provides a bunch of convenience
templates for var

Database interface design - was how to build up the library.

2011-10-07 Thread Steve Teale
I'm thinking that for each database that gets covered there will
need to be two modules, like:

etc.c.mysql
etc.mysqld

The etc.c.xxx modules would be completely different between databases -
just translations of the necessary header files. The xxxd modules
would be as similar as possible consistent with allowing the strong
points of individual database systems to show through, and the weak
points of others to be avoided. I don't think all should be reduced
to some LCD.

These modules should attempt to make a good range of capabilities
available to the D programmer, but they not have to be all encompassing.
Those users who want to do really fancy things can drop back to the
low-level interface. They should probably have the following capabilities:

1) Establishing and closing database connections.

2) The capability to execute literal SQL statements - execSQL()
if you like. Some of these will generate result sets, of which more below.

3) The capability to create prepared statements with in and out
parameters and association of the parameters with a source, and
then to execute these. This breaks down into several components/
capabilities, which could be labeled:

3a) createPreparedStatement() - marshal parameters, associate them
with a sourceand have the server prepare the statement.

3b) execStatement() - for those SQL statements that don't have a
result set.

3c) execStatementIncremental()/getNext() - execute the prepared statement,
then fetch the result rows one at a time into some kind of result set.

3d) execStatementAll() - execute the prepared statement and get all
the resulting rows into some kind of result set.

3e) (maybe) execScalar() - do the whole sequence prepare, execute,
and get a single value result set placed into a D variable.

3f) (maybe) execStoredProcedure() - another 'do the whole thing'
capability TBD.

It is when we come to the nature of the result sets that there is
likely to be dissent. I favor arrays of structs, but we should
probably do arrays of arrays of variants too for those situations
where structures can't be sorted out at compile time. There needs
to be some symmetry between what is used here, and what can be used
as input to operations such as a prepared insert. It is of course
vital that this part of each middle layer produce exactly the same
kind of results. Otherwise the top layer could become difficult.

On top of this set of two modules for each database, I envisage a
higher-level module - etc.dbops - that provides a bunch of convenience
templates for various common database operations, spanning the databases.
Once the middle layer is in place, this top layer should be relatively
easy to implement. It should be noted though that all these database
wrappers will be monstrously difficult to test.

I am at the point with MySQL where I can get the result of a plain
old query into an array of a checked structure type. I have the
prepared statement stuff, and know how the result will be created from
a prepared query (the execStatementAll() case) - I just have to plow
through a bit more binding and fetching.

This is probably rather general and vague, but I would like to get
comments so we can iterate toward a practical design.

Thanks
Steve


Re: how to build up the library..

2011-10-07 Thread Adam Ruppe
What's the big advantage of

Person.find_all_by_name_and_age("Joe", 15)

over

db.query("select * from people where name = ? and age = ?", "Joe", 15);



The latter is much easier to write in the library and you retain all
the flexibility of sql itself if needed.


Re: how to build up the library..

2011-10-07 Thread Regan Heath

On Fri, 07 Oct 2011 07:40:01 +0100, Jacob Carlborg  wrote:


On 2011-10-06 21:44, Jesse Phillips wrote:

Regan Heath Wrote:

That's just it however, I am not generous enough with my time to be of  
use
to you/D/phobos.  I spend my free time doing other things, and not  
working

on the code I have which could be of use.  I suspect there are quite a
number of people out there who are just like me.  People who have some
code which may be of use, in varying degrees of completeness from just  
an

idea to a pretty much complete re-usable library which just needs the
final touches etc.


The problem is as you say, there are many out there like you. Even if  
some people take the rule of getting these polished, they couldn't keep  
up. Finding these people his hard.


Even if we just get one contribution to Phobos through this method it  
would be better than nothing.


Exactly.  The people taking ideas from the pool don't have to keep up,  
they just need to be someone with the time/inclination to "complete"  
something/anything worthy of inclusion into phobos.  All the pool does is  
give them a leg-up or provide the technical know-how/guts they might be  
missing.  It would be something like dsource, but for code ranging from  
snippets to complete packages, and would have to be well organised, or at  
least searchable and rely on contributors including as much info about  
thier snippets etc as they can.  But, that's a nice small investment for  
someone, especially if we make it easy to contribute the code, agree to a  
license and add info about it which is then searchable.  I realise setting  
something like this up is no small amount of work, and that I'm in no  
position to do it, but it seems on the face of it to be a good idea.


The pool would serve double duty, as it would supply code  
examples/snippets to people learning D also, or anyone looking for  
examples of how to do .. well, anything that gets contributed.  Each of us  
probably has a collection of D code on our own HDDs somewhere which does  
interesting and useful things, but no-one else can see it, search it, or  
learn from it.  I'm simply suggesting we put it somewhere to share.  At  
it's most basic it could just be a wiki page, which we let google index  
for us.


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: how to build up the library..

2011-10-07 Thread Jacob Carlborg

On 2011-10-07 09:26, Russel Winder wrote:

On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
[ . . . ]

I think it's important to support the range interface (or if it's
simpler, the array interface). I think ActiveRecord has a good high
level API which allows to lazily evaluate SQL queries.

persons = Person.all # no query is performed here
persons = persons.where("name = 'Joe'") # or here

persons.each do |p| # The actual query is performed here
  # do something with each Person
end

I don't think it would be strange to see something like this:

Person.where("age>  10").map{ |p| p.name } # using "map" on an SQL query


Not just Ruby an Rails with ActiveRecord.  Groovy/Grails/GORM does what
is basically the same.  Python cannot do the same in the same way Ruby
and Groovy can, but it has it equivalent (augmented with SQLAlchemy).
Basically it comes down to constructing dynamic queries using the
dynamic and MOP nature of the languages.  The crucial keyword here is
Builder.  The trick is that what looks like function call is actually
interpreted via the builder/MOP as the construction of a data structure,
which then creates the query on demand -- with template placeholder
filling as required.

Does D have the reflection capabilities to do this in any way, shape or
form similar tp the way the dynamic languages do it?


It depends on what you want to achieve. If you want just the above 
example (and similar) to work, including lazy loading that would be 
possible and not very hard.


If you want a more complete ORM and do things like (in Ruby):

person = Person.find_all_by_name_and_age("Joe", 15)
p person.name

That's a little harder. You could use opDispatch to make 
"find_all_by_name_and_age" or "name" work, but not both. The problem is 
that you can not overload methods on static and you are not forced to 
call a static method prefixed with the class name.


class Foo
{
void bar () {};
static void bar () {};
}

Currently the above doesn't work. You can also call a static method on 
an instance, which will also cause problems. What we want here is to be 
able to have two versions of opDispatch, one static and one non-static.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-07 Thread Jacob Carlborg

On 2011-10-07 09:30, Russel Winder wrote:

On Fri, 2011-10-07 at 08:51 +0200, Jacob Carlborg wrote:
[ . . . ]

I think it's important to have a solid low level database API which an
object oriented abstraction can be built upon.


Why object oriented? Why not functional?


The point was that the low level should not be object oriented like, an 
ORM, to allow different high level abstractions built on top of the low 
level API.


I don't think that the low level API should have functions which takes a 
struct or an object and fills it fields with results from a query. 
That's up to the high level API.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-07 Thread Marco Leise

Am 07.10.2011, 09:26 Uhr, schrieb Russel Winder :


On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
[ . . . ]

I think it's important to support the range interface (or if it's
simpler, the array interface). I think ActiveRecord has a good high
level API which allows to lazily evaluate SQL queries.

persons = Person.all # no query is performed here
persons = persons.where("name = 'Joe'") # or here

persons.each do |p| # The actual query is performed here
 # do something with each Person
end

I don't think it would be strange to see something like this:

Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query


Not just Ruby an Rails with ActiveRecord.  Groovy/Grails/GORM does what
is basically the same.  Python cannot do the same in the same way Ruby
and Groovy can, but it has it equivalent (augmented with SQLAlchemy).
Basically it comes down to constructing dynamic queries using the
dynamic and MOP nature of the languages.  The crucial keyword here is
Builder.  The trick is that what looks like function call is actually
interpreted via the builder/MOP as the construction of a data structure,
which then creates the query on demand -- with template placeholder
filling as required.

Does D have the reflection capabilities to do this in any way, shape or
form similar tp the way the dynamic languages do it?


This has already been done in D. There is a nice library that assembles  
queries at compile time and fetches results lazily into structs. The name?  
Sorry, I forgot. But the author will probably show up here.


Re: how to build up the library..

2011-10-07 Thread Russel Winder
On Fri, 2011-10-07 at 08:51 +0200, Jacob Carlborg wrote:
[ . . . ]
> I think it's important to have a solid low level database API which an 
> object oriented abstraction can be built upon.

Why object oriented? Why not functional?

The lesson form ORMs is that object oriented and relational can be
linked with an adaptor but the impedance mismatch is high.  But if you
want to use an ORM use one, of course.

The computational model having issued a query is just data
transformation which is nicely functional, albeit possibly with side
effects.  But then the FP crowd have given everyone monads.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@russel.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: how to build up the library..

2011-10-07 Thread Russel Winder
On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
[ . . . ]
> I think it's important to support the range interface (or if it's 
> simpler, the array interface). I think ActiveRecord has a good high 
> level API which allows to lazily evaluate SQL queries.
> 
> persons = Person.all # no query is performed here
> persons = persons.where("name = 'Joe'") # or here
> 
> persons.each do |p| # The actual query is performed here
>  # do something with each Person
> end
> 
> I don't think it would be strange to see something like this:
> 
> Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query

Not just Ruby an Rails with ActiveRecord.  Groovy/Grails/GORM does what
is basically the same.  Python cannot do the same in the same way Ruby
and Groovy can, but it has it equivalent (augmented with SQLAlchemy).
Basically it comes down to constructing dynamic queries using the
dynamic and MOP nature of the languages.  The crucial keyword here is
Builder.  The trick is that what looks like function call is actually
interpreted via the builder/MOP as the construction of a data structure,
which then creates the query on demand -- with template placeholder
filling as required.

Does D have the reflection capabilities to do this in any way, shape or
form similar tp the way the dynamic languages do it?

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@russel.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: how to build up the library..

2011-10-06 Thread Jacob Carlborg

On 2011-10-07 07:24, Steve Teale wrote:

Andrei,

I was thinking the same thing about the C level interface sometime in the middle
of last night. A straight translation of mysqld could be put there almost
immediately. I have to make myself translate the character set stuff, and add
that, but it's probably only a days work.

As for the interface, I was influenced at the intermediate level by my memory of
using C#.

I think that a DB interface for D should be something that provides an 
understood
set of facilities rather than an interface in the language sense that provides
certain specific methods. This would allow a decent job to be done on individual
databases strengths, while making it easy for D programmers to move from one to
another. I will write up a summary of my thoughts later today, and post it here.

Briefly, I had thought of variants, but am also attracted to the idea of
'compatible structs'. These would be struct definition that when fed to a 
suitable
template function, could be determined to be a match for a stated query - a bit
like isForwardRange ;=). Other templates would be provided to automate the 
process
of 'applying' arrays of such structs to/from the database. Similar facilities
could be provided for arrays of arrays of variants.

At an even higher level one could have templates that implemented entire
operations, like updating a batch of records.

D's template facilities make such stuff easy to implement once you have certain
primitives to base them on. I am at that point now. I have bridgehead and can
consider breakout.

Steve


As I replied to another post:

I think it's important to have a solid low level database API which 
later an object oriented abstraction can be built upon.


In this low level API I don't think that results from SQL quires should 
be converted to structs. I think that's up to the higher, object 
oriented, level to do.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-06 Thread Jacob Carlborg

On 2011-10-07 04:56, Piotr Szturmaj wrote:

Nick Sabalausky wrote:

"Andrei Alexandrescu" wrote in message
news:j6ljvs$1if5$1...@digitalmars.com...


For D in particular, I think the range aspect is secondary. Probably it
will be more important to interoperate with Variant. Most APIs store
columns in a Variant structure that captures all possible types of the
database.

Resultsets come as input ranges of array of Variant. It's not
important to
make them compatible with the input range interface because it's
unlikely
you'll pass that array of Variant directly to some algorithm. That being
said, people will naturally expect to use the canonical range interface.
It would probably be gratuitous to choose other primitive(s) than
empty/front/popFront.



Personally, I would *expect* a good DB API to provide statically-typed
columns. I use D because I hate dynamic typing, not because it provides a
Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant
capability for those who want it, I wouldn't care at all either way.




What do you think about ddb(http://pszturmaj.github.com/ddb/db.html) ?.
It provides statically typed columns or dynamic Variant columns. What
you want is what you get :)


I think it's important to have a solid low level database API which an 
object oriented abstraction can be built upon.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-06 Thread Jacob Carlborg

On 2011-10-07 03:17, Andrei Alexandrescu wrote:

On 10/6/11 10:27 AM, Steve Teale wrote:

Andrei,

Are there guidelines for the Phobos process?


We follow the Boost review process:
http://www.boost.org/community/reviews.html


I have put a fair amount of work, two years ago and recently, into a
piece for
accessing MySQL via D. I'm looking at this as a bottom-up
investigation into what
might be a more generalized interface for database access.

I've got to the point where I can support a good range of database
operations, and
present result sets as arrays of D structs, which presumably implies
Ranges.
There's also lower level stuff to do more complex operations. So I'm
wondering if
I should take the first process steps. I'm retired, so I do have time
to spend on it.

The MySQL C api is not what you could call orthogonal - in
crystallography terms
it is probably Triclinic, so it may not have been the best place to
start. There's
another guy I've had some correspondence with who is working on
Postgres. He's
interested in the same idea.

What do you think?


I think this is a great initiative. Perhaps it would be nice to have a
C-level API translation in etc.mysql. Then we should have a driver-style
interface a la Java's JDBC, Perl's DBI, Python's PEP249 etc.

For D in particular, I think the range aspect is secondary. Probably it
will be more important to interoperate with Variant. Most APIs store
columns in a Variant structure that captures all possible types of the
database.

Resultsets come as input ranges of array of Variant. It's not important
to make them compatible with the input range interface because it's
unlikely you'll pass that array of Variant directly to some algorithm.
That being said, people will naturally expect to use the canonical range
interface. It would probably be gratuitous to choose other primitive(s)
than empty/front/popFront.


I think it's important to support the range interface (or if it's 
simpler, the array interface). I think ActiveRecord has a good high 
level API which allows to lazily evaluate SQL queries.


persons = Person.all # no query is performed here
persons = persons.where("name = 'Joe'") # or here

persons.each do |p| # The actual query is performed here
# do something with each Person
end

I don't think it would be strange to see something like this:

Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query

--
/Jacob Carlborg


Re: how to build up the library..

2011-10-06 Thread Jacob Carlborg

On 2011-10-06 21:44, Jesse Phillips wrote:

Regan Heath Wrote:


That's just it however, I am not generous enough with my time to be of use
to you/D/phobos.  I spend my free time doing other things, and not working
on the code I have which could be of use.  I suspect there are quite a
number of people out there who are just like me.  People who have some
code which may be of use, in varying degrees of completeness from just an
idea to a pretty much complete re-usable library which just needs the
final touches etc.


The problem is as you say, there are many out there like you. Even if some 
people take the rule of getting these polished, they couldn't keep up. Finding 
these people his hard.


Even if we just get one contribution to Phobos through this method it 
would be better than nothing.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-06 Thread Steve Teale
Andrei,

I was thinking the same thing about the C level interface sometime in the middle
of last night. A straight translation of mysqld could be put there almost
immediately. I have to make myself translate the character set stuff, and add
that, but it's probably only a days work.

As for the interface, I was influenced at the intermediate level by my memory of
using C#.

I think that a DB interface for D should be something that provides an 
understood
set of facilities rather than an interface in the language sense that provides
certain specific methods. This would allow a decent job to be done on individual
databases strengths, while making it easy for D programmers to move from one to
another. I will write up a summary of my thoughts later today, and post it here.

Briefly, I had thought of variants, but am also attracted to the idea of
'compatible structs'. These would be struct definition that when fed to a 
suitable
template function, could be determined to be a match for a stated query - a bit
like isForwardRange ;=). Other templates would be provided to automate the 
process
of 'applying' arrays of such structs to/from the database. Similar facilities
could be provided for arrays of arrays of variants.

At an even higher level one could have templates that implemented entire
operations, like updating a batch of records.

D's template facilities make such stuff easy to implement once you have certain
primitives to base them on. I am at that point now. I have bridgehead and can
consider breakout.

Steve


Re: how to build up the library..

2011-10-06 Thread Andrei Alexandrescu

On 10/6/11 8:55 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:j6ljvs$1if5$1...@digitalmars.com...


For D in particular, I think the range aspect is secondary. Probably it
will be more important to interoperate with Variant. Most APIs store
columns in a Variant structure that captures all possible types of the
database.

Resultsets come as input ranges of array of Variant. It's not important to
make them compatible with the input range interface because it's unlikely
you'll pass that array of Variant directly to some algorithm. That being
said, people will naturally expect to use the canonical range interface.
It would probably be gratuitous to choose other primitive(s) than
empty/front/popFront.



Personally, I would *expect* a good DB API to provide statically-typed
columns. I use D because I hate dynamic typing, not because it provides a
Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant
capability for those who want it, I wouldn't care at all either way.


A statically-typed interface is nice when you know the schema a priori, 
but definitely there's a need for dynamically-created queries too.



Andrei


Re: how to build up the library..

2011-10-06 Thread Piotr Szturmaj

Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:j6ljvs$1if5$1...@digitalmars.com...


For D in particular, I think the range aspect is secondary. Probably it
will be more important to interoperate with Variant. Most APIs store
columns in a Variant structure that captures all possible types of the
database.

Resultsets come as input ranges of array of Variant. It's not important to
make them compatible with the input range interface because it's unlikely
you'll pass that array of Variant directly to some algorithm. That being
said, people will naturally expect to use the canonical range interface.
It would probably be gratuitous to choose other primitive(s) than
empty/front/popFront.



Personally, I would *expect* a good DB API to provide statically-typed
columns. I use D because I hate dynamic typing, not because it provides a
Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant
capability for those who want it, I wouldn't care at all either way.




What do you think about ddb(http://pszturmaj.github.com/ddb/db.html) ?.
It provides statically typed columns or dynamic Variant columns. What 
you want is what you get :)


Re: how to build up the library..

2011-10-06 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:j6ljvs$1if5$1...@digitalmars.com...
>
> For D in particular, I think the range aspect is secondary. Probably it 
> will be more important to interoperate with Variant. Most APIs store 
> columns in a Variant structure that captures all possible types of the 
> database.
>
> Resultsets come as input ranges of array of Variant. It's not important to 
> make them compatible with the input range interface because it's unlikely 
> you'll pass that array of Variant directly to some algorithm. That being 
> said, people will naturally expect to use the canonical range interface. 
> It would probably be gratuitous to choose other primitive(s) than 
> empty/front/popFront.
>

Personally, I would *expect* a good DB API to provide statically-typed 
columns. I use D because I hate dynamic typing, not because it provides a 
Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant 
capability for those who want it, I wouldn't care at all either way.




Re: how to build up the library..

2011-10-06 Thread Andrei Alexandrescu

On 10/6/11 10:27 AM, Steve Teale wrote:

Andrei,

Are there guidelines for the Phobos process?


We follow the Boost review process: 
http://www.boost.org/community/reviews.html



I have put a fair amount of work, two years ago and recently, into a piece for
accessing MySQL via D. I'm looking at this as a bottom-up investigation into 
what
might be a more generalized interface for database access.

I've got to the point where I can support a good range of database operations, 
and
present result sets as arrays of D structs, which presumably implies Ranges.
There's also lower level stuff to do more complex operations. So I'm wondering 
if
I should take the first process steps. I'm retired, so I do have time to spend 
on it.

The MySQL C api is not what you could call orthogonal - in crystallography terms
it is probably Triclinic, so it may not have been the best place to start. 
There's
another guy I've had some correspondence with who is working on Postgres. He's
interested in the same idea.

What do you think?


I think this is a great initiative. Perhaps it would be nice to have a 
C-level API translation in etc.mysql. Then we should have a driver-style 
interface a la Java's JDBC, Perl's DBI, Python's PEP249 etc.


For D in particular, I think the range aspect is secondary. Probably it 
will be more important to interoperate with Variant. Most APIs store 
columns in a Variant structure that captures all possible types of the 
database.


Resultsets come as input ranges of array of Variant. It's not important 
to make them compatible with the input range interface because it's 
unlikely you'll pass that array of Variant directly to some algorithm. 
That being said, people will naturally expect to use the canonical range 
interface. It would probably be gratuitous to choose other primitive(s) 
than empty/front/popFront.


Making the database interface generic over other SQL databases will 
probably be considerable more work, and will need study of existing APIs 
and input from the community.



Thanks,

Andrei


Re: how to build up the library..

2011-10-06 Thread Jesse Phillips
Steve Teale Wrote:

> Andrei,
> 
> Are there guidelines for the Phobos process?
> 
> I have put a fair amount of work, two years ago and recently, into a piece for
> accessing MySQL via D. I'm looking at this as a bottom-up investigation into 
> what
> might be a more generalized interface for database access.
> 
> I've got to the point where I can support a good range of database 
> operations, and
> present result sets as arrays of D structs, which presumably implies Ranges.
> There's also lower level stuff to do more complex operations. So I'm 
> wondering if
> I should take the first process steps. I'm retired, so I do have time to 
> spend on it.
> 
> The MySQL C api is not what you could call orthogonal - in crystallography 
> terms
> it is probably Triclinic, so it may not have been the best place to start. 
> There's
> another guy I've had some correspondence with who is working on Postgres. He's
> interested in the same idea.
> 
> What do you think?
> 
> Steve

My suggestion, work with those you can find to help you. And keep these points 
in mind.

* There is interest in having a standard Database interface.
* It does not have to support ever obscure option of every database
* The Database specific "glue layer" does not need to be part of Phobos, though 
the popular ones would be good.
* The glue layer should expose the more intricate options and hopefully work 
with the generic interface.
* You will have to keep pushing for it. If you have a good solid API that you 
think is ready for inclusion in Phobos you will get more attention and a more 
critical review.
* The generic interface will be the main interest, and I think many envision it 
looking like C#'s LINQ over Java's prepare and execute. (C# has this too, I 
couldn't figure out how to use LINQ as it seemed to require more setup, I think 
D can do better)



Re: how to build up the library..

2011-10-06 Thread Jesse Phillips
Regan Heath Wrote:

> That's just it however, I am not generous enough with my time to be of use  
> to you/D/phobos.  I spend my free time doing other things, and not working  
> on the code I have which could be of use.  I suspect there are quite a  
> number of people out there who are just like me.  People who have some  
> code which may be of use, in varying degrees of completeness from just an  
> idea to a pretty much complete re-usable library which just needs the  
> final touches etc.

The problem is as you say, there are many out there like you. Even if some 
people take the rule of getting these polished, they couldn't keep up. Finding 
these people his hard.

> The size of a contribution for phobos is (one complete module) whereas in  
> many open source projects you can contribute as little as a line of  
> code/fix for a problem.  The goal of this idea is to lower the bar for  
> "contributions" and "contributors" to include more people and more code  
> until even very small ideas/examples may eventually contribute to the  
> whole if only indirectly.

Contributions can be of any size. You don't even need to use Git/pull requests. 
Just attach a diff to a bug in BugZilla. And these changes don't go throw the 
formal review, just those with Phobos repo access.

What you are looking for is Dsource, or Github, or any other source repository. 
You place your code up on the web and license it under Boost, someone can 
modify it for Phobos.

But the problem is, organizing all of them. People don't have interest in 
placing projects on Dsource anymore because it can't be organized well and it 
is relies on one person to update the software. So people go else where, but 
they don't want to take the time to manage what their project does over on 
Wiki4D, so someone else does it but isn't informed when updates need made.

So please keep writing software for yourself. Choose an appropriate license for 
how you feel it should be used and do what you do.



Re: how to build up the library..

2011-10-06 Thread Regan Heath
On Thu, 06 Oct 2011 15:47:03 +0100, Andrei Alexandrescu  
 wrote:



On 10/6/11 5:25 AM, Regan Heath wrote:

I've been lurking and contributing to this news group on and off for
years (since 2005/2006, maybe earlier). But, in all that time I have
contributed nothing to Phobos. I have contributed a set of
digest/hashing routines to Tango, because at the time Phobos wasn't
taking submissions. I have been meaning to clean my originals of these
up, get them properly documented, etc and submit them for review for
Phobos, but I just haven't had the time, and/or inclination to do so (my
free time is precious and I've just not been feeling the urge/itch to
code.. blame minecraft :p)

However, I am more than happy to hand them off in their current state to
anyone who does have both time and inclination .. and I wonder how many
other blocks of code are out there, just like mine, just waiting for the
right person to take charge of them. Would this be useful do you think?
Or would the time it takes someone to pick up new code, learn it, fine
tune it and document it.. etc be more than if they just started again
from scratch. It seems to me that sometimes, all that is needed to get a
new module off the ground is a working prototype for the guts of it,
which is what people like me who have some experience/knowledge but
little time/energy could do, before handing it to someone who has a
better idea of the D/Phobos 'way' and can organise the guts into a well
formed module which complies with D style and Phobos guidelines etc.

Part of what puts people off (I suspect) is the 'relative' complexity of
submitting code (obtaining/learning GIT etc), the standard the code
needs to be at (well organised, documented etc), and the implied
promise/commitment that submitting code brings with it (that you'll hang
around and maintain it). But, what if we were to create a system where
people could submit code, no strings attached, in any state (they would
define the state they believe it to be in) for the more dedicated
contributors to pick up, clean up, and include as and when they could?
It could be as simple as a web page, where code is pasted, files
attached, and a license waiver agreed to.

I know I have several pieces of code floating about the place which do
useful things and would be motivated to create more if it would help the
effort, and I could get a mention in the comments at the top of the
finished module :p


Thanks for your thoughts and generosity. It's great you are sharing your  
code in the hope it adds value to the community.


That's just it however, I am not generous enough with my time to be of use  
to you/D/phobos.  I spend my free time doing other things, and not working  
on the code I have which could be of use.  I suspect there are quite a  
number of people out there who are just like me.  People who have some  
code which may be of use, in varying degrees of completeness from just an  
idea to a pretty much complete re-usable library which just needs the  
final touches etc.


If we collect these pieces of code somewhere and make it searchable then  
anyone could pick up a piece and re-use it, or work on it, or .. well  
anything they want.  That's all I'm suggesting, that we create a "well of  
lost code" and let people dump things there.


Also, if past is indicative of future, it's possible but unlikely that  
someone will take your code, bring it to perfection, and go through the  
hurdles of submitting it to Phobos.


Making a body of code into a reusable library is often comparable work  
with writing the code itself. It's also seen by many as unpleasant work,  
which means most people would be more motivated to do it for their own  
work rather than others'.


You're probably right, people prefer their own code.  And, doing the work  
required to get something to the level required for Phobos is not as  
pleasant as hacking away at more 'exciting' things, this is exactly why my  
code remains incomplete (from a Phobos submission point of view).  But,  
they don't have to work on 'my' code, they might take it and tear it to  
pieces and only really take the ideas away to create something new.  The  
point is, it's a starting point.


Things have changed a lot in the way D is evolving. This includes  
migration to git, opening the compiler, runtime, and standard library  
for contributions, and a review process for adding to the standard  
library. Focusing on the last aspect, this has been a big change from  
the previous approach in which the standard library was closed, and from  
an awkward stage in which we were inclined to accept somewhat random  
contributions (encoding, xml, json) without much due process.


By any measure I can think of, establishing a review process has been a  
tremendous success, and everything else failed. We have std.datetime,  
std.parallelism to show, and there are many more to come. The difficulty  
in carrying through a Phobos submission also means establishing a stro

Re: how to build up the library..

2011-10-06 Thread Steve Teale
Andrei,

Are there guidelines for the Phobos process?

I have put a fair amount of work, two years ago and recently, into a piece for
accessing MySQL via D. I'm looking at this as a bottom-up investigation into 
what
might be a more generalized interface for database access.

I've got to the point where I can support a good range of database operations, 
and
present result sets as arrays of D structs, which presumably implies Ranges.
There's also lower level stuff to do more complex operations. So I'm wondering 
if
I should take the first process steps. I'm retired, so I do have time to spend 
on it.

The MySQL C api is not what you could call orthogonal - in crystallography terms
it is probably Triclinic, so it may not have been the best place to start. 
There's
another guy I've had some correspondence with who is working on Postgres. He's
interested in the same idea.

What do you think?

Steve


Re: how to build up the library..

2011-10-06 Thread Andrei Alexandrescu

On 10/6/11 5:25 AM, Regan Heath wrote:

I've been lurking and contributing to this news group on and off for
years (since 2005/2006, maybe earlier). But, in all that time I have
contributed nothing to Phobos. I have contributed a set of
digest/hashing routines to Tango, because at the time Phobos wasn't
taking submissions. I have been meaning to clean my originals of these
up, get them properly documented, etc and submit them for review for
Phobos, but I just haven't had the time, and/or inclination to do so (my
free time is precious and I've just not been feeling the urge/itch to
code.. blame minecraft :p)

However, I am more than happy to hand them off in their current state to
anyone who does have both time and inclination .. and I wonder how many
other blocks of code are out there, just like mine, just waiting for the
right person to take charge of them. Would this be useful do you think?
Or would the time it takes someone to pick up new code, learn it, fine
tune it and document it.. etc be more than if they just started again
from scratch. It seems to me that sometimes, all that is needed to get a
new module off the ground is a working prototype for the guts of it,
which is what people like me who have some experience/knowledge but
little time/energy could do, before handing it to someone who has a
better idea of the D/Phobos 'way' and can organise the guts into a well
formed module which complies with D style and Phobos guidelines etc.

Part of what puts people off (I suspect) is the 'relative' complexity of
submitting code (obtaining/learning GIT etc), the standard the code
needs to be at (well organised, documented etc), and the implied
promise/commitment that submitting code brings with it (that you'll hang
around and maintain it). But, what if we were to create a system where
people could submit code, no strings attached, in any state (they would
define the state they believe it to be in) for the more dedicated
contributors to pick up, clean up, and include as and when they could?
It could be as simple as a web page, where code is pasted, files
attached, and a license waiver agreed to.

I know I have several pieces of code floating about the place which do
useful things and would be motivated to create more if it would help the
effort, and I could get a mention in the comments at the top of the
finished module :p


Thanks for your thoughts and generosity. It's great you are sharing your 
code in the hope it adds value to the community. I'm sure it does, but I 
am skeptical the impact is nearly as strong as it could. Also, if past 
is indicative of future, it's possible but unlikely that someone will 
take your code, bring it to perfection, and go through the hurdles of 
submitting it to Phobos.


Making a body of code into a reusable library is often comparable work 
with writing the code itself. It's also seen by many as unpleasant work, 
which means most people would be more motivated to do it for their own 
work rather than others'.


Things have changed a lot in the way D is evolving. This includes 
migration to git, opening the compiler, runtime, and standard library 
for contributions, and a review process for adding to the standard 
library. Focusing on the last aspect, this has been a big change from 
the previous approach in which the standard library was closed, and from 
an awkward stage in which we were inclined to accept somewhat random 
contributions (encoding, xml, json) without much due process.


By any measure I can think of, establishing a review process has been a 
tremendous success, and everything else failed. We have std.datetime, 
std.parallelism to show, and there are many more to come. The difficulty 
in carrying through a Phobos submission also means establishing a strong 
esprit de corps, a commitment to quality, and a sense of meaningfully 
moving things forward together. As far as I know many other open source 
projects follow a similar model. There is essentially no evidence in 
this space to suggest that your hypothetical model of development would 
work.



Andrei


Re: how to build up the library..

2011-10-06 Thread Jacob Carlborg

On 2011-10-06 12:25, Regan Heath wrote:

It's obvious from my last post that I think a change should be allowed.
I think you'd agree, were it not for the urgent need of other library
components.

I've been lurking and contributing to this news group on and off for
years (since 2005/2006, maybe earlier). But, in all that time I have
contributed nothing to Phobos. I have contributed a set of
digest/hashing routines to Tango, because at the time Phobos wasn't
taking submissions. I have been meaning to clean my originals of these
up, get them properly documented, etc and submit them for review for
Phobos, but I just haven't had the time, and/or inclination to do so (my
free time is precious and I've just not been feeling the urge/itch to
code.. blame minecraft :p)

However, I am more than happy to hand them off in their current state to
anyone who does have both time and inclination .. and I wonder how many
other blocks of code are out there, just like mine, just waiting for the
right person to take charge of them. Would this be useful do you think?
Or would the time it takes someone to pick up new code, learn it, fine
tune it and document it.. etc be more than if they just started again
from scratch. It seems to me that sometimes, all that is needed to get a
new module off the ground is a working prototype for the guts of it,
which is what people like me who have some experience/knowledge but
little time/energy could do, before handing it to someone who has a
better idea of the D/Phobos 'way' and can organise the guts into a well
formed module which complies with D style and Phobos guidelines etc.

Part of what puts people off (I suspect) is the 'relative' complexity of
submitting code (obtaining/learning GIT etc), the standard the code
needs to be at (well organised, documented etc), and the implied
promise/commitment that submitting code brings with it (that you'll hang
around and maintain it). But, what if we were to create a system where
people could submit code, no strings attached, in any state (they would
define the state they believe it to be in) for the more dedicated
contributors to pick up, clean up, and include as and when they could?
It could be as simple as a web page, where code is pasted, files
attached, and a license waiver agreed to.

I know I have several pieces of code floating about the place which do
useful things and would be motivated to create more if it would help the
effort, and I could get a mention in the comments at the top of the
finished module :p



I think it sounds like a good idea, assuming there actually is people 
willing to do these clean ups.


--
/Jacob Carlborg


Re: how to build up the library..

2011-10-06 Thread Regan Heath
On Thu, 06 Oct 2011 10:44:42 +0100, Regan Heath   
wrote:


On Wed, 05 Oct 2011 16:44:31 +0100, Andrei Alexandrescu  
 wrote:



On 10/5/11 10:27 AM, Regan Heath wrote:

I understand the issue, and the point you're making below, and I agree
completely. At the same time, this particular change being as simple as
it is, and as obviously beneficial as I hope I have managed to show,
would have taken less time to simply change than it has taken to argue
about.


There is the issue that every small change creates a precedent for  
similar or smaller changes. I spent this much time on this particular  
issue hoping that it would improve an entire trend going forward.


I think it may have backfired somewhat.  Now people are going to think  
no change is possible and Andrei is an 'Ogre' when it comes to his own  
modules.  In situations like this some sort of precedent or impression  
will always be created.  The best you can do is take control of it, and  
clearly define it.


In this case clearly define the conditions under which the change is  
allowed


.. or not allowed. :p

It's obvious from my last post that I think a change should be allowed.  I  
think you'd agree, were it not for the urgent need of other library  
components.


I've been lurking and contributing to this news group on and off for years  
(since 2005/2006, maybe earlier).  But, in all that time I have  
contributed nothing to Phobos.  I have contributed a set of digest/hashing  
routines to Tango, because at the time Phobos wasn't taking submissions.   
I have been meaning to clean my originals of these up, get them properly  
documented, etc and submit them for review for Phobos, but I just haven't  
had the time, and/or inclination to do so (my free time is precious and  
I've just not been feeling the urge/itch to code.. blame minecraft :p)


However, I am more than happy to hand them off in their current state to  
anyone who does have both time and inclination .. and I wonder how many  
other blocks of code are out there, just like mine, just waiting for the  
right person to take charge of them.  Would this be useful do you think?   
Or would the time it takes someone to pick up new code, learn it, fine  
tune it and document it.. etc be more than if they just started again from  
scratch.  It seems to me that sometimes, all that is needed to get a new  
module off the ground is a working prototype for the guts of it, which is  
what people like me who have some experience/knowledge but little  
time/energy could do, before handing it to someone who has a better idea  
of the D/Phobos 'way' and can organise the guts into a well formed module  
which complies with D style and Phobos guidelines etc.


Part of what puts people off (I suspect) is the 'relative' complexity of  
submitting code (obtaining/learning GIT etc), the standard the code needs  
to be at (well organised, documented etc), and the implied  
promise/commitment that submitting code brings with it (that you'll hang  
around and maintain it).  But, what if we were to create a system where  
people could submit code, no strings attached, in any state (they would  
define the state they believe it to be in) for the more dedicated  
contributors to pick up, clean up, and include as and when they could?  It  
could be as simple as a web page, where code is pasted, files attached,  
and a license waiver agreed to.


I know I have several pieces of code floating about the place which do  
useful things and would be motivated to create more if it would help the  
effort, and I could get a mention in the comments at the top of the  
finished module :p


--
Using Opera's revolutionary email client: http://www.opera.com/mail/