You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(7) |
Aug
(10) |
Sep
|
Oct
(5) |
Nov
|
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(28) |
Feb
(3) |
Mar
(3) |
Apr
|
May
(1) |
Jun
|
Jul
(8) |
Aug
(4) |
Sep
|
Oct
|
Nov
(1) |
Dec
(2) |
2005 |
Jan
(1) |
Feb
(1) |
Mar
(1) |
Apr
|
May
(13) |
Jun
(2) |
Jul
(23) |
Aug
(10) |
Sep
(31) |
Oct
(1) |
Nov
(6) |
Dec
(11) |
2006 |
Jan
(6) |
Feb
(5) |
Mar
(19) |
Apr
(29) |
May
(63) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(9) |
Nov
(3) |
Dec
|
2007 |
Jan
|
Feb
(16) |
Mar
(1) |
Apr
(3) |
May
(1) |
Jun
|
Jul
(6) |
Aug
(18) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
(4) |
Feb
(8) |
Mar
|
Apr
(3) |
May
|
Jun
(9) |
Jul
|
Aug
(7) |
Sep
(2) |
Oct
(11) |
Nov
(30) |
Dec
(2) |
2009 |
Jan
(1) |
Feb
|
Mar
(25) |
Apr
|
May
(9) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
(24) |
Nov
(9) |
Dec
(2) |
2010 |
Jan
(7) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(4) |
Jul
|
Aug
|
Sep
(22) |
Oct
|
Nov
|
Dec
(1) |
2011 |
Jan
(10) |
Feb
(17) |
Mar
(4) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(7) |
Aug
(2) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
(13) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(17) |
Dec
|
2014 |
Jan
(16) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(1) |
Aug
|
Sep
|
Oct
(3) |
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2022 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Markus H. <mar...@mh...> - 2022-02-11 23:37:48
|
Hi, here's a ping to everyone who is still and maybe accidentally subscribed to this list. A bout of corona, quite harmless thanks to three helpings of Comirnaty, created some free time to fiddle with my software projects again, after being forced to neglect them for years. Long story short, I'd like to revert an ill-advised patch from 2017 and add an option to the MySQL driver which allows users to set the SQL mode per session, without having to reconfigure an entire server for specific purposes like some legacy SQL code. Problem is, my knowledge about release versioning and, even more so, library versioning, is rusty, to say the least. Neither of the changes will affect backward compatibility. The change to libdbi fixes a stupid patch which caused an extra error message without affecting the function of the library itself. The change to the driver honors another option but the driver works the same if the option is not set. So how am I supposed to deal with the versioning here? Helpful hints are greatly welcome. Also, feel free to suggest additional changes that the project might need. regards, Markus -- Markus Hoenicka http://www.mhoenicka.de AQ score 38 |
From: Pabitra D. <pab...@ya...> - 2018-12-29 02:06:13
|
Hello, Good day.I have following queries. -As libdbi provides standard C abstraction, Can I use it in Windows and Linux platforms?-From where can I get DbiXX detail documentation and source code of the same? Please revert. Regards, Pabitra |
From: Jan E. <je...@in...> - 2014-10-02 20:29:31
|
On Thursday 2014-10-02 21:35, Holger Hans Peter Freyther wrote: >On Thu, Oct 02, 2014 at 08:43:58PM +0200, Jan Engelhardt wrote: > >> You posted the SQL CREATE statements; do you also have a testcase >> available? > >if you still have a copy of the OpenBSC tree. Just execute make >check and our db integration tests will segfault. Is that enough >for you? It takes a bunch of libraries to build that. Some of them I had already added to openSUSE, but not all/not in required versions. Whilst pursuing an update, there have been new problems. I will be sending some patches to osmocom, be sure to take them. |
From: Jan E. <je...@in...> - 2014-10-02 18:44:06
|
On Thursday 2014-10-02 20:12, Holger Freyther wrote: > >> Ubuntu has updated their version from libdbi 0.8.x to 0.9.0 and >> in Debian unstable. One issue is that we have used _get_uint where >> we now need to use _get_ulonglong to not generate a dbi error. The >> other issues seem to be genuine memory issues with libdbi that lead >> to a segfault in our testsuite. > >debian testing has been updated too. Is libdbi still maintained? >Does anyone intend to resolve the memory violations? You posted the SQL CREATE statements; do you also have a testcase available? |
From: Holger F. <ho...@fr...> - 2014-10-02 18:13:16
|
Holger Freyther <holger <at> freyther.de> writes: > > Good Morning, Good Evening, > Ubuntu has updated their version from libdbi 0.8.x to 0.9.0 and > in Debian unstable. One issue is that we have used _get_uint where > we now need to use _get_ulonglong to not generate a dbi error. The > other issues seem to be genuine memory issues with libdbi that lead > to a segfault in our testsuite. debian testing has been updated too. Is libdbi still maintained? Does anyone intend to resolve the memory violations? |
From: Holger F. <ho...@fr...> - 2014-07-15 06:57:28
|
Good Morning, Ubuntu has updated their version from libdbi 0.8.x to 0.9.0 and in Debian unstable. One issue is that we have used _get_uint where we now need to use _get_ulonglong to not generate a dbi error. The other issues seem to be genuine memory issues with libdbi that lead to a segfault in our testsuite. invalid read in getTables [SCHEMA_EQUIPMENT] = "CREATE TABLE IF NOT EXISTS Equipment (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " "name TEXT, " "classmark1 NUMERIC, " "classmark2 BLOB, " "classmark3 BLOB, " "imei NUMERIC UNIQUE NOT NULL" ")", [SCHEMA_EQUIPMENT_WATCH] = "CREATE TABLE IF NOT EXISTS EquipmentWatch (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " "subscriber_id NUMERIC NOT NULL, " "equipment_id NUMERIC NOT NULL, " "UNIQUE (subscriber_id, equipment_id) " ")", curr_table before getTables = 'SELECT Equipment.* FROM Equipment JOIN EquipmentWatch ON EquipmentWatch.equipment_id=Equipment.id WHERE EquipmentWatch.subscriber_id = 1 ORDER BY EquipmentWatch.updated DESC' ==17178== Invalid read of size 1 ==17178== at 0x40FA609: getTables (dbd_sqlite3.c:1462) ==17178== by 0x40FA863: find_result_field_types.isra.0 (dbd_sqlite3.c:868) ==17178== by 0x40FB776: dbd_query (dbd_sqlite3.c:638) ==17178== by 0x412B098: dbi_conn_queryf (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==17178== by 0x804D7D9: get_equipment_by_subscr (db.c:549) ==17178== by 0x804E3C9: db_get_subscriber (db.c:896) ==17178== by 0x804F23A: db_create_subscriber (db.c:506) ==17178== by 0x804B770: main (db_test.c:178) ==17178== Address 0x64692e74 is not stack'd, malloc'd or (recently) free'd ==17178== Issuing the query shown in quotes triggers this out of bounds read. The workaround I have is to make equ-join using a where clause. ==8810== Invalid read of size 1 ==8810== at 0x412FA54: _dbd_decode_binary (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==8810== by 0x40F9C98: dbd_fetch_row (dbd_sqlite3.c:1741) ==8810== by 0x412B7EE: dbi_result_seek_row (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==8810== by 0x412BB59: dbi_result_next_row (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==8810== by 0x804D6DB: get_equipment_by_subscr (db.c:558) ==8810== by 0x804E2B9: db_get_subscriber (db.c:896) ==8810== by 0x804FB1B: db_prepare (db.c:236) ==8810== by 0x804C018: main (db_test.c:168) ==8810== Address 0x44719e1 is 0 bytes after a block of size 1 alloc'd ==8810== at 0x4028B4C: malloc (in /usr/lib/valgrind/vgpreload_memcheck- x86-linux.so) ==8810== by 0x41C1907: strdup (strdup.c:42) ==8810== by 0x40F9C7B: dbd_fetch_row (dbd_sqlite3.c:1740) ==8810== by 0x412B7EE: dbi_result_seek_row (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==8810== by 0x412BB59: dbi_result_next_row (in /usr/lib/i386-linux- gnu/libdbi.so.1.1.0) ==8810== by 0x804D6DB: get_equipment_by_subscr (db.c:558) ==8810== by 0x804E2B9: db_get_subscriber (db.c:896) ==8810== by 0x804FB1B: db_prepare (db.c:236) ==8810== by 0x804C018: main (db_test.c:168) ==8810== The tables after running the test includes: sqlite> select * from Equipment; 1|2014-03-08 15:35:08|2014-03-08 15:35:28||51|||6666666666666666 3|2014-07-04 06:23:28|2014-07-04 06:23:28|||||1234567890 5|2014-07-04 06:23:28|2014-07-04 06:23:28|||||6543560920 The length of data->d_string at the time valgrind generates the warning is 0. But not everytime it is 0 a warning will be generated. Is this something that can be easily fixed? holger |
From: Jan E. <je...@in...> - 2014-06-27 13:34:58
|
It is currently impossible to distinguish an SQL column of decimal(m,n) type from an SQL column of string type within libdbi, because both get mapped to DBI_TYPE_STRING. I feel inclined to break this up such that SQL DECIMAL gets mapped to DBI_TYPE_DECIMAL, and SQL FLOAT/DOUBLE get mapped to a new DBI_TYPE_FLOAT. Or other names. In any case, it will require changes to applications in any case, so that's the impact. |
From: Jan E. <je...@in...> - 2014-01-24 14:55:56
|
On Friday 2014-01-24 13:55, Markus Hoenicka wrote: >At 2014-01-24 13:23 Jan Engelhardt was heard to say: >> >> Now, release? > >Well, why not. We just need to take care of your changes of the driver >interface. Although this does not affect the libtool versioning (if I >understand your changes correctly), we have claimed in the past that >0.9.x drivers work with any 0.9.y library. If I recall our version >number black magic correctly, this would require us to start 1.0 (or >0.10 ?) series of both library and drivers. So just make it a 1.0. (The libtool numbering is correct already.) >BTW which test platforms do we have at our disposal? Platforms I use in the current context: openSUSE, mingw-w64 Available build platforms: openSUSE x86/x64, ppc/ppc64 Fedora and other Redhats x86/x64 Cygwin x86/x64 mingw-w64 x86/x64 mingw-org x86 If you have a dsc that is accepted by OpenBuildService, can also add the Debian targets. |
From: Markus H. <mar...@mh...> - 2014-01-24 12:55:25
|
At 2014-01-24 13:23 Jan Engelhardt was heard to say: > > Now, release? > Well, why not. We just need to take care of your changes of the driver interface. Although this does not affect the libtool versioning (if I understand your changes correctly), we have claimed in the past that 0.9.x drivers work with any 0.9.y library. If I recall our version number black magic correctly, this would require us to start 1.0 (or 0.10 ?) series of both library and drivers. BTW which test platforms do we have at our disposal? I can contribute FreeBSD 9.2 and Debian testing. I've seen a bunch of 0.9.0 test failures on the Debian build farm lately on some non-x86/x86-64 platforms. Maybe we should try to fix those problems before releasing a new version. I'll compile a list of test failures asap so we can discuss what can be fixed in a reasonable timeframe. regards, Markus -- Markus Hoenicka http://www.mhoenicka.de AQ score 38 |
From: Jan E. <je...@in...> - 2014-01-24 12:23:34
|
On Friday 2014-01-24 09:17, Markus Hoenicka wrote: >At 2014-01-24 02:50 Jan Engelhardt was heard to say: >> Speaking of which, autogen.sh has too much cruft. It should be removed >> and/or replaced to only call `autoreconf -fi`. And perhaps `rm -Rf >> autom4te.cache` because that seems to go unused. > >Thanks for that, I was not aware of autoreconf. It certainly make sense >to use that as it seems to do the right thing automagically. However, >I'd prefer to keep autogen.sh around, even if it contains just a single >call to autoreconf, for the sake of backwards compatibility. No objections, I use an autogen.sh myself sometimes. I sent up a new autogen.sh into the repo. Now, release? |
From: <jp...@re...> - 2014-01-24 10:15:46
|
> It certainly make sense > to use that as it seems to do the right thing automagically. However, > I'd prefer to keep autogen.sh around, even if it contains just a single > call to autoreconf, for the sake of backwards compatibility. You must be right. I agree with this decision. Thanks -- Jan Pacner |
From: Markus H. <mar...@mh...> - 2014-01-24 08:18:06
|
At 2014-01-24 02:50 Jan Engelhardt was heard to say: > Speaking of which, autogen.sh has too much cruft. It should be removed > and/or replaced to only call `autoreconf -fi`. And perhaps `rm -Rf > autom4te.cache` because that seems to go unused. Thanks for that, I was not aware of autoreconf. It certainly make sense to use that as it seems to do the right thing automagically. However, I'd prefer to keep autogen.sh around, even if it contains just a single call to autoreconf, for the sake of backwards compatibility. regards, Markus -- Markus Hoenicka http://www.mhoenicka.de AQ score 38 |
From: Jan E. <je...@in...> - 2014-01-24 01:50:44
|
On Friday 2014-01-24 00:07, mar...@mh... wrote: >In any case, what do you think about adding "--force-missing" to the >automake call in ./autogen.sh to facilitate easier updating to newer >automake releases? gmake is usually capable of refreshing things "as needed", so when autoreconf ought to be run, passing -f all the time seems free. Speaking of which, autogen.sh has too much cruft. It should be removed and/or replaced to only call `autoreconf -fi`. And perhaps `rm -Rf autom4te.cache` because that seems to go unused. |
From: <mar...@mh...> - 2014-01-23 23:05:40
|
jp...@re... writes: > Up until now, I've used version automake-1.12.5 with timestamp > 2012-09-25. But it's possible (and I'd rather prefer it) to use a newer > one (IMHO a half-year old one should be enough stable). > Hi, I just checked my local copies. The last release was built from the CVS sources which still have the automake 1.11 files. My current git local copy uses automake 1.14, so if I should package a new release anytime soon it would have automake files newer than what you asked for. In any case, what do you think about adding "--force-missing" to the automake call in ./autogen.sh to facilitate easier updating to newer automake releases? regards, Markus -- Markus Hoenicka http://www.mhoenicka.de AQ score 38 |
From: <jp...@re...> - 2014-01-23 14:36:56
|
Up until now, I've used version automake-1.12.5 with timestamp 2012-09-25. But it's possible (and I'd rather prefer it) to use a newer one (IMHO a half-year old one should be enough stable). -- Jan Pacner On 01/21/2014 07:33 PM, Jan Engelhardt wrote: > On Tuesday 2014-01-21 10:27, jp...@re... wrote: > >> Hi, >> >> libdbi ships with archaic version of automake which doesn't support e.g. >> aarch64 which is currently officially supported in many (not-only Linux) >> distributions (Fedora, Gentoo, etc.). >> >> Could you please update the automake scripts (config.guess, config.sub, >> depcomp etc.)? > > Do you happen to know the minimum version needed to bring the features > you seek? > |
From: Jan E. <je...@in...> - 2014-01-21 18:33:31
|
On Tuesday 2014-01-21 10:27, jp...@re... wrote: >Hi, > >libdbi ships with archaic version of automake which doesn't support e.g. >aarch64 which is currently officially supported in many (not-only Linux) >distributions (Fedora, Gentoo, etc.). > >Could you please update the automake scripts (config.guess, config.sub, >depcomp etc.)? Do you happen to know the minimum version needed to bring the features you seek? |
From: <jp...@re...> - 2014-01-21 09:27:19
|
Hi, libdbi ships with archaic version of automake which doesn't support e.g. aarch64 which is currently officially supported in many (not-only Linux) distributions (Fedora, Gentoo, etc.). Could you please update the automake scripts (config.guess, config.sub, depcomp etc.)? Kind regards -- Jan Pacner |
From: Mike R. <mry...@gm...> - 2014-01-06 15:37:40
|
Ah! Well, I stuck my foot right in my mouth, didn't I? I did not read the patch closely enough, please ignore the noise. On Mon, Jan 6, 2014 at 10:08 AM, Jan Engelhardt <je...@in...> wrote: > On Monday 2014-01-06 15:57, Mike Rylander wrote: > >>While I can certainly understand the desire to improve handling of >>dates and times in libdbi (I helped a bit with the timezone code a few >>years back), I think breaking the API for all current applications is >>a bit heavy handed. > > Thanks for your response. > > The API for DBI programs remains the same. > > It is only the API for DBI drivers which changes (and that I have > addressed in lockstep), as a result of everything relying on dbi_date_t. -- Mike Rylander | Director of Research and Development | Equinox Software, Inc. / Your Library's Guide to Open Source | phone: 1-877-OPEN-ILS (673-6457) | email: mi...@es... | web: http://www.esilibrary.com |
From: Jan E. <je...@in...> - 2014-01-06 15:08:54
|
On Monday 2014-01-06 15:57, Mike Rylander wrote: >While I can certainly understand the desire to improve handling of >dates and times in libdbi (I helped a bit with the timezone code a few >years back), I think breaking the API for all current applications is >a bit heavy handed. Thanks for your response. The API for DBI programs remains the same. It is only the API for DBI drivers which changes (and that I have addressed in lockstep), as a result of everything relying on dbi_date_t. |
From: Mike R. <mry...@gm...> - 2014-01-06 14:57:37
|
While I can certainly understand the desire to improve handling of dates and times in libdbi (I helped a bit with the timezone code a few years back), I think breaking the API for all current applications is a bit heavy handed. How about a parallel API for grabbing the struct instead? That way you get what you need, and application authors have a migration path that allows them to benefit from bug fixes in other areas while they change their apps to use the struct instead, if their code would benefit from that. TIA, On Sun, Jan 5, 2014 at 8:43 AM, Jan Engelhardt <je...@in...> wrote: > > I have a 2-patch here which I would like to share before merging. > > SQL databases such as Mysql support dates from 1000-01-01 to > 9999-01-01. However, even "reasonable" dates like 1968-02-14 cannot > be reliably retrieved through libdbi. The root problem is that time_t > only starts at 1970, and MSVCRT outright refuses to transform a > struct tm into an epochtime if it is before 1970 - and that is even > within the specification. > > How I solve this: make the struct tm available. It is a bit of a cut > into the dbi API, but hopefully done right. > > ------------------------------------------------------------------------------ > Rapidly troubleshoot problems before they affect your business. Most IT > organizations don't have a clear picture of how application performance > affects their revenue. With AppDynamics, you get 100% visibility into your > Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! > http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk > _______________________________________________ > libdbi-devel mailing list > lib...@li... > https://lists.sourceforge.net/lists/listinfo/libdbi-devel -- Mike Rylander | Director of Research and Development | Equinox Software, Inc. / Your Library's Guide to Open Source | phone: 1-877-OPEN-ILS (673-6457) | email: mi...@es... | web: http://www.esilibrary.com |
From: Jan E. <je...@in...> - 2014-01-05 14:01:48
|
libdbi replaced dbi_data_t's datetime field by datetimex and switched from _dbd_parse_datetime for _dbd_parse_datetimex to support dates outside the range of time_t. Adjust the drivers to follow suit. --- drivers/db2/dbd_db2.c | 2 +- drivers/firebird/utility.c | 2 +- drivers/freetds/dbd_freetds.c | 3 +-- drivers/ingres/dbd_ingres.c | 32 ++++++++++++++++---------------- drivers/msql/dbd_msql.c | 2 +- drivers/mysql/dbd_mysql.c | 2 +- drivers/oracle/dbd_oracle.c | 30 ++++++++++++------------------ drivers/pgsql/dbd_pgsql.c | 2 +- drivers/sqlite/dbd_sqlite.c | 2 +- drivers/sqlite3/dbd_sqlite3.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/drivers/db2/dbd_db2.c b/drivers/db2/dbd_db2.c index 30a8186..1e97067 100755 --- a/drivers/db2/dbd_db2.c +++ b/drivers/db2/dbd_db2.c @@ -992,7 +992,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi default: break; } - data->d_datetime = _dbd_parse_datetime(ptr_date, attribs); + _dbd_parse_datetimex(ptr_date, attribs, &data->d_datetimex); free((char *) ptr_date); break; default: diff --git a/drivers/firebird/utility.c b/drivers/firebird/utility.c index d797141..de672dd 100644 --- a/drivers/firebird/utility.c +++ b/drivers/firebird/utility.c @@ -333,7 +333,7 @@ int _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowid times.tm_mon+1, times.tm_mday); } - data->d_datetime = _dbd_parse_datetime(date_s, sizeattrib); + _dbd_parse_datetimex(date_s, sizeattrib, &data->d_datetimex); break; case DBI_TYPE_BINARY: diff --git a/drivers/freetds/dbd_freetds.c b/drivers/freetds/dbd_freetds.c index c272073..98c4864 100644 --- a/drivers/freetds/dbd_freetds.c +++ b/drivers/freetds/dbd_freetds.c @@ -1031,8 +1031,7 @@ dbi_row_t *_dbd_freetds_buffers_binding(dbi_conn_t * conn, dbi_result_t * result CS_SUCCEED) { // fprintf(stderr, "cs_convert() succeeded when failure was expected\n"); } - ((dbi_data_t *) addr)->d_datetime = - _dbd_parse_datetime(datastring, DBI_DATETIME_TIME | DBI_DATETIME_DATE); + _dbd_parse_datetimex(datastring, DBI_DATETIME_TIME | DBI_DATETIME_DATE, &((dbi_data_t *)addr)->d_datetimex); } break; /* decode binary string */ diff --git a/drivers/ingres/dbd_ingres.c b/drivers/ingres/dbd_ingres.c index d0b2abf..1a5e091 100644 --- a/drivers/ingres/dbd_ingres.c +++ b/drivers/ingres/dbd_ingres.c @@ -485,21 +485,22 @@ size_t dbd_quote_binary(dbi_conn_t *conn, const unsigned char* orig, /* ---------- result handling ---------- */ -static time_t ingres_date(char *raw){ - struct tm unixtime; +static int ingres_date(const char *raw, dbi_datetimex *dtx) +{ + struct tm *unixtime = &dtx->tm; char *p = raw, *q, sep; PRINT_DEBUG(NULL,"parsing date: '%s'\n",raw); - unixtime.tm_sec = unixtime.tm_min = unixtime.tm_hour = 0; - unixtime.tm_isdst = -1; + unixtime->tm_sec = unixtime->tm_min = unixtime->tm_hour = 0; + unixtime->tm_isdst = -1; // parse Ingres default (US) date format: dd-mmm-yyyy [hh:mm:ss] //for(p = raw; *p && !isdigit(*p); ++p) // ; if(isdigit(*p)){ // process day - unixtime.tm_mday = atoi(p); + unixtime->tm_mday = atoi(p); while(*p && isdigit(*p)) ++p; if(!*p){ _verbose_handler(NULL,"date ended after day??",raw); return 0; } @@ -507,7 +508,7 @@ static time_t ingres_date(char *raw){ // process month if(isdigit(*p)){ - unixtime.tm_mon = atoi(p)-1; /* months are 0 through 11 */ + unixtime->tm_mon = atoi(p)-1; /* months are 0 through 11 */ while(*p && *p != sep) ++p; }else{ @@ -516,17 +517,17 @@ static time_t ingres_date(char *raw){ ++p; if(*p){ *p = 0; - unixtime.tm_mon = in_word_set(q,3)->index; // should work for long month names too + unixtime->tm_mon = in_word_set(q,3)->index; // should work for long month names too ++p; } } if(!*p){ _verbose_handler(NULL,"date ended after month??",raw); return 0; } // process year - unixtime.tm_year = atoi(p)-1900; + unixtime->tm_year = atoi(p)-1900; PRINT_DEBUG(NULL,"ingres_date: parsed date day=%d mon=%d yr=%d\n", - unixtime.tm_mday, unixtime.tm_mon, unixtime.tm_year); + unixtime->tm_mday, unixtime->tm_mon, unixtime->tm_year); while(isdigit(*p)) ++p; @@ -537,32 +538,31 @@ static time_t ingres_date(char *raw){ // Ingres does not generate a time by itself, it's always preceded by a date. if(isdigit(*p)){ // time is present // process hours - unixtime.tm_hour = atoi(p); + unixtime->tm_hour = atoi(p); while(isdigit(*p)) ++p; if(!*p){ _verbose_handler(NULL,"time ended after hour??",raw); return 0; } ++p; // skip separator // process minutes - unixtime.tm_min = atoi(p); + unixtime->tm_min = atoi(p); while(isdigit(*p)) ++p; if(!*p){ _verbose_handler(NULL,"time ended after minute??",raw); return 0; } ++p; // skip separator // process seconds - unixtime.tm_sec = atoi(p); + unixtime->tm_sec = atoi(p); PRINT_DEBUG(NULL,"ingres_date: parsed time %02d:%02d:%02d\n", - unixtime.tm_hour, unixtime.tm_min, unixtime.tm_sec); + unixtime->tm_hour, unixtime->tm_min, unixtime->tm_sec); /* check for a timezone suffix */ //while(isdigit(*p) || *p == ' ') // ++p; }else if(*p) _verbose_handler(NULL,"bad time: '%s'",p); - - return timegm(&unixtime); + dtx->utc_offset = 0; }else _verbose_handler(NULL,"bad date: '%s'",raw); return 0; @@ -660,7 +660,7 @@ static int ingres_field(dbi_result_t *result, dbi_row_t *row, dbi_data_t *data, len = convParm.cv_dstValue.dv_length; if(pdesc->ds_dataType == IIAPI_DTE_TYPE){ val[len] = 0; - data->d_datetime = ingres_date(val); + ingres_date(val, &data->d_datetimex); PRINT_DEBUG(result->conn," [%d] date string %d bytes\n", idx,len); break; }else if(pdesc->ds_dataType == IIAPI_DEC_TYPE || pdesc->ds_dataType == IIAPI_MNY_TYPE){ diff --git a/drivers/msql/dbd_msql.c b/drivers/msql/dbd_msql.c index f3430b1..55c38be 100644 --- a/drivers/msql/dbd_msql.c +++ b/drivers/msql/dbd_msql.c @@ -511,7 +511,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi case DBI_TYPE_DATETIME: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE\ , DBI_DATETIME_TIME); - data->d_datetime = _dbd_parse_datetime(raw, sizeattrib); + _dbd_parse_datetimex(raw, sizeattrib, &data->d_datetimex); break; default: data->d_string = strdup(raw); diff --git a/drivers/mysql/dbd_mysql.c b/drivers/mysql/dbd_mysql.c index bca34c3..c11e6a8 100644 --- a/drivers/mysql/dbd_mysql.c +++ b/drivers/mysql/dbd_mysql.c @@ -902,7 +902,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi break; case DBI_TYPE_DATETIME: sizeattrib = result->field_attribs[curfield] & (DBI_DATETIME_DATE|DBI_DATETIME_TIME); - data->d_datetime = _dbd_parse_datetime(raw, sizeattrib); + _dbd_parse_datetimex(raw, sizeattrib, &data->d_datetimex); break; } diff --git a/drivers/oracle/dbd_oracle.c b/drivers/oracle/dbd_oracle.c index ab04f99..9ef29e8 100755 --- a/drivers/oracle/dbd_oracle.c +++ b/drivers/oracle/dbd_oracle.c @@ -68,7 +68,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi unsigned long long _oracle_query_to_longlong(dbi_conn_t *conn, const char *sql_cmd); void _checkerr(OCIError * errhp, sword status); static size_t oracle_escape_string(char *to, const char *from, size_t length); -time_t _oradate_to_time_t (char *obuff); +int _oradate_to_dtx(const char *obuff, dbi_datetimex dtx); void dbd_register_driver(const dbi_info_t **_driver_info, const char ***_custom_functions, @@ -777,7 +777,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi memcpy(data->d_string, cols[curfield],row->field_sizes[curfield]); break; case DBI_TYPE_DATETIME: - data->d_datetime = _oradate_to_time_t (cols[curfield]); + _oradate_to_tm(cols[curfield], &data->d_datetimex); break; } if (cols[curfield]) free(cols[curfield]); @@ -923,13 +923,10 @@ static size_t oracle_escape_string(char *to, const char *from, size_t length) return (size_t) (to-to_start); } - - -time_t _oradate_to_time_t (char *obuff) +int _oradate_to_tm(const char *obuff, dbi_datetimex *dtx) { - struct tm tmt; + struct tm *tmt = &dtx->tm; /* char stime[101], *cp = NULL; */ - time_t loct = 0L; /* memset(stime, 0, sizeof(stime)); */ @@ -943,15 +940,12 @@ time_t _oradate_to_time_t (char *obuff) /* cp = strptime(stime, "%Y%m%d%H%M%S", &tmt); */ - memset(&tmt, 0, sizeof(tmt)); - tmt.tm_sec = obuff[6]-1; - tmt.tm_min = obuff[5]-1; - tmt.tm_hour = obuff[4]-1; - tmt.tm_mday = obuff[3]; - tmt.tm_mon = obuff[2]; - tmt.tm_year = (obuff[0]-100)*100 + (obuff[1]-100); - - loct = mktime(&tmt); - - return(loct); + memset(tmt, 0, sizeof(*tmt)); + tmt->tm_sec = obuff[6]-1; + tmt->tm_min = obuff[5]-1; + tmt->tm_hour = obuff[4]-1; + tmt->tm_mday = obuff[3]; + tmt->tm_mon = obuff[2]; + tmt->tm_year = (obuff[0]-100)*100 + (obuff[1]-100); + return 0; } diff --git a/drivers/pgsql/dbd_pgsql.c b/drivers/pgsql/dbd_pgsql.c index ae31d6c..b5820d6 100644 --- a/drivers/pgsql/dbd_pgsql.c +++ b/drivers/pgsql/dbd_pgsql.c @@ -882,7 +882,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowi case DBI_TYPE_DATETIME: sizeattrib = result->field_attribs[curfield] & (DBI_DATETIME_DATE|DBI_DATETIME_TIME); - data->d_datetime = _dbd_parse_datetime(raw, sizeattrib); + _dbd_parse_datetimex(raw, sizeattrib, &data->d_datetimex); break; default: diff --git a/drivers/sqlite/dbd_sqlite.c b/drivers/sqlite/dbd_sqlite.c index 76e27a1..7b67136 100644 --- a/drivers/sqlite/dbd_sqlite.c +++ b/drivers/sqlite/dbd_sqlite.c @@ -1286,7 +1286,7 @@ void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned int rowidx) { break; case DBI_TYPE_DATETIME: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE, DBI_DATETIME_TIME); - data->d_datetime = _dbd_parse_datetime(raw, sizeattrib); + _dbd_parse_datetimex(raw, sizeattrib, &data->d_datetimex); break; default: diff --git a/drivers/sqlite3/dbd_sqlite3.c b/drivers/sqlite3/dbd_sqlite3.c index 0f993cc..2e75e41 100644 --- a/drivers/sqlite3/dbd_sqlite3.c +++ b/drivers/sqlite3/dbd_sqlite3.c @@ -1751,7 +1751,7 @@ static void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long lo break; case DBI_TYPE_DATETIME: sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE, DBI_DATETIME_TIME); - data->d_datetime = _dbd_parse_datetime(raw, sizeattrib); + _dbd_parse_datetimex(raw, sizeattrib, &data->d_datetimex); break; default: -- 1.8.4 |
From: Jan E. <je...@in...> - 2014-01-05 14:01:48
|
Dates before the epoch are not (always) representable in time_t. In particular, the Microsoft C runtime's mktime function rejects any dates before 1970, which is different from glibc which tries to produce negative time_t values. The sensible thing to do is to expose the broken-down date, for example in a struct tm. --- configure.ac | 4 ++-- doc/driver-guide.sgml | 14 +++++++---- include/dbi/dbd.h | 2 +- include/dbi/dbi-dev.h | 2 +- include/dbi/dbi.h.in | 6 +++++ src/dbd_helper.c | 37 +++++++++++++++-------------- src/dbi_result.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++----- src/libdbi.map | 6 +++-- 8 files changed, 102 insertions(+), 35 deletions(-) diff --git a/configure.ac b/configure.ac index 7daf410..3417385 100644 --- a/configure.ac +++ b/configure.ac @@ -6,9 +6,9 @@ AC_CONFIG_SRCDIR([src/dbi_main.c]) AC_USE_SYSTEM_EXTENSIONS dnl set up libtool library versioning -LIB_CURRENT=2 +LIB_CURRENT=3 LIB_REVISION=0 -LIB_AGE=1 +LIB_AGE=0 dnl set up libdbi versioning from the above interface version numbers dnl the math contains an ugly hack to massage the minor version number diff --git a/doc/driver-guide.sgml b/doc/driver-guide.sgml index acdf617..dc4f943 100644 --- a/doc/driver-guide.sgml +++ b/doc/driver-guide.sgml @@ -994,28 +994,32 @@ published by the Free Software Foundation. </VarListEntry> </VariableList> </section> - <section id="internal-dbd-parse-datetime" xreflabel="_dbd_parse_datetime"> - <title>_dbd_parse_datetime</title> + <section id="internal-dbd-parse-datetimex" xreflabel="_dbd_parse_datetimex"> + <title>_dbd_parse_datetimex</title> <funcsynopsis> <funcprototype> - <funcdef>time_t <function moreinfo="none">_dbd_parse_datetime</function></funcdef> + <funcdef>int <function moreinfo="none">_dbd_parse_datetimex</function></funcdef> <paramdef>const char *<parameter moreinfo="none">raw</parameter></paramdef> <paramdef>unsigned int <parameter moreinfo="none">attribs</parameter></paramdef> + <paramdef>dbi_datetimex *<parameter moreinfo="none">dtx</parameter></paramdef> </funcprototype> </funcsynopsis> - <para>Parses the input time, date, or datetime string and converts the value into a time_t value.</para> + <para>Parses the input time, date, or datetime string into a + dbi_datetimex, the latter of which groups a struct tm and a timezone + offset.</para> <VariableList> <VarListEntry> <Term>Arguments</Term> <ListItem> <para><literal moreinfo="none">raw</literal>: A zero-terminated string containing a time, date, or datetime value. Accepted formats are YYYY-MM-DD for date values, HH:MM:SS for time values, and YYYY-MM-DD HH:MM:SS for datetime values. The separators must be present, but can be any character.</para> <Para><Literal>attribs</Literal>: The field attributes of raw.</Para> + <Para><Literal>dtx</Literal>: a dbi_datetimex structure to fill in.</Para> </ListItem> </VarListEntry> <varlistentry> <term><emphasis>Returns</emphasis></term> <listitem> - <para>The numeric equivalent of the input based on UTC. In case of an error, this function returns the start of the Unix epoch.</para> + <para>Always zero.</para> </listitem> </varlistentry> </VariableList> diff --git a/include/dbi/dbd.h b/include/dbi/dbd.h index 33c3efc..cd621df 100644 --- a/include/dbi/dbd.h +++ b/include/dbi/dbd.h @@ -75,7 +75,7 @@ dbi_result_t *_dbd_result_create_from_stringarray(dbi_conn_t *conn, unsigned lon void _dbd_register_driver_cap(dbi_driver_t *driver, const char *capname, int value); void _dbd_register_conn_cap(dbi_conn_t *conn, const char *capname, int value); int _dbd_result_add_to_conn(dbi_result_t *result); -time_t _dbd_parse_datetime(const char *raw, unsigned int attribs); +int _dbd_parse_datetimex(const char *raw, unsigned int attr, dbi_datetimex *dtx); size_t _dbd_escape_chars(char *dest, const char *orig, size_t orig_size, const char *toescape); size_t _dbd_encode_binary(const unsigned char *in, size_t n, unsigned char *out); size_t _dbd_decode_binary(const unsigned char *in, unsigned char *out); diff --git a/include/dbi/dbi-dev.h b/include/dbi/dbi-dev.h index 02b2283..0e21005 100644 --- a/include/dbi/dbi-dev.h +++ b/include/dbi/dbi-dev.h @@ -48,7 +48,7 @@ typedef union dbi_data_u { float d_float; double d_double; char *d_string; - time_t d_datetime; + dbi_datetimex d_datetimex; } dbi_data_t; typedef struct dbi_row_s { diff --git a/include/dbi/dbi.h.in b/include/dbi/dbi.h.in index b5b08e8..92a8e22 100644 --- a/include/dbi/dbi.h.in +++ b/include/dbi/dbi.h.in @@ -100,6 +100,10 @@ typedef struct { dbi_time time; } dbi_datetime; +typedef struct { + struct tm tm; + int utc_offset; +} dbi_datetimex; /* function callback definitions */ typedef void (*dbi_conn_error_handler_func)(dbi_conn, void *); @@ -303,6 +307,7 @@ char *dbi_result_get_string_copy(dbi_result Result, const char *fieldname); unsigned char *dbi_result_get_binary_copy(dbi_result Result, const char *fieldname); time_t dbi_result_get_datetime(dbi_result Result, const char *fieldname); +const dbi_datetimex *dbi_result_get_datetimex(dbi_result Result, const char *fieldname); int dbi_result_bind_char(dbi_result Result, const char *fieldname, char *bindto); int dbi_result_bind_uchar(dbi_result Result, const char *fieldname, unsigned char *bindto); @@ -349,6 +354,7 @@ char *dbi_result_get_string_copy_idx(dbi_result Result, unsigned int fieldidx); unsigned char *dbi_result_get_binary_copy_idx(dbi_result Result, unsigned int fieldidx); time_t dbi_result_get_datetime_idx(dbi_result Result, unsigned int fieldidx); +const dbi_datetimex *dbi_result_get_datetimex_idx(dbi_result Result, unsigned int fieldidx); /* get_as* functions */ long long dbi_result_get_as_longlong(dbi_result Result, const char *fieldname); diff --git a/src/dbd_helper.c b/src/dbd_helper.c index 833dc0f..3a20448 100644 --- a/src/dbd_helper.c +++ b/src/dbd_helper.c @@ -31,6 +31,7 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> +#include <time.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -299,8 +300,10 @@ static _capability_t *_find_or_create_conn_cap(dbi_conn_t *conn, const char *cap return cap; } -time_t _dbd_parse_datetime(const char *raw, unsigned int attribs) { - struct tm unixtime; +int _dbd_parse_datetimex(const char *raw, unsigned int attribs, + dbi_datetimex *dtx) +{ + struct tm *unixtime = &dtx->tm; char *unparsed; char *cur; @@ -311,11 +314,11 @@ time_t _dbd_parse_datetime(const char *raw, unsigned int attribs) { int check_time = 1; - unixtime.tm_sec = unixtime.tm_min = unixtime.tm_hour = 0; - unixtime.tm_mday = 1; /* days are 1 through 31 */ - unixtime.tm_mon = 0; - unixtime.tm_year = 70; /* can't start before Unix epoch */ - unixtime.tm_isdst = -1; + unixtime->tm_sec = unixtime->tm_min = unixtime->tm_hour = 0; + unixtime->tm_mday = 1; /* days are 1 through 31 */ + unixtime->tm_mon = 0; + unixtime->tm_year = 70; /* can't start before Unix epoch */ + unixtime->tm_isdst = -1; if (raw && (unparsed = strdup(raw)) != NULL) { cur = unparsed; @@ -336,9 +339,9 @@ time_t _dbd_parse_datetime(const char *raw, unsigned int attribs) { cur[4] = '\0'; cur[7] = '\0'; cur[10] = '\0'; - unixtime.tm_year = atoi(cur)-1900; - unixtime.tm_mon = atoi(cur+5)-1; /* months are 0 through 11 */ - unixtime.tm_mday = atoi(cur+8); + unixtime->tm_year = atoi(cur)-1900; + unixtime->tm_mon = atoi(cur+5)-1; /* months are 0 through 11 */ + unixtime->tm_mday = atoi(cur+8); if (attribs & DBI_DATETIME_TIME) { cur += 11; if (*cur == ' ') { @@ -350,9 +353,9 @@ time_t _dbd_parse_datetime(const char *raw, unsigned int attribs) { if (check_time && strlen(cur) > 7 && attribs & DBI_DATETIME_TIME) { cur[2] = '\0'; cur[5] = '\0'; - unixtime.tm_hour = atoi(cur); - unixtime.tm_min = atoi(cur+3); - unixtime.tm_sec = atoi(cur+6); + unixtime->tm_hour = atoi(cur); + unixtime->tm_min = atoi(cur+3); + unixtime->tm_sec = atoi(cur+6); /* check for a timezone suffix */ cur += 8; @@ -394,18 +397,16 @@ time_t _dbd_parse_datetime(const char *raw, unsigned int attribs) { _gm_offset += _tz_hours * 60 * 60; _gm_offset += _tz_mins * 60; - if ( _tz_dir ) { + if (!_tz_dir) _gm_offset *= -1; - } } } } free(unparsed); } - - /* output is UTC, not local time */ - return (time_t)(_gm_offset + timegm(&unixtime)); + dtx->utc_offset = _gm_offset; + return 0; } /* Calculate the required buffer size (in bytes) for directory * diff --git a/src/dbi_result.c b/src/dbi_result.c index 35e1b61..751e490 100644 --- a/src/dbi_result.c +++ b/src/dbi_result.c @@ -1334,6 +1334,14 @@ unsigned char *dbi_result_get_binary_copy_idx(dbi_result Result, unsigned int fi return newblob; } +static time_t _dbi_make_datetime(const dbi_datetimex *dtx) +{ + struct tm copy = dtx->tm; + + /* timegm reserves the right to modify it by not taking a const tm */ + return timegm(©) - dtx->utc_offset; +} + time_t dbi_result_get_datetime(dbi_result Result, const char *fieldname) { time_t my_ERROR = 0; unsigned int fieldidx; @@ -1367,7 +1375,51 @@ time_t dbi_result_get_datetime_idx(dbi_result Result, unsigned int fieldidx) { return my_ERROR; } - return (time_t)(RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetime); + return _dbi_make_datetime(&RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetimex); +} + +static const dbi_datetimex _dbi_datetimex_ERROR = { + .tm = { + .tm_sec = -1, .tm_min = -1, .tm_hour = -1, + .tm_mday = -1, .tm_mon = -1, .tm_year = -1, + .tm_wday = -1, .tm_yday = -1, .tm_isdst = -1, + }, +}; + +const dbi_datetimex * +dbi_result_get_datetimex(dbi_result Result, const char *fieldname) +{ + unsigned int fieldidx; + dbi_error_flag errflag = DBI_ERROR_NONE; + + _reset_conn_error(RESULT->conn); + fieldidx = _find_field(RESULT, fieldname, &errflag); + if (errflag != DBI_ERROR_NONE) { + dbi_conn_t *conn = RESULT->conn; + _error_handler(conn, DBI_ERROR_BADNAME); + return &_dbi_datetimex_ERROR; + } + return dbi_result_get_datetimex_idx(Result, fieldidx + 1); +} + +const dbi_datetimex * +dbi_result_get_datetimex_idx(dbi_result Result, unsigned int fieldidx) +{ + --fieldidx; + _reset_conn_error(RESULT->conn); + if (fieldidx >= RESULT->numfields) { + _error_handler(RESULT->conn, DBI_ERROR_BADIDX); + return &_dbi_datetimex_ERROR; + } + if (RESULT->field_types[fieldidx] != DBI_TYPE_DATETIME) { + _verbose_handler(RESULT->conn, + "%s: field `%s` is not datetime type\n", + __func__, + dbi_result_get_field_name(Result, fieldidx + 1)); + _error_handler(RESULT->conn, DBI_ERROR_BADTYPE); + return &_dbi_datetimex_ERROR; + } + return &RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetimex; } /* RESULT: get_as* functions */ @@ -1430,7 +1482,7 @@ long long dbi_result_get_as_longlong_idx(dbi_result Result, unsigned int fieldid case DBI_TYPE_BINARY: return 0; /* do not raise an error */ case DBI_TYPE_DATETIME: - return (long long)(RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetime); + return _dbi_make_datetime(&RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetimex); default: _error_handler(RESULT->conn, DBI_ERROR_BADTYPE); return my_ERROR; @@ -1457,7 +1509,6 @@ char *dbi_result_get_as_string_copy_idx(dbi_result Result, unsigned int fieldidx char *my_ERROR = "ERROR"; char *newstring = NULL; char *oldstring = NULL; - struct tm utctime; fieldidx--; @@ -1544,10 +1595,13 @@ char *dbi_result_get_as_string_copy_idx(dbi_result Result, unsigned int fieldidx break; case DBI_TYPE_BINARY: break; /* return empty string, do not raise an error */ - case DBI_TYPE_DATETIME: - gmtime_r(&(RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetime), &utctime); - snprintf(newstring, 32, "%04d-%02d-%02d %02d:%02d:%02d", utctime.tm_year+1900, utctime.tm_mon+1, utctime.tm_mday, utctime.tm_hour, utctime.tm_min, utctime.tm_sec); + case DBI_TYPE_DATETIME: { + const struct tm *tm = &RESULT->rows[RESULT->currowidx]->field_values[fieldidx].d_datetimex.tm; + snprintf(newstring, 32, "%04d-%02d-%02d %02d:%02d:%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); break; + } default: _error_handler(RESULT->conn, DBI_ERROR_BADTYPE); } diff --git a/src/libdbi.map b/src/libdbi.map index 6d86cdd..96d4118 100644 --- a/src/libdbi.map +++ b/src/libdbi.map @@ -1,4 +1,4 @@ -ABI_2 { +ABI_3 { global: dbi_conn_cap_get; dbi_conn_clear_option; @@ -104,6 +104,8 @@ global: dbi_result_get_currow; dbi_result_get_datetime; dbi_result_get_datetime_idx; + dbi_result_get_datetimex; + dbi_result_get_datetimex_idx; dbi_result_get_double; dbi_result_get_double_idx; dbi_result_get_field_attrib; @@ -163,7 +165,7 @@ global: _dbd_encode_binary; _dbd_escape_chars; _dbd_internal_error_handler; - _dbd_parse_datetime; + _dbd_parse_datetimex; _dbd_register_conn_cap; _dbd_register_driver_cap; _dbd_result_add_field; -- 1.8.4 |
From: Jan E. <je...@in...> - 2014-01-05 14:01:47
|
I have a 2-patch here which I would like to share before merging. SQL databases such as Mysql support dates from 1000-01-01 to 9999-01-01. However, even "reasonable" dates like 1968-02-14 cannot be reliably retrieved through libdbi. The root problem is that time_t only starts at 1970, and MSVCRT outright refuses to transform a struct tm into an epochtime if it is before 1970 - and that is even within the specification. How I solve this: make the struct tm available. It is a bit of a cut into the dbi API, but hopefully done right. |
From: Jan E. <je...@in...> - 2013-11-14 00:29:16
|
On Thursday 2013-11-14 00:32, mar...@mh... wrote: >Jan Engelhardt writes: > > Git repositories are now up, with tags and all the fluff. > > > > [remote "sf"] > > url = git://git.code.sf.net/p/libdbi/libdbi > > pushurl = ssh://git.code.sf.net/p/libdbi/libdbi > > [remote "sf"] > > url = git://git.code.sf.net/p/libdbi-drivers/libdbi-drivers > > pushurl = ssh://git.code.sf.net/p/libdbi-drivers/libdbi-drivers > > >However, I can't find any trace of the web pages. I >used to have those in the cvs repositories as well, just to have them >version-controlled as well. Is there a way to make them available >through git without screwing up the sources proper? Now imported into (ssh|git)://git.code.sf.net/p/libdbi/libdbi-www (ssh|git)://git.code.sf.net/p/libdbi-drivers/libdbi-drivers-www |
From: <mar...@mh...> - 2013-11-13 23:31:59
|
Jan Engelhardt writes: > Git repositories are now up, with tags and all the fluff. > > [remote "sf"] > url = git://git.code.sf.net/p/libdbi/libdbi > pushurl = ssh://git.code.sf.net/p/libdbi/libdbi > [remote "sf"] > url = git://git.code.sf.net/p/libdbi-drivers/libdbi-drivers > pushurl = ssh://git.code.sf.net/p/libdbi-drivers/libdbi-drivers Hi, thanks for that. I managed to clone and build both libdbi and libdbi-drivers. However, I can't find any trace of the web pages. I used to have those in the cvs repositories as well, just to have them version-controlled as well. Is there a way to make them available through git without screwing up the sources proper? regards, Markus -- Markus Hoenicka http://www.mhoenicka.de AQ score 38 |