Browse Source

Fixed setting Null binds.

Brucey 3 năm trước cách đây
mục cha
commit
a234822ddf
4 tập tin đã thay đổi với 172 bổ sung85 xóa
  1. 9 9
      mariadb.mod/common.bmx
  2. 63 43
      mariadb.mod/glue.c
  3. 41 33
      mariadb.mod/mariadb.bmx
  4. 59 0
      mariadb.mod/tests/null_bind.bmx

+ 9 - 9
mariadb.mod/common.bmx

@@ -135,15 +135,15 @@ Extern
 	Function bmx_mysql_setBool(bools:Byte Ptr, index:Int, isNull:Int)
 	Function bmx_mysql_deleteBools(bools:Byte Ptr)
 	
-	Function bmx_mysql_bind_int(params:Byte Ptr, index:Int, value:Int Ptr)
-	Function bmx_mysql_bind_float(params:Byte Ptr, index:Int, value:Float Ptr)
-	Function bmx_mysql_bind_double(params:Byte Ptr, index:Int, value:Double Ptr)
-	Function bmx_mysql_bind_long(params:Byte Ptr, index:Int, value:Long Ptr)
-	Function bmx_mysql_bind_string(params:Byte Ptr, index:Int, value:Byte Ptr, size:Int)
-	Function bmx_mysql_bind_date(params:Byte Ptr, index:Int, value:Byte Ptr, _year:Int, _month:Int, _day:Int)
-	Function bmx_mysql_bind_time(params:Byte Ptr, index:Int, value:Byte Ptr, _hour:Int, _min:Int, _sec:Int)
-	Function bmx_mysql_bind_datetime(params:Byte Ptr, index:Int, value:Byte Ptr, _year:Int, _month:Int, _day:Int, _hour:Int, _min:Int, _sec:Int)
-	Function bmx_mysql_bind_blob(params:Byte Ptr, index:Int, value:Byte Ptr, size:Int)
+	Function bmx_mysql_bind_int(params:Byte Ptr, index:Int, value:Int Ptr, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_float(params:Byte Ptr, index:Int, value:Float Ptr, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_double(params:Byte Ptr, index:Int, value:Double Ptr, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_long(params:Byte Ptr, index:Int, value:Long Ptr, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_string(params:Byte Ptr, index:Int, value:Byte Ptr, size:Int, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_date(params:Byte Ptr, index:Int, value:Byte Ptr, _year:Int, _month:Int, _day:Int, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_time(params:Byte Ptr, index:Int, value:Byte Ptr, _hour:Int, _min:Int, _sec:Int, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_datetime(params:Byte Ptr, index:Int, value:Byte Ptr, _year:Int, _month:Int, _day:Int, _hour:Int, _min:Int, _sec:Int, nullsPtr:Byte Ptr)
+	Function bmx_mysql_bind_blob(params:Byte Ptr, index:Int, value:Byte Ptr, size:Int, nullsPtr:Byte Ptr)
 	
 	Function bmx_mysql_makeVals:Byte Ptr(size:Int)
 	Function bmx_mysql_deleteVals(vals:Byte Ptr)

+ 63 - 43
mariadb.mod/glue.c

@@ -122,117 +122,134 @@ void bmx_mysql_deleteVals(char ** vals) {
 }
 
 void bmx_mysql_bind_null(MYSQL_BIND* bindings, int index) {
-
 	MYSQL_BIND* bind = &bindings[index];
 	bind->buffer_type = MYSQL_TYPE_NULL;
 }
 
-void bmx_mysql_bind_int(MYSQL_BIND* bindings, int index, int * value) {
+void bmx_mysql_bind_int(MYSQL_BIND* bindings, int index, int * value, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 	
 	bind->buffer_type = MYSQL_TYPE_LONG;
-	bind->buffer = value;
-	bind->buffer_length = sizeof(int);
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = sizeof(int);
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_float(MYSQL_BIND* bindings, int index, float * value) {
+void bmx_mysql_bind_float(MYSQL_BIND* bindings, int index, float * value, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_FLOAT;
-	bind->buffer = value;
-	bind->buffer_length = sizeof(float);
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = sizeof(float);
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_double(MYSQL_BIND* bindings, int index, double * value) {
+void bmx_mysql_bind_double(MYSQL_BIND* bindings, int index, double * value, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_DOUBLE;
-	bind->buffer = value;
-	bind->buffer_length = sizeof(double);
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = sizeof(double);
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_long(MYSQL_BIND* bindings, int index, long * value) {
+void bmx_mysql_bind_long(MYSQL_BIND* bindings, int index, long * value, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_LONGLONG;
-	bind->buffer = value;
-	bind->buffer_length = 8;
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = 8;
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_string(MYSQL_BIND* bindings, int index, char * value, int size) {
+void bmx_mysql_bind_string(MYSQL_BIND* bindings, int index, char * value, int size, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 	bind->buffer_type = MYSQL_TYPE_STRING;
-	bind->buffer = value;
-	bind->buffer_length = size;
 
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = size;
+
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_blob(MYSQL_BIND* bindings, int index, char * value, int size) {
+void bmx_mysql_bind_blob(MYSQL_BIND* bindings, int index, char * value, int size, my_bool * isNull) {
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_BLOB;
-	bind->buffer = value;
-	bind->buffer_length = size;
 
-	bind->is_unsigned = 0;
+	if (!isNull) {
+		bind->buffer = value;
+		bind->buffer_length = size;
+
+		bind->is_unsigned = 0;
+	}
 }
 
-void bmx_mysql_bind_date(MYSQL_BIND* bindings, int index, MYSQL_TIME * date, unsigned int year, unsigned int month, unsigned int day) {
+void bmx_mysql_bind_date(MYSQL_BIND* bindings, int index, MYSQL_TIME * date, unsigned int year, unsigned int month, unsigned int day, my_bool * isNull) {
 
 	date->year = year;
 	date->month = month;
 	date->day = day;
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_DATE;
-	bind->buffer = (char *)date;
-	bind->buffer_length = sizeof(MYSQL_TIME);
 
+	if (!isNull) {
+		bind->buffer = (char *)date;
+		bind->buffer_length = sizeof(MYSQL_TIME);
+	}
 }
 
-void bmx_mysql_bind_time(MYSQL_BIND* bindings, int index, MYSQL_TIME * time, unsigned int hour, unsigned int minute, unsigned int second) {
+void bmx_mysql_bind_time(MYSQL_BIND* bindings, int index, MYSQL_TIME * time, unsigned int hour, unsigned int minute, unsigned int second, my_bool * isNull) {
 
 	time->hour = hour;
 	time->minute = minute;
 	time->second = second;
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_TIME;
-	bind->buffer = (char *)time;
-	bind->buffer_length = sizeof(MYSQL_TIME);
+	if (!isNull) {
+		bind->buffer = (char *)time;
+		bind->buffer_length = sizeof(MYSQL_TIME);
+	}
 }
 
 void bmx_mysql_bind_datetime(MYSQL_BIND* bindings, int index, MYSQL_TIME  * datetime,
-		unsigned int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int minute, unsigned int second) {
+		unsigned int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int minute, unsigned int second, my_bool * isNull) {
 
 	datetime->year = year;
 	datetime->month = month;
@@ -242,12 +259,15 @@ void bmx_mysql_bind_datetime(MYSQL_BIND* bindings, int index, MYSQL_TIME  * date
 	datetime->second = second;
 
 	MYSQL_BIND* bind = &bindings[index];
-	bind->is_null = (my_bool*)0;
+	bind->is_null = (my_bool*)isNull;
 	bind->length = 0;
 
 	bind->buffer_type = MYSQL_TYPE_DATETIME;
-	bind->buffer = (char *)datetime;
-	bind->buffer_length = sizeof(MYSQL_TIME);
+
+	if (!isNull) {
+		bind->buffer = (char *)datetime;
+		bind->buffer_length = sizeof(MYSQL_TIME);
+	}
 }
 
 void examine_bindings(MYSQL_BIND* bindings, int size, MYSQL_STMT *stmt) {

+ 41 - 33
mariadb.mod/mariadb.bmx

@@ -31,11 +31,13 @@ about: A MariaDB database driver for #Database.Core
 End Rem
 Module Database.MariaDB
 
-ModuleInfo "Version: 1.00"
+ModuleInfo "Version: 1.01"
 ModuleInfo "Author: Bruce A Henderson"
 ModuleInfo "License: BSD"
 ModuleInfo "Copyright: Wrapper - 2007-2022 Bruce A Henderson"
 
+ModuleInfo "History: 1.01"
+ModuleInfo "History: Fixed setting Null binds"
 ModuleInfo "History: 1.00 Initial Release"
 
 ?win32x86
@@ -557,51 +559,57 @@ Type TMySQLResultSet Extends TQueryResultSet
 
 		Local strings:Byte Ptr[]
 		Local times:Byte Ptr[]
+		Local nulls:Byte[]
 
 		If paramCount = bindCount Then
 
 			strings = New Byte Ptr[paramCount]
 			times = New Byte Ptr[paramCount]
+			nulls = New Byte[paramCount]
 		
 			For Local i:Int = 0 Until paramCount
 
 				Local isNull:Int = False
-				
+				Local nullsPtr:Byte Ptr
+
 				If Not values[i] Or values[i].isNull() Then
 					isNull = True
-				Else
-					Select values[i].kind()
-						Case DBTYPE_INT
-							bmx_mysql_bind_int(parameterBindings, i, Varptr TDBInt(values[i]).value)
-						Case DBTYPE_FLOAT
-							bmx_mysql_bind_float(parameterBindings, i, Varptr TDBFloat(values[i]).value)
-						Case DBTYPE_DOUBLE
-							bmx_mysql_bind_double(parameterBindings, i, Varptr TDBDouble(values[i]).value)
-						Case DBTYPE_LONG
-							bmx_mysql_bind_long(parameterBindings, i, Varptr TDBLong(values[i]).value)
-						Case DBTYPE_STRING
-							local s:Byte Ptr = values[i].getString().ToUTF8String()
-							strings[i] = s
-							bmx_mysql_bind_string(parameterBindings, i, s, _strlen(s))
-							
-						Case DBTYPE_BLOB
-							bmx_mysql_bind_blob(parameterBindings, i, TDBBlob(values[i]).value, TDBBlob(values[i])._size)
-
-						Case DBTYPE_DATE
-							Local date:TDBDate = TDBDate(values[i])
-							times[i] = bmx_mysql_makeTime()
-							bmx_mysql_bind_date(parameterBindings, i, times[i], date.getYear(), date.getMonth(), date.getDay())
-						Case DBTYPE_DATETIME
-							Local date:TDBDateTime = TDBDateTime(values[i])
-							times[i] = bmx_mysql_makeTime()
-							bmx_mysql_bind_datetime(parameterBindings, i, times[i], date.getYear(), date.getMonth(), date.getDay(), date.getHour(), date.getMinute(), date.getSecond())
-						Case DBTYPE_TIME
-							Local date:TDBTime = TDBTime(values[i])
-							times[i] = bmx_mysql_makeTime()
-							bmx_mysql_bind_time(parameterBindings, i, times[i], date.getHour(), date.getMinute(), date.getSecond())
-					End Select
+					nulls[i] = 1
+					nullsPtr = Byte Ptr(nulls) + i
 				End If
 
+				Select values[i].kind()
+					Case DBTYPE_INT
+						bmx_mysql_bind_int(parameterBindings, i, Varptr TDBInt(values[i]).value, nullsPtr)
+					Case DBTYPE_FLOAT
+						bmx_mysql_bind_float(parameterBindings, i, Varptr TDBFloat(values[i]).value, nullsPtr)
+					Case DBTYPE_DOUBLE
+						bmx_mysql_bind_double(parameterBindings, i, Varptr TDBDouble(values[i]).value, nullsPtr)
+					Case DBTYPE_LONG
+						bmx_mysql_bind_long(parameterBindings, i, Varptr TDBLong(values[i]).value, nullsPtr)
+					Case DBTYPE_STRING
+						local s:Byte Ptr = values[i].getString().ToUTF8String()
+						strings[i] = s
+						bmx_mysql_bind_string(parameterBindings, i, s, _strlen(s), nullsPtr)
+						
+					Case DBTYPE_BLOB
+						bmx_mysql_bind_blob(parameterBindings, i, TDBBlob(values[i]).value, TDBBlob(values[i])._size, nullsPtr)
+
+					Case DBTYPE_DATE
+						Local date:TDBDate = TDBDate(values[i])
+						times[i] = bmx_mysql_makeTime()
+						bmx_mysql_bind_date(parameterBindings, i, times[i], date.getYear(), date.getMonth(), date.getDay(), nullsPtr)
+					Case DBTYPE_DATETIME
+						Local date:TDBDateTime = TDBDateTime(values[i])
+						times[i] = bmx_mysql_makeTime()
+						bmx_mysql_bind_datetime(parameterBindings, i, times[i], date.getYear(), date.getMonth(), date.getDay(), date.getHour(), date.getMinute(), date.getSecond(), nullsPtr)
+					Case DBTYPE_TIME
+						Local date:TDBTime = TDBTime(values[i])
+						times[i] = bmx_mysql_makeTime()
+						bmx_mysql_bind_time(parameterBindings, i, times[i], date.getHour(), date.getMinute(), date.getSecond(), nullsPtr)
+				End Select
+
+
 			Next
 
 			' actually bind the parameters

+ 59 - 0
mariadb.mod/tests/null_bind.bmx

@@ -0,0 +1,59 @@
+SuperStrict
+
+Framework Database.MariaDB
+Import BRL.filesystem
+Import BRL.StandardIO
+
+Local db:TDBConnection = LoadDatabase("MARIADB", "maxtest", Null, 0, "brucey", "brucey")
+
+If Not db Then
+	Print("Didn't work...")
+	End
+End If
+
+If db.hasError() Then
+	errorAndClose(db)
+End If
+
+
+If db.isOpen() Then
+
+	db.executeQuery("DROP TABLE if exists nulltest")
+	
+	Local s:String = "CREATE TABLE if not exists nulltest ( " + ..
+	  " c1 varchar(30)," + ..
+	  " c2 int, c3 float )"
+
+	db.executeQuery(s)
+
+	If db.hasError() Then
+		errorAndClose(db)
+	End If
+	
+	db.executeQuery("INSERT INTO nulltest VALUES('hello', 1, 5)")
+	db.executeQuery("INSERT INTO nulltest VALUES('world', 2, 10)")
+
+	Local query:TDatabaseQuery = TDatabaseQuery.Create(db)
+	query.Prepare("UPDATE nulltest SET c3=? WHERE c2=?")
+	
+	query.BindValue(0, TDBFLoat.Set(1))
+	query.BindValue(1, TDBInt.Set(1))
+	
+	query.Execute()
+	
+	query.BindValue(0, New TDBFLoat())
+	query.BindValue(1, TDBInt.Set(1))
+	
+	query.Execute()
+	
+	
+	db.close()
+	
+End If
+
+Function errorAndClose(db:TDBConnection)
+	Print(db.error().toString())
+	db.close()
+	End
+End Function
+