[patch] limited sql date support

Nirgal <[email protected]> Thu, 25 Aug 2011 20:11:26 +0000
Newsgroups gmane.comp.db.mdb-tools.devel
Message-ID <[email protected]>
The attached patch derived from the one at https://github.com/markrwilliams/mdbtools/commit/6e9b71af1ff194721928181dc9e694b65c999b98
provide limited sql support for date type.
Exemple usage:
select * from table where dt > 12345678.75

Here 12345678.75 is the number of second since epoch.
Not perfect, but still usefull.

------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management 
Up to 160% more powerful than alternatives and 25% more efficient. 
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev

_______________________________________________
mdbtools-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mdbtools-dev
wheredate.diff (text/x-patch, 4.6 KB)
Index: mdbtools-0.6pre1/include/mdbtools.h
===================================================================
--- mdbtools-0.6pre1.orig/include/mdbtools.h
+++ mdbtools-0.6pre1/include/mdbtools.h
@@ -462,6 +462,7 @@
 /* data.c */
 extern int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr, int *len_ptr);
 extern void mdb_data_dump(MdbTableDef *table);
+extern void mdb_date_to_tm(double td, struct tm *t);
 extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_ptr);
 extern int mdb_rewind_table(MdbTableDef *table);
 extern int mdb_fetch_row(MdbTableDef *table);
Index: mdbtools-0.6pre1/src/libmdb/data.c
===================================================================
--- mdbtools-0.6pre1.orig/src/libmdb/data.c
+++ mdbtools-0.6pre1/src/libmdb/data.c
@@ -779,56 +779,63 @@
 /* Date/Time is stored as a double, where the whole
    part is the days from 12/30/1899 and the fractional
    part is the fractional part of one day. */
-static char *
-mdb_date_to_string(MdbHandle *mdb, int start)
+
+void
+mdb_date_to_tm(double td, struct tm *t)
 {
-	struct tm t;
 	long int day, time;
 	int yr, q;
 	int *cal;
 	int noleap_cal[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
 	int leap_cal[]   = {0,31,60,91,121,152,182,213,244,274,305,335,366};
 
-	char *text = (char *) g_malloc(MDB_BIND_SIZE);
-	double td = mdb_get_double(mdb->pg_buf, start);
-
 	day = (long int)(td);
 	time = (long int)(fabs(td - day) * 86400.0 + 0.5);
-	t.tm_hour = time / 3600;
-	t.tm_min = (time / 60) % 60;
-	t.tm_sec = time % 60; 
-	t.tm_year = 1 - 1900;
+	t->tm_hour = time / 3600;
+	t->tm_min = (time / 60) % 60;
+	t->tm_sec = time % 60;
+	t->tm_year = 1 - 1900;
 
 	day += 693593; /* Days from 1/1/1 to 12/31/1899 */
-	t.tm_wday = (day+1) % 7;
+	t->tm_wday = (day+1) % 7;
 
 	q = day / 146097;  /* 146097 days in 400 years */
-	t.tm_year += 400 * q;
+	t->tm_year += 400 * q;
 	day -= q * 146097;
 
 	q = day / 36524;  /* 36524 days in 100 years */
 	if (q > 3) q = 3;
-	t.tm_year += 100 * q;
+	t->tm_year += 100 * q;
 	day -= q * 36524;
 
 	q = day / 1461;  /* 1461 days in 4 years */
-	t.tm_year += 4 * q;
+	t->tm_year += 4 * q;
 	day -= q * 1461;
 
 	q = day / 365;  /* 365 days in 1 year */
 	if (q > 3) q = 3;
-	t.tm_year += q;
+	t->tm_year += q;
 	day -= q * 365;
 
-	yr = t.tm_year + 1900;
+	yr = t->tm_year + 1900;
 	cal = ((yr)%4==0 && ((yr)%100!=0 || (yr)%400==0)) ?
 		leap_cal : noleap_cal;
-	for (t.tm_mon=0; t.tm_mon<12; t.tm_mon++) {
-		if (day < cal[t.tm_mon+1]) break;
+	for (t->tm_mon=0; t->tm_mon<12; t->tm_mon++) {
+		if (day < cal[t->tm_mon+1]) break;
 	}
-	t.tm_mday = day - cal[t.tm_mon] + 1;
-	t.tm_yday = day;
-	t.tm_isdst = -1;
+	t->tm_mday = day - cal[t->tm_mon] + 1;
+	t->tm_yday = day;
+	t->tm_isdst = -1;
+}
+
+static char *
+mdb_date_to_string(MdbHandle *mdb, int start)
+{
+	struct tm t;
+	char *text = (char *) g_malloc(MDB_BIND_SIZE);
+	double td = mdb_get_double(mdb->pg_buf, start);
+
+	mdb_date_to_tm(td, &t);
 
 	strftime(text, MDB_BIND_SIZE, date_fmt, &t);
 
Index: mdbtools-0.6pre1/src/libmdb/sargs.c
===================================================================
--- mdbtools-0.6pre1.orig/src/libmdb/sargs.c
+++ mdbtools-0.6pre1/src/libmdb/sargs.c
@@ -28,7 +28,7 @@
  * a mdb_test_[type]() function and invoke it from mdb_test_sarg()
  */
 #include "mdbtools.h"
-
+#include <time.h>
 #ifdef DMALLOC
 #include "dmalloc.h"
 #endif
@@ -97,8 +97,49 @@
 	}
 	return 0;
 }
-#if 0
-#endif
+
+int
+mdb_test_date(MdbSargNode *node, double td)
+{
+	struct tm found;
+	char date_tmp[MDB_BIND_SIZE];	//you should figure out a way to pull mdb_date_to_string in here
+
+	time_t found_t;
+	time_t asked_t;
+
+	double diff;
+
+	mdb_date_to_tm(td, &found);
+
+	asked_t = node->value.i;
+	found_t = mktime(&found);
+
+	diff = difftime(asked_t, found_t);
+
+	switch (node->op) {
+	case MDB_EQUAL:
+		if (diff==0) return 1;
+		break;
+	case MDB_GT:
+		if (diff<0) return 1;
+		break;
+	case MDB_LT:
+		if (diff>0) return 1;
+		break;
+	case MDB_GTEQ:
+		if (diff<=0) return 1;
+		break;
+	case MDB_LTEQ:
+		if (diff>=0) return 1;
+		break;
+	default:
+		fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_date() for operator %d\n", node->op);
+		break;
+	}
+	return 0;
+}
+
+
 int
 mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
 {
@@ -155,6 +196,8 @@
 		case MDB_TEXT:
 			mdb_unicode2ascii(mdb, field->value, field->siz, tmpbuf, 256);
 			return mdb_test_string(node, tmpbuf);
+		case MDB_DATETIME:
+			return mdb_test_date(node, mdb_get_double(field->value, 0));
 		default:
 			fprintf(stderr, "Calling mdb_test_sarg on unknown type.  Add code to mdb_test_sarg() for type %d\n",col->col_type);
 			break;