[Dbix-class] column default values, SQLite and Oracle
Jason Gottshall
jgottshall at capwiz.com
Thu Jan 22 22:39:36 GMT 2009
Jess Robinson wrote:
> On Wed, 07 Jan 2009 21:06:27 -0000, Jason Gottshall
> <jgottshall at capwiz.com> wrote:
>
>> I'm attempting to set things up so my existing Oracle-based schema can
>> be deployed to SQLite via $schema->deploy so we can do some localized
>> testing. One incompatibility that is hitting us hard is that SQLite
>> doesn't accept dynamic expressions as default values for date-typed
>> columns, while Oracle does, and we have a number of existing tables that
>> take advantage of this feature. So the relevant columns' default values
>> are currently configured in the Result classes with scalar refs
>> containing the expressions. Of course SQLite chokes when deploy()
>> attempts to create the corresponding tables. But I have an idea...
>>
>> a) Patch SQLT::Producer::SQLite so that it ignores scalar ref (i.e. SQL
>> expression) default values on date columns
>
> No, thanks, since those actually have a meaning, eg \'CURRENT_TIMESTAMP'
True, though the producer currently checks plain scalars for valid forms
of those types of things and uses them appropriately. We could probably
regex the scalar refs and only ignore the ones that contain expressions
other than the few (3?) like your example that are actually valid in
SQLite.
>> b) Patch DBIC::Storage::DBI::SQLite so that insert() looks in the column
>> metadata for scalar ref default values for date columns and drops them
>> into the query as literal sql expressions
>
> c) create a component that is only loaded when
> $schema->storage->sqlt_type eq 'SQLite' which overrides insert and
> does.. whatever.
Is that "c" meant to replace my "b"? (my "b" was a second necessary
step, not an alternative to "a".) It does makes sense, tho. I just don't
know the internals well enough yet to know the right place to put that
kind of stuff without digging.
>> One additional issue here is that the accepted syntax for date
>> expressions is different between SQLite and Oracle (and every other
>> rdbms, for that matter), so we might have to go one step further and
>> allow the default_value in the column metadata to be a hashref where the
>> keys are storage types and the values are the corresponding syntax, for
>> example:
>>
>> __PACKAGE__->add_columns(
>> some_date => {
>> data_type => 'DATE',
>> default_value => {
>> Oracle => \q[sysdate + 1],
>> SQLite => \q[date('now', '+1 day')],
>> Pg => \q[now + interval '1 day'],
>> mysql => \q[now() + interval 1 day],
>> },
>> },
>> );
>
> It'd be more sensible to let SQL::Translator do this bit, since that's
> it's purpose. So you write whichever of those as the default value, and
> SQLT translates into something standard on the SQLT::Schema::Field, and
> back into whichever producer you use on deploy().
I'd love to leave all this to SQL::Translator. The question then
becomes: what is that "something standard"? It's the lack of a standard
that's giving me headaches in the first place. And looking at the
differences among various implementations, we may need a whole separate
date expression parser for every flavor in order to get this right. My
flavor-specific hash idea was intentionally avoiding the whole
convoluted parse-and-reformat issue; this way you really only have to
worry about figuring out the syntax for the ones you intend to use...
>> Thoughts, anyone?
> Several ;)
Thanks for thinking about this, Jess!
Jason
--
Jason Gottshall
jgottshall at capwiz.com
More information about the DBIx-Class
mailing list