Closed pheaver closed 12 years ago
You can do half of this already; convert your result to a RawResult
(from Database.PostgreSQL.Simple.Field
) and you can get the raw data and field information. However be aware that keeping a RawResult around will keep the entire C result data structure around; you should probably copy out any information you want to keep and try to eliminate any references to the RawResult promptly. (Though note the typename need not be copied, you can store a reference to the same ByteString without retaining a larger-than-necessary chunk of information)
There isn't any out-of-box code to deal with a dynamic number of columns in the result; but there shouldn't be anything preventing you from adding your own instance for QueryResults
either, without modifying the library. And if you come up with something you like, I could certainly entertain it for inclusion into the library itself.
Yes, but dealing with RawResult
is a little too low level, and doesn't take advantage of the convenient Result and QueryResults interface. I have written an instance of QueryResults [SqlValue] that works for my purposes, but it's a little incomplete; it doesn't handle the cases that will never occur for me.
Yeah, the Field interface could use a bit of polishing. Even so I think I get what you are saying. I'm a little concerned that such an effort will be forever incomplete and/or insufficiently of general interest; for example I'm using some user-defined datatypes provided by third-party plugin modules to PostgreSQL, specifically the period
datatype provided Jeff Davis's temporal postgres extension, and one of my gripes with HDBC was that I had to modify the library itself to support it. (Or, cast them to Strings and convert them myself, which is a minor kludge)
I made sure to make it possible for clients of postgresql-simple to add support for third-party PostgreSQL and Haskell types in clean way, without modifying the library itself. For example PostgreSQL's timestamp type supports ±infinity
values, which Haskell's UTCTime
does not; so if you need to deal with these values, you can define your own Haskell type that does and add a Result instance that will convert timestamps to it.
And, incidentally, I changed the type of convert
from mysql-simple to support composing Result instances along the lines of the newly added instance (Result a, Result b) => Result (Either a b)
. If you are building something roughly similar to SqlValue
, It's probably more efficient to dispatch directly on the typeOid or typename, (depending on whether it's a built-in type with a stable Oid or not), but you might find this kind of composition useful for your purposes.
Excellent points. That's a really nice advantage in postgresql-simple, that it's fairly easy to extend and add whatever types you want for parameters and results.
The database queries in our application are not always static; the number and types of columns in the result of our select statements are often not known at compile time. So, sometimes I need to be able to check what the type of the result is, and in HDBC I would do that by pattern matching on a SqlValue.
So, it is useful for us to have a composite datatype like HDBC's SqlValue, and instance like this for it:
We don't need an instance for Param or QueryParams because I can just use
render
to convert all my arguments to theAction
type.We wouldn't need the silly
toSql
andfromSql
functions from HDBC, just the SqlValue and the QueryResults instance.Does this seem reasonable? Would you accept a patch that provides this?