
On Behalf Of Corwin Joy
I guess you could do this in the bindings. I'm not sure how you would get compile time checks that you are assigning an illegal value to a field if you just expose a collection of boost::variant fields tho'.
Unfortunately, there really isn't any way to guarantee at compile time what the data types in a database will be at run time.
Actually if you re-read my earlier post my point is exactly the reverse. Fixed length strings are easy to support from an implementation point of view, it is arbitrary length strings that are hard.
I guess I'm still thinking of it from an interface point of view. Even if you're dealing in fixed length strings in the implementation, you can still return arbitrary length strings to the user. SQLPutData won't be a problem since we're using read-only record sets.
2. More problematic, if you call SQLGetData and SQLPutData on a
column > then > ODBC says it may not be supported unless that string column comes last.
That's odd. I've never used a native interface that cared about column order.
I'm not saying that you should default construct this inside private class members, but what I am saying is that you will need to allow it to be overriden. I'll give a couple examples: 1. In microsoft access there are two kinds of text fields, text and memo. text can be up to 255 bytes long, memo can be much larger (I think up to 4k). When you bind a text column, you have to specify a SQL column length. If you specify >255 for a text column you will get an error. If you specify 255 for a memo column you will get truncated. When the user binds a std::string you don't know what kind of SQL type they are binding to.
The interface only provides the ability to read from record sets, which is all some native interfaces allow. When returning std::string, it doesn't matter whether the source was memo or not. Speaking of Access; I'm pretty familiar with it too. We had been using it for 5 or 6 years via DAO and just finished converting our entire system to PostgreSQL. I didn't know about memo fields when we first set up our access databases, and the 255 byte limit was a major source of pain for us. Now all our text fields are unbounded (and per PostgreSQL documentation suffer no performance penalty). I think it's just common wisdom in programming that if you put an arbitrary size limitation on something you're asking for trouble, which is part of the reason I'm not too worried about fixed length strings.
Anyway, not having a class to hold the source SQL column type is just wrong IMO since there are all kinds of conversion rules that may be desired and the default may not be the right one and have to be overriden.
I'm still thinking about the interface. The implementation will certainly need no hang on to the SQL column type. It will be the implementation's job to choose the right conversion.
Yes, definitely they should be hidden as private members, I was just pointing out that this association needs to be made.
I think we're saying the same thing then. We definitely can't convert from database type to C++ type without this information. I was thinking that it would live in the implementations: Boost.Database.PostgreSQL, Boost.Database.MySQL, etc... and not in the interface.