Re: [Chicken-users] DBI
On Mon, Apr 7, 2008 at 9:51 AM, Graham Fawcett <[EMAIL PROTECTED]> wrote: > Matthew, you just reminded me that I never made a release for the > Postgres change I made, that allows for (optional) query parameters. > I'll find a minute today to release it. Ah, it looks like Kon moved postgresql to the tags/trunk structure (r9971, March 20), which included my query-parameters in the 2.0.13 release. Thanks Kon! Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Sun, Apr 6, 2008 at 1:46 PM, Matthew Welland <[EMAIL PROTECTED]> wrote: > What is the status of this effort? > > I have written a *very* simplistic DBI which supports lowest common > demoninator access to sqlite3 and postgresql. It is only 90 or so lines of > code but so far seems enough to let me write for sqlite and switch to > postgresql etc. Matthew, you just reminded me that I never made a release for the Postgres change I made, that allows for (optional) query parameters. I'll find a minute today to release it. Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
The status is I'm lazy and haven't done much of anything. I did take a brief look at OpenDBX: http://www.linuxnetworks.de/doc/index.php/OpenDBX Perhaps we'd be better off wrapping this than writing our own wrapper for each DB? Thoughts anyone? Matthew Welland wrote: What is the status of this effort? I have written a *very* simplistic DBI which supports lowest common demoninator access to sqlite3 and postgresql. It is only 90 or so lines of code but so far seems enough to let me write for sqlite and switch to postgresql etc. I'd be interested in making this into an egg if anyone thought it'd be useful to them but I don't want where we have multiple solutions to the same problem on the eggs page so I'll pass if the "real" dbi is coming to market any time soon. Let me know, eggify or put on snippets or wait for real dbi? Also, if I did make it an egg what to call it? sdbi for simple dbi? ;; ;; sqlite3 example simple test code for ;; (use sqlite3) (system "rm -f tests/test.db") (load "mrwdbi.scm") (dbi:open 'sqlite3 '((dbname . "tests/test.db"))) (dbi:exec db "CREATE TABLE foo(id INTEGER PRIMARY KEY,name TEXT);") (dbi:exec db "INSERT INTO foo(name) VALUES(?);" "Matt") (dbi:for-each-row (lambda (tuple) (print (vector-ref tuple 0) " " (vector-ref tuple 1))) db "SELECT * FROM foo;") (dbi:close db) (system "rm -f tests/test.db") ;; ;; postgresql simple test code ;; (system "dropdb test") (system "createdb test") (use postgresql) (load "mrwdbi.scm") (define db (dbi:open 'pg '((dbname . "test") (user . "matt") (password . "**") (host . "localhost" (dbi:exec db "CREATE TABLE foo(id SERIAL PRIMARY KEY,name TEXT);") (dbi:exec db "INSERT INTO foo(name) VALUES(?);" "Matt") (dbi:for-each-row (lambda (tuple) (print (vector-ref tuple 0) " " (vector-ref tuple 1))) db "SELECT * FROM foo;") (dbi:close db) (system "dropdb test") On Saturday 01 March 2008 10:26:45 am Vincent Manis wrote: On 2008 Feb 29, at 23:13, Alex Shinn wrote: However, different backends represent this (and various other extensions we'll eventually want) in different ways. SQL could just generate a standard syntax that all the backends would have to support, but then they'd be reparsing the SQL string we just generated and then putting it back together in their own way. It makes more sense to integrate the SQL generation with the backends from the start. This all sounds uncomfortably like ODBC to me. I would not use a module like that, but would use a DBI-like module, for the reasons we discussed a couple of days ago: prototyping, relatively quick-and-dirty applications, and teaching. A caution against overengineering isn't out of place here. What is the problem this high-level API is trying to solve? -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
What is the status of this effort? I have written a *very* simplistic DBI which supports lowest common demoninator access to sqlite3 and postgresql. It is only 90 or so lines of code but so far seems enough to let me write for sqlite and switch to postgresql etc. I'd be interested in making this into an egg if anyone thought it'd be useful to them but I don't want where we have multiple solutions to the same problem on the eggs page so I'll pass if the "real" dbi is coming to market any time soon. Let me know, eggify or put on snippets or wait for real dbi? Also, if I did make it an egg what to call it? sdbi for simple dbi? ;; ;; sqlite3 example simple test code for ;; (use sqlite3) (system "rm -f tests/test.db") (load "mrwdbi.scm") (dbi:open 'sqlite3 '((dbname . "tests/test.db"))) (dbi:exec db "CREATE TABLE foo(id INTEGER PRIMARY KEY,name TEXT);") (dbi:exec db "INSERT INTO foo(name) VALUES(?);" "Matt") (dbi:for-each-row (lambda (tuple) (print (vector-ref tuple 0) " " (vector-ref tuple 1))) db "SELECT * FROM foo;") (dbi:close db) (system "rm -f tests/test.db") ;; ;; postgresql simple test code ;; (system "dropdb test") (system "createdb test") (use postgresql) (load "mrwdbi.scm") (define db (dbi:open 'pg '((dbname . "test") (user . "matt") (password . "**") (host . "localhost" (dbi:exec db "CREATE TABLE foo(id SERIAL PRIMARY KEY,name TEXT);") (dbi:exec db "INSERT INTO foo(name) VALUES(?);" "Matt") (dbi:for-each-row (lambda (tuple) (print (vector-ref tuple 0) " " (vector-ref tuple 1))) db "SELECT * FROM foo;") (dbi:close db) (system "dropdb test") On Saturday 01 March 2008 10:26:45 am Vincent Manis wrote: > On 2008 Feb 29, at 23:13, Alex Shinn wrote: > > However, different backends represent > > this (and various other extensions we'll eventually want) in > > different ways. SQL could just generate a standard syntax > > that all the backends would have to support, but then they'd > > be reparsing the SQL string we just generated and then > > putting it back together in their own way. It makes more > > sense to integrate the SQL generation with the backends from > > the start. > > This all sounds uncomfortably like ODBC to me. I would not > use a module like that, but would use a DBI-like module, > for the reasons we discussed a couple of days ago: prototyping, > relatively quick-and-dirty applications, and teaching. > > A caution against overengineering isn't out of place here. > What is the problem this high-level API is trying to solve? > > -- vincent > > > ___ > Chicken-users mailing list > Chicken-users@nongnu.org > http://lists.nongnu.org/mailman/listinfo/chicken-users -- http://www.kiatoa.com, fight for a better world. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On 2008 Feb 29, at 23:13, Alex Shinn wrote: However, different backends represent this (and various other extensions we'll eventually want) in different ways. SQL could just generate a standard syntax that all the backends would have to support, but then they'd be reparsing the SQL string we just generated and then putting it back together in their own way. It makes more sense to integrate the SQL generation with the backends from the start. This all sounds uncomfortably like ODBC to me. I would not use a module like that, but would use a DBI-like module, for the reasons we discussed a couple of days ago: prototyping, relatively quick-and-dirty applications, and teaching. A caution against overengineering isn't out of place here. What is the problem this high-level API is trying to solve? -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
> "Tobia" == Tobia Conforto <[EMAIL PROTECTED]> writes: Tobia> Alex Shinn wrote: >> The biggest issue I see with the sql egg right now is >> it currently hard-codes all values, generating a new >> SQL expression every time. You want it to be able to >> represent placeholder values (named or just with a ?) >> ... It makes more sense to integrate the SQL >> generation with the backends from the start. Tobia> What you propose might get really complex. [...] Tobia> The DBI should just provide a standard way to Tobia> compile prepared statements, so that an improved Tobia> sql egg could use prepared statements across all Tobia> DBs that support it. IMHO the key is lessening Tobia> the burden on the backend writer, while providing Tobia> most features of modern DBs in a consistent Tobia> interface. I'd have to disagree, and say that the key, as with any programming library, is lessening the burden on the user. Do the hard work once so it doesn't have to be duplicated. Every other DBI library for every language I've ever seen allows prepared statements. >> The issue isn't just with the actual query string >> generated either. We may want the high-level >> interface to always allow the LIMIT and OFFSET >> keywords to page results, even if the backend doesn't >> support it, by emulating it on the client side. Tobia> Uhh, still more burden on the backend writer? I Tobia> don't like the sound of it. Besides, if you need Tobia> limit and offset, you might as well upgrade to Tobia> another RDBMS. ROFL! Tell Oracle users to "upgrade" to another RDBMS :) Oracle has no LIMIT or OFFSET - there's a trick you can use to make a nested SELECT and filter by row-number, but usually it's recommended to just return a cursor and let the client read and discard the initial unneeded rows then only read the remaining LIMIT rows. -- Alex ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Alex Shinn wrote: The biggest issue I see with the sql egg right now is it currently hard-codes all values, generating a new SQL expression every time. You want it to be able to represent placeholder values (named or just with a ?) ... It makes more sense to integrate the SQL generation with the backends from the start. What you propose might get really complex. Some database may allow prepared statements with a ? in place of column names, while others don't. How does the library know which replacement slots will be table names and which will be literals, at prepared statement creation time, before seeing the actual values? Taking these decisions from the user and putting them into the library means writing lots of code to do static analysis of the s-expr sql language. Which is not a bad thing per se, but it would need to be backend-specific, and I'm not sure most backend writers (if any at all) would do it. The DBI should just provide a standard way to compile prepared statements, so that an improved sql egg could use prepared statements across all DBs that support it. IMHO the key is lessening the burden on the backend writer, while providing most features of modern DBs in a consistent interface. The issue isn't just with the actual query string generated either. We may want the high-level interface to always allow the LIMIT and OFFSET keywords to page results, even if the backend doesn't support it, by emulating it on the client side. Uhh, still more burden on the backend writer? I don't like the sound of it. Besides, if you need limit and offset, you might as well upgrade to another RDBMS. Tobia ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
> "Tobia" == Tobia Conforto <[EMAIL PROTECTED]> writes: Tobia> What's wrong with the sql egg? Can't we just use Tobia> that, maybe improve it a bit? Sure, I didn't mean to rule that out. The biggest issue I see with the sql egg right now is it currently hard-codes all values, generating a new SQL expression every time. You want it to be able to represent placeholder values (named or just with a ? as in Perl's DBI) allowing the backends to cache the SQL expression and apply it to different data. However, different backends represent this (and various other extensions we'll eventually want) in different ways. SQL could just generate a standard syntax that all the backends would have to support, but then they'd be reparsing the SQL string we just generated and then putting it back together in their own way. It makes more sense to integrate the SQL generation with the backends from the start. The issue isn't just with the actual query string generated either. We may want the high-level interface to always allow the LIMIT and OFFSET keywords to page results, even if the backend doesn't support it, by emulating it on the client side. This would have to be handled as a combination of query string generation and result set processing. -- Alex ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Graham Fawcett wrote: (eq? (void) (void)) => #t is a property that shouldn't exist (eq? (void) (void)) => #f is better, raising an exception is better still. I think SQL has it right here: NULL any-op anything, or in s-expr (any- op NULL anything), gives NULL. So NULL is neither equal nor disequal to NULL, or to "hello", it's NULL to them. (I'm not suggesting adding this behaviour to Chicken, as it would degrade performance for every simple operation without a good reason. I'm just noting what I think is a nice approach.) Tobia ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Fri, Feb 29, 2008 at 10:41 AM, felix winkelmann <[EMAIL PROTECTED]> wrote: > On Thu, Feb 28, 2008 at 4:02 PM, Graham Fawcett > > <[EMAIL PROTECTED]> wrote: > > > > > It would be a smart idea to change the implementation, then, so that > > the unspecified value could not be tested with (eq?). That would > > prevent it from being 'misused'. > > The unspecified value is unspecified. It has both no identity and > no efforts are made to make it identity-less. Right, but (eq? (void) (void)) => #t is a property that shouldn't exist for two unspecified values: by definition it gives identity to unspecified. (eq? (void) (void)) => #f is better, raising an exception is better still. To preserve the 'undefined' meaning, any functions that can test # should really be internal, e.g. in the ##sys# namespace. But as you say, it's unspecified, so this is a divergent discussion. :-) > > There does seem to be a good case for an immediate value that *can* be > > tested this way, though. John et. al. wouldn't have used (void) in > > eggs if there weren't. Record instances aren't really a great answer > > (though I suggested them myself) since different records of the same > > type will fail an identity test. > > Unless you use a single unique instance. That would be problematic in compiled code, would it not? Where is the instance stored? Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 4:02 PM, Graham Fawcett <[EMAIL PROTECTED]> wrote: > > It would be a smart idea to change the implementation, then, so that > the unspecified value could not be tested with (eq?). That would > prevent it from being 'misused'. The unspecified value is unspecified. It has both no identity and no efforts are made to make it identity-less. > > There does seem to be a good case for an immediate value that *can* be > tested this way, though. John et. al. wouldn't have used (void) in > eggs if there weren't. Record instances aren't really a great answer > (though I suggested them myself) since different records of the same > type will fail an identity test. Unless you use a single unique instance. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Alex Shinn wrote: the column info should be present once, not duplicated for every row. Since you may want to manage a huge number of rows in memory at once it makes sense to optimize for size. This could be a vector but it would probably be best to leave it unspecified and use an opaque accessor to retrieve fields, so that individual backends could just provide direct access to the row objects returned by the C library, without needing to copy any data. +1 Utility functions could convert a row into an alist, in case the programmer needs/prefers one. We should certainly build the DBI layer, but we should include something like SchemeQL on top of it. However, a big complaint I have with SchemeQL is that it's entirely macro-based, and provides no way to leverage its power to build dynamic queries. Our SchemeQL should be combinator based (something like the sql egg) What's wrong with the sql egg? Can't we just use that, maybe improve it a bit? Tobia ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 10:30 AM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Thu, Feb 28, 2008 at 10:05:58AM -0500, Graham Fawcett wrote: > > > Why the thunk? (why not directly the port?) > > > > Laziness: it avoids the overhead of setting up the input port if it's > > not required. You might want to iterate over a set of (id, name, blob) > > records and only open the blob if the name meets some criteria that > > are local to the app (i.e. can't be expressed in a WHERE clause). > > You can make a 'smart' custom port that only really opens the blob when > you first read from it (it has to be a custom port anyway, so this is > not too much extra work). This makes for a more convenient API, IMHO. That's true. I was going to argue that it doesn't have to be a custom port (some interfaces may return a TCP port to consume the blob, for example) and that I'd rather not add an extra layer. But using a custom port would also ensure that the right cleanup code was called, and that's a big win. The custom-port is a good solution. G ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 10:05:58AM -0500, Graham Fawcett wrote: > > Why the thunk? (why not directly the port?) > > Laziness: it avoids the overhead of setting up the input port if it's > not required. You might want to iterate over a set of (id, name, blob) > records and only open the blob if the name meets some criteria that > are local to the app (i.e. can't be expressed in a WHERE clause). You can make a 'smart' custom port that only really opens the blob when you first read from it (it has to be a custom port anyway, so this is not too much extra work). This makes for a more convenient API, IMHO. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgpIyFIIGhZsD.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 9:54 AM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Thu, Feb 28, 2008 at 09:47:08AM -0500, Graham Fawcett wrote: > > Yes, input port was what I was thinking. Thanks. The input port would > > return the body of the LOB and return #!eof when it's consumed. > > > > The "Chicken blob or string" options are redundant, so the revised > > proposal is to represent a LOB with a thunk that evaluates to an input > > port. > > Why the thunk? (why not directly the port?) Laziness: it avoids the overhead of setting up the input port if it's not required. You might want to iterate over a set of (id, name, blob) records and only open the blob if the name meets some criteria that are local to the app (i.e. can't be expressed in a WHERE clause). Best, Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 2:40 AM, felix winkelmann <[EMAIL PROTECTED]> wrote: > On Wed, Feb 27, 2008 at 10:31 PM, Peter Bex <[EMAIL PROTECTED]> wrote: > > On Wed, Feb 27, 2008 at 04:23:37PM -0500, Graham Fawcett wrote: > > > > Can you even check for void? Afaik there's no VOID? procedure. > > > > > > You can; just compare with another (void) value: > > > > > > (define void? (cute eq? (void) <>)) > > > > That sounds rather brittle. Afaik "void" is defined as "no value". > > > > One possible and plausible implementation of VOID is this: > > > > (define (void) (values)) > > > > (eq? (values) (values)) is #t, but I'm not sure how safe it is to > > depend on that. Especially since VOID is some kind of "undefined" > > value, nobody says this representation can't change. I don't think > > you should depend on this implementation detail. > > > > Absolutely. Tha values definition of void above is btw not equivalent and > would break in many places. I stand corrected. :-) It would be a smart idea to change the implementation, then, so that the unspecified value could not be tested with (eq?). That would prevent it from being 'misused'. There does seem to be a good case for an immediate value that *can* be tested this way, though. John et. al. wouldn't have used (void) in eggs if there weren't. Record instances aren't really a great answer (though I suggested them myself) since different records of the same type will fail an identity test. Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 09:47:08AM -0500, Graham Fawcett wrote: > Yes, input port was what I was thinking. Thanks. The input port would > return the body of the LOB and return #!eof when it's consumed. > > The "Chicken blob or string" options are redundant, so the revised > proposal is to represent a LOB with a thunk that evaluates to an input > port. Why the thunk? (why not directly the port?) Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgpHNbPsGXjRn.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Thu, Feb 28, 2008 at 4:11 AM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Wed, Feb 27, 2008 at 02:27:36PM -0800, Vincent Manis wrote: > > On 2008 Feb 27, at 13:27, Graham Fawcett wrote: > > > At the driver level, LOBs are often handled with a stream-based > > > interface. For an LOB, I'd suggest representing it with a a thunk > > > which, when evaluated, returns an input stream, Chicken blob or a > > > string. That would allow you to inspect the other column values before > > > deciding whether to evaluate the LOB. > > +1. -- vincent > I assume with "input stream" you mean "input port"? (With "stream", I > think of SRFI-40/41) > > In that case, +1. Yes, input port was what I was thinking. Thanks. The input port would return the body of the LOB and return #!eof when it's consumed. The "Chicken blob or string" options are redundant, so the revised proposal is to represent a LOB with a thunk that evaluates to an input port. Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
dbi:query-fold, dbi:query-map, query-for-each. I thought about implementing these, but I haven't been able to think of the use case that makes them necessary in the presence Scheme's fold, map, and for-each, other than as shorthand (which could be define'd in place in a heartbeat for anyone who wants it) Result streaming. You want to avoid having a query function that returns a list of rows, where possible, because some DB APIs will let you stream rows from the server as you consume them. For a million row result, being able to stream them from the server into a function that converts them to HTML and streams them out to a browser, or whatever, is a big save in server memory :-) Ideally, have your query function return a proper *stream* of conses with promises in, then use existing stream fold/map/filter on them, of course. Vague memory there's an SRFI for that, but I've never had the need to look it up in detail. dbi:insert-id Should this come from a function, or should it be returned as a response to dbi:query? I wouldn't mind seeing the query handler be smart enough that if my query involves INSERT and i've inserted a row that becomes ID 42, that the response would be something like '((rows-affected 1) (insert-id 42)) Certainly, we'd want to look at what we'd want to normalize these labels to, but that's not a huge issue. The related question is whether singleton response values (like rows-affected with nothing else) should return as a singleton (a)list or as a numeric value --> My vote would be to return the singleton (a)list to simplify the conditional checking the caller needs to use. In my past I've preferred to have "query" procedures for SQL queries, and "execute" procedures for INSERT et al, which don't return a table, just success/failure. Then you can have a more specific procedure for "insert" that returns inserted ID metadata. ABS -- Alaric Snell-Pym Work: http://www.snell-systems.co.uk/ Play: http://www.snell-pym.org.uk/alaric/ Blog: http://www.snell-pym.org.uk/?author=4 ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On 27 Feb 2008, at 8:11 pm, John Cowan wrote: In reality, though, I think portability between databases is more hypothetical than real. Projects typically start with one database and stick to it, for moving between databases *even if a portability layer is in use* turns out to be hard -- all sorts of stuff outside the main code base ends up changing (path names, load scripts, whatever). Yeah, but finer-grained things than apps can be portable. Eg, OR mapping layers. Being general-purpose tools, they want to be able to work on lots of different SQL servers, so the authors of them often avoid server-specific SQL, and where they have to for efficiency or whatever, make a decision what syntax to use there and then in that one place. So they benefit from a generic interface for the bulk of their queries. ABS -- Alaric Snell-Pym Work: http://www.snell-systems.co.uk/ Play: http://www.snell-pym.org.uk/alaric/ Blog: http://www.snell-pym.org.uk/?author=4 ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
> "John" == John Cowan <[EMAIL PROTECTED]> writes: John> I suggest that a row be an a-list, and that null John> columns be represented by being non-existent in John> the a-list. I disagree - the column info should be present once, not duplicated for every row. Since you may want to manage a huge number of rows in memory at once it makes sense to optimize for size. This could be a vector but it would probably be best to leave it unspecified and use an opaque accessor to retrieve fields, so that individual backends could just provide direct access to the row objects returned by the C library, without needing to copy any data. We should certainly build the DBI layer, but we should include something like SchemeQL on top of it. However, a big complaint I have with SchemeQL is that it's entirely macro-based, and provides no way to leverage its power to build dynamic queries. Our SchemeQL should be combinator based (something like the sql egg). We can use MATCH (maybe with extensions) to destructure the rows conveniently. -- Alex ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 02:27:36PM -0800, Vincent Manis wrote: > On 2008 Feb 27, at 13:27, Graham Fawcett wrote: > > At the driver level, LOBs are often handled with a stream-based > > interface. For an LOB, I'd suggest representing it with a a thunk > > which, when evaluated, returns an input stream, Chicken blob or a > > string. That would allow you to inspect the other column values before > > deciding whether to evaluate the LOB. > > > +1. -- vincent I assume with "input stream" you mean "input port"? (With "stream", I think of SRFI-40/41) In that case, +1. Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgpgFtbFEzql0.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 10:31 PM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Wed, Feb 27, 2008 at 04:23:37PM -0500, Graham Fawcett wrote: > > > Can you even check for void? Afaik there's no VOID? procedure. > > > > You can; just compare with another (void) value: > > > > (define void? (cute eq? (void) <>)) > > That sounds rather brittle. Afaik "void" is defined as "no value". > > One possible and plausible implementation of VOID is this: > > (define (void) (values)) > > (eq? (values) (values)) is #t, but I'm not sure how safe it is to > depend on that. Especially since VOID is some kind of "undefined" > value, nobody says this representation can't change. I don't think > you should depend on this implementation detail. > Absolutely. Tha values definition of void above is btw not equivalent and would break in many places. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 10:35 PM, Graham Fawcett <[EMAIL PROTECTED]> wrote: > > (void) returns the unspecified value, in Chicken, # -- as > does (values). But the unspecified value is a value, and can be tested > for identity with eq?. Bu it is unspecified! How can you compare the identity of something that has none? "void" means: the return value is not specific and may even be different over multiple invocations. It gives the compiler the opportunity to not worry about returning some particular value, since it indicates that a computation was performed solely for it's side effects. In short: don't rely on the result of "void". It's reason of existence is to have something to return as a result that should not be relied on. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: void as a return value (Re: [Chicken-users] DBI)
On 2008 Feb 27, at 19:17, John Cowan wrote, quoting me: alternatively, an object called the-SQL-null-object could be created (perhaps as a record type value). That is a priori reasonable, but it won't work with eq?, whereas the unspecified value will. I fail to understand why eq? compatibility is significant, one provides a predicate to test SQL null-ness. In order to sort out this farrago of nothingness, let me suggest the following: a. '() is just right for a multivalued field that happens to contain no values, but is unsuitable for indicating SQL null. b. (the-SQL-null-object) returns an SQL null value, and (SQL-null? x) tells you whether x is an SQL null. (I'm not wedded to those names, just using them as an example.) c. Whether (the-SQL-null-object) returns a value of a disjoint type from that returned by (void) is theoretically unimportant, but it would be more elegant and explainable if the return value behaves in a manner that's consistent with #!eof. -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: void as a return value (Re: [Chicken-users] DBI)
Vincent Manis scripsit: > Please, please, don't ever write functions that return void as anything > other than an indication that no value was returned. If no value is returned, you should use (values), which genuinely returns no values and is distinguishable by call-with-values or any of the macros built over it. It's true that if you use (values) in a context where there must be a value, Chicken coerces it to #, but they are not the same concept. > #;44> (car (db-fetch-row (db-query "select salary where empname='Bilbo > Baggins'"))) > #;45> > > So now, (a) you get no output, which might be mystifying and (b) car > is now returning void. Neither of these violates any language rule, > but each violates the Law of Least Astonishment. I grant (a) is surprising, but I deny that (b) is. > For SQL nulls, one could use '(), as has been mentioned; That works only because SQL has such an impoverished domain of values. The same is not true for other languages that Chicken can interface with, including languages for non-SQL database engines. Identifying the null value with the zero-length list is really a data pun. > alternatively, an object called the-SQL-null-object could be created > (perhaps as a record type value). That is a priori reasonable, but it won't work with eq?, whereas the unspecified value will. > Incidentally, there are several different meanings for null in SQL, True but not immediately relevant. > People have enough trouble understanding SQL null without further > conflating it with `this function returns no values'. As I explained above, they are actually not conflated. -- XQuery Blueberry DOMJohn Cowan Entity parser dot-com [EMAIL PROTECTED] Abstract schemata http://www.ccil.org/~cowan XPointer errata Infoset Unicode BOM --Richard Tobin ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Peter Bex scripsit: > That sounds rather brittle. Afaik "void" is defined as "no value". On Chicken, which is what we are talking about, it's a specific immediate value, like #t, #f, or (). A number of eggs already depend on this; for example, it's the Chicken equivalent of Lua's nil, and is used for SQL NULL on some but not all existing database eggs. > One possible and plausible implementation of VOID is this: > > (define (void) (values)) That happens to deliver the void value on Chicken as well; on some Schemes it's an error (attempt to deliver other than one value to a "normal" continuation). -- John Cowan [EMAIL PROTECTED] http://ccil.org/~cowan Linguistics is arguably the most hotly contested property in the academic realm. It is soaked with the blood of poets, theologians, philosophers, philologists, psychologists, biologists and neurologists, along with whatever blood can be got out of grammarians. - Russ Rymer ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: void as a return value (Re: [Chicken-users] DBI)
Vincent Manis wrote: \begin{rant} On the subject of using void as a return value (rather than to indicate that a function or method doesn't return anything), E. Please, please, don't ever write functions that return void as anything other than an indication that no value was returned. #;44> (car (db-fetch-row (db-query "select salary where empname='Bilbo Baggins'"))) #;45> I don't yet have an opinion on using void, but this function would return either a list: ( (void) ) or an alist: ( (salary . (void) ) depending on which we used to represent rows. Either way, there would indeed be a return value. So now, (a) you get no output, which might be mystifying and (b) car is now returning void. Neither of these violates any language rule, but each violates the Law of Least Astonishment. For SQL nulls, one could use '(), as has been mentioned; alternatively, an object called the-SQL-null-object could be created (perhaps as a record type value). Incidentally, there are several different meanings for null in SQL, including no information, not applicable, no value presently exists (but one might in the future), etc. You can find lengthy essays on the appropriateness of using NULL in several of Chris Date's `Writings on Database' books. People have enough trouble understanding SQL null without further conflating it with `this function returns no values'. \end{rant} Sorry :-) -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
void as a return value (Re: [Chicken-users] DBI)
\begin{rant} On the subject of using void as a return value (rather than to indicate that a function or method doesn't return anything), E. Please, please, don't ever write functions that return void as anything other than an indication that no value was returned. #;44> (car (db-fetch-row (db-query "select salary where empname='Bilbo Baggins'"))) #;45> So now, (a) you get no output, which might be mystifying and (b) car is now returning void. Neither of these violates any language rule, but each violates the Law of Least Astonishment. For SQL nulls, one could use '(), as has been mentioned; alternatively, an object called the-SQL-null-object could be created (perhaps as a record type value). Incidentally, there are several different meanings for null in SQL, including no information, not applicable, no value presently exists (but one might in the future), etc. You can find lengthy essays on the appropriateness of using NULL in several of Chris Date's `Writings on Database' books. People have enough trouble understanding SQL null without further conflating it with `this function returns no values'. \end{rant} Sorry :-) -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On 2008 Feb 27, at 13:27, Graham Fawcett wrote: At the driver level, LOBs are often handled with a stream-based interface. For an LOB, I'd suggest representing it with a a thunk which, when evaluated, returns an input stream, Chicken blob or a string. That would allow you to inspect the other column values before deciding whether to evaluate the LOB. +1. -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On 2008 Feb 27, at 12:11, John Cowan wrote: In reality, though, I think portability between databases is more hypothetical than real. Projects typically start with one database and stick to it, for moving between databases *even if a portability layer is in use* turns out to be hard -- all sorts of stuff outside the main code base ends up changing (path names, load scripts, whatever). Agreed. Not only the API but even the dialect of SQL in use changes enough that one must review all the DB code in an application when the underlying DBMS changes. (Even when the old API works with the new DBMS, performance may be so abysmal that a rewrite is still necessary. I remember consulting with a team who were shocked when I told them that although you CAN use ODBC with Oracle, you really really don't want to. Switching from ODBC to OCI resulted in a 40% performance increase for their mid-tier server.) That said, a DBI is still useful, for several reasons. First, management may not have decided which DBMS is to be used, or may reverse their decision at an inopportune time. Whether prototyping or doing early production development, a DBI can be very useful. Second, I have taught database classes, and grew to love the fact that a DBI helps people learn the concepts without getting into a messof stuff that's not really relevant. -- vincent ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 4:31 PM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Wed, Feb 27, 2008 at 04:23:37PM -0500, Graham Fawcett wrote: > > > Can you even check for void? Afaik there's no VOID? procedure. > > > > You can; just compare with another (void) value: > > > > (define void? (cute eq? (void) <>)) > > That sounds rather brittle. Afaik "void" is defined as "no value". (void) returns the unspecified value, in Chicken, # -- as does (values). But the unspecified value is a value, and can be tested for identity with eq?. > (eq? (values) (values)) is #t, but I'm not sure how safe it is to > depend on that. Especially since VOID is some kind of "undefined" > value, nobody says this representation can't change. I don't think > you should depend on this implementation detail. It's an implementation detail of Chicken, but it is highly unlikely that it will change. Void is nebulous as a concept, but its Chicken implementation is concrete. Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 04:23:37PM -0500, Graham Fawcett wrote: > > Can you even check for void? Afaik there's no VOID? procedure. > > You can; just compare with another (void) value: > > (define void? (cute eq? (void) <>)) That sounds rather brittle. Afaik "void" is defined as "no value". One possible and plausible implementation of VOID is this: (define (void) (values)) (eq? (values) (values)) is #t, but I'm not sure how safe it is to depend on that. Especially since VOID is some kind of "undefined" value, nobody says this representation can't change. I don't think you should depend on this implementation detail. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgptr55Lkwtno.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 4:04 PM, Peter Bex <[EMAIL PROTECTED]> wrote: > On Wed, Feb 27, 2008 at 02:47:14PM -0600, Jeremy Sydik wrote: > > dbi:query-fold, dbi:query-map, query-for-each. I thought about > > implementing these, but I > > haven't been able to think of the use case that makes them necessary > > in the presence > > Scheme's fold, map, and for-each, other than as shorthand (which > > could be define'd > > in place in a heartbeat for anyone who wants it) > > No. If you want to look at a result set that consists of several hundred > binary blobs of megabytes each, you most certainly don't want to implement > this as a "fetch all into one list" operation. You would want to load in > one row, handle it, then take the next, etc. At the driver level, LOBs are often handled with a stream-based interface. For an LOB, I'd suggest representing it with a a thunk which, when evaluated, returns an input stream, Chicken blob or a string. That would allow you to inspect the other column values before deciding whether to evaluate the LOB. G ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 4:04 PM, Peter Bex <[EMAIL PROTECTED]> wrote: > > I've tended to let null be '(), but that partly comes from liking the > > look of > > (null? (alist-ref 'field result)) I'm not entirely comfortable with > > leaving the > > value entirely absent simply because the mapping I mention to value > > lists and vectors becomes more problematic. That said, my usage of > > value lists and vectors is limited enough that I'm not that tied to it > > either. > > Can you even check for void? Afaik there's no VOID? procedure. You can; just compare with another (void) value: (define void? (cute eq? (void) <>)) Graham ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Jeremy Sydik wrote: I've been working a little in the same vein, but it's still pretty tied to a specific project My needs are pretty light, but I'm finding that the most useful functions seem to be sql:query-list and sql:query-alist I started out thinking in terms of Perl/Python type DBI, but I'm questioning that now. I'd like to see a lightweight layer that means I don't have to remember as many specifics of the specific DB egg -- I agree with John that, most of the time, plugging in multiple DBs isn't that relevant. I have one project that does it, but it uses such basic SQL-92 that I'm getting away with supporting multiple DBs. In terms of staying lightweight, Agreed, light weight is my goal as well. I'd like to look at the suggested functions: dbi:connect => I'm currently doing this as individual (driver:get-connection)'s that produce a function that takes a message to support the rest of the dbi. This seems like a potential win I'm not sure I understand. Do you mean having functions like the following: dbi:connect-mysql dbi:connect-postgresql and etc? dbi:query => like I mentioned above, I'm using query-list and query-alist. I also see value for query-vector, but haven't done much with it. The question is, would we be better having individual functions or a single dbi:query that takes a (defaulted) argument that specifies the output? I'd like to have a single representation for a row, myself, so we can just have query return whatever we decide that should be, unless there are compelling reasons to have multiple output formats. Perhaps there are performance issues of alists vs lists vs vectors that would come into play? I have no idea. dbi:num-rows => I've found that I almost always end up using (length) instead. Probably not optimal, but I've not had a major problem here. dbi:fetch-row => I've not used this either, but I'm usually pushing my queried list into a for-each or a map. the question is, what is our specific use case? num-rows and fetch are actually there to support an implementation of representing query results as Streams that I'm considering, mostly. dbi:query-fold, dbi:query-map, query-for-each. I thought about implementing these, but I haven't been able to think of the use case that makes them necessary in the presence Scheme's fold, map, and for-each, other than as shorthand (which could be define'd in place in a heartbeat for anyone who wants it) These would be here for performance. To use the Scheme map function, we have to build up a list of all the resulting rows first. With a dbi:query-map function, we wouldn't. This is the also the same reason I was thinking about a Stream implementation. If that ended up being workable we wouldn't need these. dbi:insert-id Should this come from a function, or should it be returned as a response to dbi:query? I wouldn't mind seeing the query handler be smart enough that if my query involves INSERT and i've inserted a row that becomes ID 42, that the response would be something like '((rows-affected 1) (insert-id 42)) Certainly, we'd want to look at what we'd want to normalize these labels to, but that's not a huge issue. The related question is whether singleton response values (like rows-affected with nothing else) should return as a singleton (a)list or as a numeric value --> My vote would be to return the singleton (a)list to simplify the conditional checking the caller needs to use. I'll add this to the open questions on the Wiki, I'm not sure what we should do about return values in general. This leaves (dbi:connect driver-proc [[connection params]]) In my case, I'm using SRFI-89 style define* for named params and defaults. What do other people think of this approach? (dbi:query conn str [[output type option?]]) With alist, the output type option probably isn't that important depending on how NULL is handled. It might also be nice to make query smart enough to give sensible responses for non SELECT queries, so we'd need to decide what the alist-names for these should look like Is this over-simplified? Row representation. I think my preference would be using alists as the the representation Thinking about it, Scheme already gives us everything we need to get value lists, vectors, and hash-tables if we start from alists, so it seems like the better choice. Agreed. I've tended to let null be '(), but that partly comes from liking the look of (null? (alist-ref 'field result)) I'm not entirely comfortable with leaving the value entirely absent simply because the mapping I mention to value lists and vectors becomes more problematic. That said, my usage of value lists and vectors is limited enough that I'm not that tied to it either. That's true, conversion to other representations from the alist will have to be considered. ___
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 02:47:14PM -0600, Jeremy Sydik wrote: > I've been working a little in the same vein, but it's still pretty > tied to a specific project > My needs are pretty light, but I'm finding that the most useful > functions seem to be > > sql:query-list > and > sql:query-alist > > I'd like to look at the > suggested functions: > > dbi:num-rows => I've found that I almost always end up using (length) > instead. Probably not > optimal, but I've not had a major problem here. > dbi:fetch-row => I've not used this either, but I'm usually pushing my > queried list into a for-each > or a map. the question is, what is our specific use case? > dbi:query-fold, dbi:query-map, query-for-each. I thought about > implementing these, but I > haven't been able to think of the use case that makes them necessary > in the presence > Scheme's fold, map, and for-each, other than as shorthand (which > could be define'd > in place in a heartbeat for anyone who wants it) No. If you want to look at a result set that consists of several hundred binary blobs of megabytes each, you most certainly don't want to implement this as a "fetch all into one list" operation. You would want to load in one row, handle it, then take the next, etc. As I've mentioned on the wiki (can we please move the discussion there?), instead of using these particular three procedures, I'd prefer it if DBI would just return a SRFI-41 stream so that the user has a proper list library at his disposal, without the problems I've described above. (the GC could clean up rows whenever needed) > dbi:insert-id Should this come from a function, or should it be > returned as a response to > dbi:query? I wouldn't mind seeing the query handler be smart enough > that if my query > involves INSERT and i've inserted a row that becomes ID 42, that the > response would > be something like '((rows-affected 1) (insert-id 42)) Certainly, we'd > want to look at what > we'd want to normalize these labels to, but that's not a huge issue. Sounds like a good idea. Why make it two operations if you can do it in one you will very often want to call anyway? > The related question is whether singleton response values (like rows- > affected with > nothing else) should return as a singleton (a)list or as a numeric > value --> My vote would > be to return the singleton (a)list to simplify the conditional > checking the caller needs > to use. Returning the same type of result value always is a Good Thing, I agree. > This leaves > (dbi:connect driver-proc [[connection params]]) > In my case, I'm using SRFI-89 style define* for named params and > defaults. What do > other people think of this approach? I'm not sure about this point yet. I'm more concerned about how to specify what implementation to use. You wouldn't want DBI to have all other database eggs as its dependencies. If you only want to connect to a MySQL db, you only should need that egg. > Row representation. I think my preference would be using alists as > the the representation > Thinking about it, Scheme already gives us everything we need to get > value lists, vectors, > and hash-tables if we start from alists, so it seems like the better > choice. Indeed, alists sounds best. > I've tended to let null be '(), but that partly comes from liking the > look of > (null? (alist-ref 'field result)) I'm not entirely comfortable with > leaving the > value entirely absent simply because the mapping I mention to value > lists and vectors becomes more problematic. That said, my usage of > value lists and vectors is limited enough that I'm not that tied to it > either. Can you even check for void? Afaik there's no VOID? procedure. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgpglN6IAwmO1.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
On Wed, Feb 27, 2008 at 02:40:54PM -0600, Ozzi Lee wrote: > > In reality, though, I think portability between databases is more > > hypothetical than real. Projects typically start with one database and > > stick to it, for moving between databases *even if a portability layer > > is in use* turns out to be hard -- all sorts of stuff outside the main > > code base ends up changing (path names, load scripts, whatever). > > I agree that portability isn't that great in practice. I'd like to see a > DBI egg for two reasons: > > 1. Starting out on a project, 90% of the time I'll use SQLite, because > it's the easiest. Often I'll want to switch to MySQL once things get > rolling. A single DBI interface makes this quite a bit easier. > > 2. For quick and dirty scripts that need to access a database, it would > be nice to have to keep in the differences between the different interfaces. I'd like to add a third: 3. Even if individual *projects* choose a particular database implementation, any given *library* or *framework* should be database-agnostic, wherever possible. This gives people who use your library/framework the freedom to choose their database for their projects. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth pgpsavtmLoMYe.pgp Description: PGP signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
I've been working a little in the same vein, but it's still pretty tied to a specific project My needs are pretty light, but I'm finding that the most useful functions seem to be sql:query-list and sql:query-alist I started out thinking in terms of Perl/Python type DBI, but I'm questioning that now. I'd like to see a lightweight layer that means I don't have to remember as many specifics of the specific DB egg -- I agree with John that, most of the time, plugging in multiple DBs isn't that relevant. I have one project that does it, but it uses such basic SQL-92 that I'm getting away with supporting multiple DBs. In terms of staying lightweight, I'd like to look at the suggested functions: dbi:connect => I'm currently doing this as individual (driver:get- connection)'s that produce a function that takes a message to support the rest of the dbi. This seems like a potential win dbi:query => like I mentioned above, I'm using query-list and query- alist. I also see value for query-vector, but haven't done much with it. The question is, would we be better having individual functions or a single dbi:query that takes a (defaulted) argument that specifies the output? dbi:num-rows => I've found that I almost always end up using (length) instead. Probably not optimal, but I've not had a major problem here. dbi:fetch-row => I've not used this either, but I'm usually pushing my queried list into a for-each or a map. the question is, what is our specific use case? dbi:query-fold, dbi:query-map, query-for-each. I thought about implementing these, but I haven't been able to think of the use case that makes them necessary in the presence Scheme's fold, map, and for-each, other than as shorthand (which could be define'd in place in a heartbeat for anyone who wants it) dbi:insert-id Should this come from a function, or should it be returned as a response to dbi:query? I wouldn't mind seeing the query handler be smart enough that if my query involves INSERT and i've inserted a row that becomes ID 42, that the response would be something like '((rows-affected 1) (insert-id 42)) Certainly, we'd want to look at what we'd want to normalize these labels to, but that's not a huge issue. The related question is whether singleton response values (like rows- affected with nothing else) should return as a singleton (a)list or as a numeric value --> My vote would be to return the singleton (a)list to simplify the conditional checking the caller needs to use. This leaves (dbi:connect driver-proc [[connection params]]) In my case, I'm using SRFI-89 style define* for named params and defaults. What do other people think of this approach? (dbi:query conn str [[output type option?]]) With alist, the output type option probably isn't that important depending on how NULL is handled. It might also be nice to make query smart enough to give sensible responses for non SELECT queries, so we'd need to decide what the alist-names for these should look like Is this over-simplified? Row representation. I think my preference would be using alists as the the representation Thinking about it, Scheme already gives us everything we need to get value lists, vectors, and hash-tables if we start from alists, so it seems like the better choice. I've tended to let null be '(), but that partly comes from liking the look of (null? (alist-ref 'field result)) I'm not entirely comfortable with leaving the value entirely absent simply because the mapping I mention to value lists and vectors becomes more problematic. That said, my usage of value lists and vectors is limited enough that I'm not that tied to it either. --Jeremy On Feb 27, 2008, at 2:11 PM, John Cowan wrote: Ozzi Lee scripsit: Let me know what you think. If someone's already got something going I'd like to pitch in as well. I suggest that a row be an a-list, and that null columns be represented by being non-existent in the a-list. If you end up preferring a plain list or a vector, then use (void) instead -- I am trying to get this standardized as the Chicken representation of SQL's NULL. In reality, though, I think portability between databases is more hypothetical than real. Projects typically start with one database and stick to it, for moving between databases *even if a portability layer is in use* turns out to be hard -- all sorts of stuff outside the main code base ends up changing (path names, load scripts, whatever). -- You let them out again, Old Man Willow! John Cowan What you be a-thinking of? You should not be waking! [EMAIL PROTECTED] Eat earth! Dig deep! Drink water! Go to sleep! Bombadil is talking.http://ccil.org/~cowan ___ Chicken-users mailing list Chicken-users@nong
Re: [Chicken-users] DBI
I suggest that a row be an a-list, and that null columns be represented by being non-existent in the a-list. If you end up preferring a plain list or a vector, then use (void) instead -- I am trying to get this standardized as the Chicken representation of SQL's NULL. I like a-lists as rows for well. I'm not sure about null columns not existing, I think I like it but I guess I'd have to think about/play with it. Otherwise I agree (void) is probably a good idea. In reality, though, I think portability between databases is more hypothetical than real. Projects typically start with one database and stick to it, for moving between databases *even if a portability layer is in use* turns out to be hard -- all sorts of stuff outside the main code base ends up changing (path names, load scripts, whatever). I agree that portability isn't that great in practice. I'd like to see a DBI egg for two reasons: 1. Starting out on a project, 90% of the time I'll use SQLite, because it's the easiest. Often I'll want to switch to MySQL once things get rolling. A single DBI interface makes this quite a bit easier. 2. For quick and dirty scripts that need to access a database, it would be nice to have to keep in the differences between the different interfaces. I would like for a DBI egg itself to be as agnostic as possible. SQL implementation issues (DBI won't mess with SQL at all) and outside scripts aside, do you know of any incompatibilities that would affect this? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] DBI
Ozzi Lee scripsit: > Let me know what you think. If someone's already got something going I'd > like to pitch in as well. I suggest that a row be an a-list, and that null columns be represented by being non-existent in the a-list. If you end up preferring a plain list or a vector, then use (void) instead -- I am trying to get this standardized as the Chicken representation of SQL's NULL. In reality, though, I think portability between databases is more hypothetical than real. Projects typically start with one database and stick to it, for moving between databases *even if a portability layer is in use* turns out to be hard -- all sorts of stuff outside the main code base ends up changing (path names, load scripts, whatever). -- You let them out again, Old Man Willow! John Cowan What you be a-thinking of? You should not be waking! [EMAIL PROTECTED] Eat earth! Dig deep! Drink water! Go to sleep! Bombadil is talking.http://ccil.org/~cowan ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users