* beagled/Makefile.am, beagled/Mono.Data.SqliteClient: Pull in latest
upstream version, and update Jon's read-on-demand optimization.
* beagled/FileAttributesStore_Sqlite.cs, beagled/TextCache.cs: Update for
slightly modified sqlite exception API.
Index: beagled/FileAttributesStore_Sqlite.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/FileAttributesStore_Sqlite.cs,v
retrieving revision 1.20
diff -u -B -p -r1.20 FileAttributesStore_Sqlite.cs
--- beagled/FileAttributesStore_Sqlite.cs 24 Jan 2006 23:35:23 -0000 1.20
+++ beagled/FileAttributesStore_Sqlite.cs 2 Feb 2006 15:20:47 -0000
@@ -195,11 +195,8 @@ namespace Beagle.Daemon {
try {
command.ExecuteNonQuery ();
break;
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ } catch (SqliteBusyException ex) {
+ Thread.Sleep (50);
}
}
@@ -224,11 +221,8 @@ namespace Beagle.Daemon {
while (reader == null) {
try {
reader = command.ExecuteReader ();
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ } catch (SqliteBusyException ex) {
+ Thread.Sleep (50);
}
}
return reader;
@@ -239,11 +233,8 @@ namespace Beagle.Daemon {
while (true) {
try {
return reader.Read ();
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ } catch (SqliteBusyException ex) {
+ Thread.Sleep (50);
}
}
}
Index: beagled/Makefile.am
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Makefile.am,v
retrieving revision 1.150
diff -u -B -p -r1.150 Makefile.am
--- beagled/Makefile.am 31 Jan 2006 22:55:32 -0000 1.150
+++ beagled/Makefile.am 2 Feb 2006 15:20:47 -0000
@@ -9,7 +9,8 @@
# 0219 = Variable is assigned but never used
# 0436 = Ignore imported type (local SqliteClient)
-CSC = mcs -debug -nowarn:0162,0164,0169,0219,0436
+# unsafe arg for Mono.Data.SqliteClient fork
+CSC = mcs -debug -nowarn:0162,0164,0169,0219,0436 -unsafe
BACKENDDIR = $(pkglibdir)/Backends
@@ -244,7 +245,7 @@ SQLITE_CSFILES = \
$(sqlitedir)/Sqlite.cs \
$(sqlitedir)/SqliteDataAdapter.cs \
$(sqlitedir)/SqliteDataReader.cs \
- $(sqlitedir)/SqliteException.cs \
+ $(sqlitedir)/SqliteExceptions.cs \
$(sqlitedir)/SqliteParameterCollection.cs \
$(sqlitedir)/SqliteParameter.cs \
$(sqlitedir)/SqliteRowUpdatedEventArgs.cs \
Index: beagled/TextCache.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/TextCache.cs,v
retrieving revision 1.28
diff -u -B -p -r1.28 TextCache.cs
--- beagled/TextCache.cs 30 Jan 2006 18:19:54 -0000 1.28
+++ beagled/TextCache.cs 2 Feb 2006 15:20:47 -0000
@@ -116,12 +116,9 @@ namespace Beagle.Daemon {
try {
reader = ExecuteReaderOrWait (command);
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.NOTADB) {
- Logger.Log.Warn ("Likely sqlite database version mismatch trying to read from {0}. Purging.", db_filename);
- create_new_db = true;
- } else
- throw;
+ } catch (ApplicationException ex) {
+ Logger.Log.Warn ("Likely sqlite database version mismatch trying to read from {0}. Purging.", db_filename);
+ create_new_db = true;
}
if (reader != null)
@@ -178,12 +175,9 @@ namespace Beagle.Daemon {
try {
command.ExecuteNonQuery ();
break;
- } catch (SqliteException ex) {
+ } catch (SqliteBusyException ex) {
// FIXME: should we eventually time out?
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ Thread.Sleep (50);
}
}
command.Dispose ();
@@ -195,11 +189,8 @@ namespace Beagle.Daemon {
while (reader == null) {
try {
reader = command.ExecuteReader ();
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ } catch (SqliteBusyException ex) {
+ Thread.Sleep (50);
}
}
return reader;
@@ -210,11 +201,8 @@ namespace Beagle.Daemon {
while (true) {
try {
return reader.Read ();
- } catch (SqliteException ex) {
- if (ex.SqliteError == SqliteError.BUSY)
- Thread.Sleep (50);
- else
- throw ex;
+ } catch (SqliteBusyException ex) {
+ Thread.Sleep (50);
}
}
}
Index: beagled/Mono.Data.SqliteClient/Sqlite.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/Sqlite.cs,v
retrieving revision 1.2
diff -u -B -p -r1.2 Sqlite.cs
--- beagled/Mono.Data.SqliteClient/Sqlite.cs 24 Oct 2005 21:56:28 -0000 1.2
+++ beagled/Mono.Data.SqliteClient/Sqlite.cs 2 Feb 2006 15:20:48 -0000
@@ -33,13 +33,14 @@
using System;
using System.Security;
using System.Runtime.InteropServices;
+using System.Text;
namespace Mono.Data.SqliteClient
{
///
/// Represents the return values for sqlite_exec() and sqlite_step()
///
- public enum SqliteError : int {
+ internal enum SqliteError : int {
/// Successful result
OK = 0,
/// SQL error or missing database
@@ -134,14 +135,14 @@ namespace Mono.Data.SqliteClient
[DllImport ("sqlite")]
internal static extern SqliteError sqlite_exec (IntPtr handle, string sql, IntPtr callback, IntPtr user_data, out IntPtr errstr_ptr);
- [DllImport("sqlite3")]
- internal static extern int sqlite3_open (string dbname, out IntPtr handle);
+ [DllImport("sqlite3", CharSet = CharSet.Unicode)]
+ internal static extern int sqlite3_open16 (string dbname, out IntPtr handle);
[DllImport("sqlite3")]
internal static extern void sqlite3_close (IntPtr sqlite_handle);
[DllImport("sqlite3")]
- internal static extern IntPtr sqlite3_errmsg (IntPtr sqlite_handle);
+ internal static extern IntPtr sqlite3_errmsg16 (IntPtr sqlite_handle);
[DllImport("sqlite3")]
internal static extern int sqlite3_changes (IntPtr handle);
@@ -150,7 +151,7 @@ namespace Mono.Data.SqliteClient
internal static extern int sqlite3_last_insert_rowid (IntPtr sqlite_handle);
[DllImport ("sqlite3")]
- internal static extern SqliteError sqlite3_prepare (IntPtr sqlite_handle, IntPtr zSql, int zSqllen, out IntPtr pVm, out IntPtr pzTail);
+ internal static extern SqliteError sqlite3_prepare16 (IntPtr sqlite_handle, IntPtr zSql, int zSqllen, out IntPtr pVm, out IntPtr pzTail);
[DllImport ("sqlite3")]
internal static extern SqliteError sqlite3_step (IntPtr pVm);
@@ -162,16 +163,16 @@ namespace Mono.Data.SqliteClient
internal static extern SqliteError sqlite3_exec (IntPtr handle, string sql, IntPtr callback, IntPtr user_data, out IntPtr errstr_ptr);
[DllImport ("sqlite3")]
- internal static extern IntPtr sqlite3_column_name (IntPtr pVm, int col);
+ internal static extern IntPtr sqlite3_column_name16 (IntPtr pVm, int col);
[DllImport ("sqlite3")]
- internal static extern IntPtr sqlite3_column_text (IntPtr pVm, int col);
+ internal static extern IntPtr sqlite3_column_text16 (IntPtr pVm, int col);
[DllImport ("sqlite3")]
internal static extern IntPtr sqlite3_column_blob (IntPtr pVm, int col);
[DllImport ("sqlite3")]
- internal static extern int sqlite3_column_bytes (IntPtr pVm, int col);
+ internal static extern int sqlite3_column_bytes16 (IntPtr pVm, int col);
[DllImport ("sqlite3")]
internal static extern int sqlite3_column_count (IntPtr pVm);
@@ -185,11 +186,14 @@ namespace Mono.Data.SqliteClient
[DllImport ("sqlite3")]
internal static extern double sqlite3_column_double (IntPtr pVm, int col);
+ [DllImport ("sqlite3")]
+ internal static extern IntPtr sqlite3_column_decltype16 (IntPtr pVm, int col);
+
[DllImport ("sqlite3")]
internal static extern int sqlite3_bind_parameter_count (IntPtr pStmt);
[DllImport ("sqlite3")]
- internal static extern String sqlite3_bind_parameter_name (IntPtr pStmt, int n);
+ internal static extern IntPtr sqlite3_bind_parameter_name (IntPtr pStmt, int n); // UTF-8 encoded return
[DllImport ("sqlite3")]
internal static extern SqliteError sqlite3_bind_blob (IntPtr pStmt, int n, byte[] blob, int length, IntPtr freetype);
@@ -201,18 +205,75 @@ namespace Mono.Data.SqliteClient
internal static extern SqliteError sqlite3_bind_int (IntPtr pStmt, int n, int value);
[DllImport ("sqlite3")]
- internal static extern SqliteError sqlite3_bind_int64 (IntPtr pStmt, Int64 n, long value);
+ internal static extern SqliteError sqlite3_bind_int64 (IntPtr pStmt, int n, long value);
[DllImport ("sqlite3")]
internal static extern SqliteError sqlite3_bind_null (IntPtr pStmt, int n);
- [DllImport ("sqlite3")]
- internal static extern SqliteError sqlite3_bind_text (IntPtr pStmt, int n, string value, int length, IntPtr freetype);
-
- [DllImport ("sqlite3")]
- internal static extern SqliteError sqlite3_bind_text16 (IntPtr pStmt, int n, byte[] value, int length, IntPtr freetype);
+ [DllImport ("sqlite3", CharSet = CharSet.Unicode)]
+ internal static extern SqliteError sqlite3_bind_text16 (IntPtr pStmt, int n, string value, int length, IntPtr freetype);
#endregion
+
+ // These are adapted from Mono.Unix. When encoding is null,
+ // use Ansi encoding, which is a superset of the default
+ // expected encoding (ISO-8859-1).
+
+ public static IntPtr StringToHeap (string s, Encoding encoding)
+ {
+ if (encoding == null)
+ return Marshal.StringToCoTaskMemAnsi (s);
+
+ int min_byte_count = encoding.GetMaxByteCount(1);
+ char[] copy = s.ToCharArray ();
+ byte[] marshal = new byte [encoding.GetByteCount (copy) + min_byte_count];
+
+ int bytes_copied = encoding.GetBytes (copy, 0, copy.Length, marshal, 0);
+
+ if (bytes_copied != (marshal.Length-min_byte_count))
+ throw new NotSupportedException ("encoding.GetBytes() doesn't equal encoding.GetByteCount()!");
+
+ IntPtr mem = Marshal.AllocCoTaskMem (marshal.Length);
+ if (mem == IntPtr.Zero)
+ throw new OutOfMemoryException ();
+
+ bool copied = false;
+ try {
+ Marshal.Copy (marshal, 0, mem, marshal.Length);
+ copied = true;
+ }
+ finally {
+ if (!copied)
+ Marshal.FreeCoTaskMem (mem);
+ }
+
+ return mem;
+ }
+
+ public static unsafe string HeapToString (IntPtr p, Encoding encoding)
+ {
+ if (encoding == null)
+ return Marshal.PtrToStringAnsi (p);
+
+ if (p == IntPtr.Zero)
+ return null;
+
+ // This assumes a single byte terminates the string.
+
+ int len = 0;
+ while (Marshal.ReadByte (p, len) != 0)
+ checked {++len;}
+
+ string s = new string ((sbyte*) p, 0, len, encoding);
+ len = s.Length;
+ while (len > 0 && s [len-1] == 0)
+ --len;
+ if (len == s.Length)
+ return s;
+ return s.Substring (0, len);
+ }
+
+
}
}
Index: beagled/Mono.Data.SqliteClient/SqliteCommand.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/SqliteCommand.cs,v
retrieving revision 1.3
diff -u -B -p -r1.3 SqliteCommand.cs
--- beagled/Mono.Data.SqliteClient/SqliteCommand.cs 15 Nov 2005 20:49:12 -0000 1.3
+++ beagled/Mono.Data.SqliteClient/SqliteCommand.cs 2 Feb 2006 15:20:48 -0000
@@ -9,6 +9,7 @@
// Chris Turchin
// Jeroen Zwartepoorte
// Thomas Zoechling
+// Joshua Tauberer
//
// Copyright (C) 2002 Vladimir Vukicevic
//
@@ -35,7 +36,6 @@
using System;
using System.Collections;
using System.Text;
-using Mono.Unix.Native;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Data;
@@ -58,7 +57,6 @@ namespace Mono.Data.SqliteClient
private UpdateRowSource upd_row_source;
private SqliteParameterCollection sql_params;
private bool prepared = false;
- private ArrayList pStmts;
#endregion
@@ -98,7 +96,7 @@ namespace Mono.Data.SqliteClient
public string CommandText
{
get { return sql; }
- set { sql = value; }
+ set { sql = value; prepared = false; }
}
public int CommandTimeout
@@ -173,27 +171,162 @@ namespace Mono.Data.SqliteClient
return Sqlite.sqlite_changes(parent_conn.Handle);
}
- private string ReplaceParams(Match m)
+ private void BindParameters3 (IntPtr pStmt)
{
- string input = m.Value;
- if (m.Groups["param"].Success)
+ if (sql_params == null) return;
+ if (sql_params.Count == 0) return;
+
+ int pcount = Sqlite.sqlite3_bind_parameter_count (pStmt);
+
+ for (int i = 1; i <= pcount; i++)
{
- Group g = m.Groups["param"];
- string find = g.Value;
- //FIXME: sqlite works internally only with strings, so this assumtion is mostly legit, but what about date formatting, etc?
- //Need to fix SqlLiteDataReader first to acurately describe the tables
- SqliteParameter sqlp = Parameters[find];
- string replace = Convert.ToString(sqlp.Value);
- if(sqlp.DbType == DbType.String)
- {
- replace = "\"" + replace + "\"";
+ String name = Sqlite.HeapToString (Sqlite.sqlite3_bind_parameter_name (pStmt, i), Encoding.UTF8);
+ if (name == null) continue;
+
+ SqliteParameter param = sql_params[name];
+
+ if (param.Value == null) {
+ Sqlite.sqlite3_bind_null (pStmt, i);
+ continue;
}
+
+ Type ptype = param.Value.GetType ();
+
+ SqliteError err;
- input = Regex.Replace(input,find,replace);
- return input;
+ if (ptype.Equals (typeof (String)))
+ {
+ String s = (String)param.Value;
+ err = Sqlite.sqlite3_bind_text16 (pStmt, i, s, -1, (IntPtr)(-1));
+ }
+ else if (ptype.Equals (typeof (DBNull)))
+ {
+ err = Sqlite.sqlite3_bind_null (pStmt, i);
+ }
+ else if (ptype.Equals (typeof (Boolean)))
+ {
+ bool b = (bool)param.Value;
+ err = Sqlite.sqlite3_bind_int (pStmt, i, b ? 1 : 0);
+ } else if (ptype.Equals (typeof (Byte)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (Byte)param.Value);
+ }
+ else if (ptype.Equals (typeof (Char)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (Char)param.Value);
+ }
+ else if (ptype.Equals (typeof (Int16)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (Int16)param.Value);
+ }
+ else if (ptype.Equals (typeof (Int32)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (Int32)param.Value);
+ }
+ else if (ptype.Equals (typeof (SByte)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (SByte)param.Value);
+ }
+ else if (ptype.Equals (typeof (UInt16)))
+ {
+ err = Sqlite.sqlite3_bind_int (pStmt, i, (UInt16)param.Value);
+ }
+ else if (ptype.Equals (typeof (DateTime)))
+ {
+ DateTime dt = (DateTime)param.Value;
+ err = Sqlite.sqlite3_bind_int64 (pStmt, i, dt.ToFileTime ());
+ }
+ else if (ptype.Equals (typeof (Double)))
+ {
+ err = Sqlite.sqlite3_bind_double (pStmt, i, (Double)param.Value);
+ }
+ else if (ptype.Equals (typeof (Single)))
+ {
+ err = Sqlite.sqlite3_bind_double (pStmt, i, (Single)param.Value);
+ }
+ else if (ptype.Equals (typeof (UInt32)))
+ {
+ err = Sqlite.sqlite3_bind_int64 (pStmt, i, (UInt32)param.Value);
+ }
+ else if (ptype.Equals (typeof (Int64)))
+ {
+ err = Sqlite.sqlite3_bind_int64 (pStmt, i, (Int64)param.Value);
+ }
+ else if (ptype.Equals (typeof (Byte[])))
+ {
+ err = Sqlite.sqlite3_bind_blob (pStmt, i, (Byte[])param.Value, ((Byte[])param.Value).Length, (IntPtr)(-1));
+ }
+ else
+ {
+ throw new ApplicationException("Unkown Parameter Type");
+ }
+ if (err != SqliteError.OK)
+ {
+ throw new ApplicationException ("Sqlite error in bind " + err);
+ }
+ }
+ }
+
+ private void GetNextStatement (IntPtr pzStart, out IntPtr pzTail, out IntPtr pStmt)
+ {
+ if (parent_conn.Version == 3)
+ {
+ SqliteError err = Sqlite.sqlite3_prepare16 (parent_conn.Handle, pzStart, -1, out pStmt, out pzTail);
+ if (err != SqliteError.OK)
+ throw new SqliteSyntaxException (GetError3());
}
else
- return m.Value;
+ {
+ IntPtr errMsg;
+ SqliteError err = Sqlite.sqlite_compile (parent_conn.Handle, pzStart, out pzTail, out pStmt, out errMsg);
+
+ if (err != SqliteError.OK)
+ {
+ string msg = "unknown error";
+ if (errMsg != IntPtr.Zero)
+ {
+ msg = Marshal.PtrToStringAnsi (errMsg);
+ Sqlite.sqliteFree (errMsg);
+ }
+ throw new SqliteSyntaxException (msg);
+ }
+ }
+ }
+
+ // Executes a statement and ignores its result.
+ private void ExecuteStatement (IntPtr pStmt) {
+ int cols;
+ IntPtr pazValue, pazColName;
+ ExecuteStatement (pStmt, out cols, out pazValue, out pazColName);
+ }
+
+ // Executes a statement and returns whether there is more data available.
+ internal bool ExecuteStatement (IntPtr pStmt, out int cols, out IntPtr pazValue, out IntPtr pazColName) {
+ SqliteError err;
+
+ if (parent_conn.Version == 3)
+ {
+ err = Sqlite.sqlite3_step (pStmt);
+ if (err == SqliteError.ERROR)
+ throw new SqliteExecutionException (GetError3());
+ pazValue = IntPtr.Zero; pazColName = IntPtr.Zero; // not used for v=3
+ cols = Sqlite.sqlite3_column_count (pStmt);
+ }
+ else
+ {
+ err = Sqlite.sqlite_step (pStmt, out cols, out pazValue, out pazColName);
+ if (err == SqliteError.ERROR)
+ throw new SqliteExecutionException ();
+ }
+
+ if (err == SqliteError.BUSY)
+ throw new SqliteBusyException();
+
+ if (err == SqliteError.MISUSE)
+ throw new SqliteExecutionException();
+
+ // err is either ROW or DONE.
+ return err == SqliteError.ROW;
}
#endregion
@@ -204,154 +337,54 @@ namespace Mono.Data.SqliteClient
{
}
- public string ProcessParameters()
+ public string BindParameters2()
{
- string processedText = sql;
-
- //Regex looks odd perhaps, but it works - same impl. as in the firebird db provider
- //the named parameters are using the ADO.NET standard @-prefix but sqlite is considering ":" as a prefix for v.3...
- //ref: http://www.mail-archive.com/sqlite-users@sqlite.org/msg01851.html
- //Regex r = new Regex(@"(('[^']*?\@[^']*')*[^'@]*?)*(?@\w+)+([^'@]*?('[^']*?\@[^']*'))*",RegexOptions.ExplicitCapture);
-
- //The above statement is true for the commented regEx, but I changed it to use the :-prefix, because now (12.05.2005 sqlite3)
- //sqlite is using : as Standard Parameterprefix
-
- Regex r = new Regex(@"(('[^']*?\:[^']*')*[^':]*?)*(?:\w+)+([^':]*?('[^']*?\:[^']*'))*",RegexOptions.ExplicitCapture);
- MatchEvaluator me = new MatchEvaluator(ReplaceParams);
- processedText = r.Replace(sql, me);
- return processedText;
+ string text = sql;
+
+ // There used to be a crazy regular expression here, but it caused Mono
+ // to go into an infinite loop of some sort when there were no parameters
+ // in the SQL string. That was too complicated anyway.
+
+ // Here we search for substrings of the form :wwwww where w is a letter or digit
+ // (not sure what a legitimate Sqlite3 identifier is), except those within quotes.
+
+ char inquote = (char)0;
+ for (int i = 0; i < text.Length; i++) {
+ char c = text[i];
+ if (c == inquote) {
+ inquote = (char)0;
+ } else if (inquote == (char)0 && (c == '\'' || c == '"')) {
+ inquote = c;
+ } else if (inquote == (char)0 && c == ':') {
+ int start = i;
+ while (++i < text.Length && char.IsLetterOrDigit(text[i])) { } // scan to end
+ string name = text.Substring(start, i-start);
+ string value = "'" + Convert.ToString(Parameters[name].Value).Replace("'", "''") + "'";
+ text = text.Replace(name, value);
+ i += value.Length - name.Length - 1;
+ }
+ }
+
+ return text;
}
public void Prepare ()
{
- pStmts = new ArrayList();
- string sqlcmds = sql;
+ // There isn't much we can do here. If a table schema
+ // changes after preparing a statement, Sqlite bails,
+ // so we can only compile statements right before we
+ // want to run them.
+ if (prepared) return;
+
if (Parameters.Count > 0 && parent_conn.Version == 2)
{
- sqlcmds = ProcessParameters();
+ sql = BindParameters2();
}
- SqliteError err = SqliteError.OK;
- IntPtr psql = Mono.Unix.UnixMarshal.StringToHeap(sqlcmds);
- IntPtr pzTail = psql;
- try {
- do { // sql may contain multiple sql commands, loop until they're all processed
- IntPtr pStmt = IntPtr.Zero;
- if (parent_conn.Version == 3)
- {
- err = Sqlite.sqlite3_prepare (parent_conn.Handle, pzTail, sql.Length, out pStmt, out pzTail);
- if (err != SqliteError.OK) {
- string msg = Marshal.PtrToStringAnsi (Sqlite.sqlite3_errmsg (parent_conn.Handle));
- throw new SqliteException (err, msg);
- }
- }
- else
- {
- IntPtr errMsg;
- err = Sqlite.sqlite_compile (parent_conn.Handle, pzTail, out pzTail, out pStmt, out errMsg);
-
- if (err != SqliteError.OK)
- {
- string msg = "unknown error";
- if (errMsg != IntPtr.Zero)
- {
- msg = Marshal.PtrToStringAnsi (errMsg);
- Sqlite.sqliteFree (errMsg);
- }
- throw new SqliteException (err, msg);
- }
- }
-
- pStmts.Add(pStmt);
-
- if (parent_conn.Version == 3)
- {
- int pcount = Sqlite.sqlite3_bind_parameter_count (pStmt);
- if (sql_params == null) pcount = 0;
-
- for (int i = 1; i <= pcount; i++)
- {
- String name = Sqlite.sqlite3_bind_parameter_name (pStmt, i);
- SqliteParameter param = sql_params[name];
- Type ptype = param.Value.GetType ();
-
- if (ptype.Equals (typeof (String)))
- {
- String s = (String)param.Value;
- err = Sqlite.sqlite3_bind_text (pStmt, i, s, s.Length, (IntPtr)(-1));
- }
- else if (ptype.Equals (typeof (DBNull)))
- {
- err = Sqlite.sqlite3_bind_null (pStmt, i);
- }
- else if (ptype.Equals (typeof (Boolean)))
- {
- bool b = (bool)param.Value;
- err = Sqlite.sqlite3_bind_int (pStmt, i, b ? 1 : 0);
- } else if (ptype.Equals (typeof (Byte)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (Byte)param.Value);
- }
- else if (ptype.Equals (typeof (Char)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (Char)param.Value);
- }
- else if (ptype.Equals (typeof (Int16)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (Int16)param.Value);
- }
- else if (ptype.Equals (typeof (Int32)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (Int32)param.Value);
- }
- else if (ptype.Equals (typeof (SByte)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (SByte)param.Value);
- }
- else if (ptype.Equals (typeof (UInt16)))
- {
- err = Sqlite.sqlite3_bind_int (pStmt, i, (UInt16)param.Value);
- }
- else if (ptype.Equals (typeof (DateTime)))
- {
- DateTime dt = (DateTime)param.Value;
- err = Sqlite.sqlite3_bind_int64 (pStmt, i, dt.ToFileTime ());
- }
- else if (ptype.Equals (typeof (Double)))
- {
- err = Sqlite.sqlite3_bind_double (pStmt, i, (Double)param.Value);
- }
- else if (ptype.Equals (typeof (Single)))
- {
- err = Sqlite.sqlite3_bind_double (pStmt, i, (Single)param.Value);
- }
- else if (ptype.Equals (typeof (UInt32)))
- {
- err = Sqlite.sqlite3_bind_int64 (pStmt, i, (UInt32)param.Value);
- }
- else if (ptype.Equals (typeof (Int64)))
- {
- err = Sqlite.sqlite3_bind_int64 (pStmt, i, (Int64)param.Value);
- }
- else
- {
- throw new ApplicationException("Unkown Parameter Type");
- }
- if (err != SqliteError.OK)
- {
- throw new ApplicationException ("Sqlite error in bind " + err);
- }
- }
- }
- } while ((int)pzTail - (int)psql < sql.Length);
- } finally {
- Mono.Unix.UnixMarshal.FreeHeap(psql);
- }
- prepared=true;
+ prepared = true;
}
-
IDbDataParameter IDbCommand.CreateParameter()
{
return CreateParameter ();
@@ -365,7 +398,6 @@ namespace Mono.Data.SqliteClient
public int ExecuteNonQuery ()
{
int rows_affected;
- // Since want_results is false, this always returns null
ExecuteReader (CommandBehavior.Default, false, out rows_affected);
return rows_affected;
}
@@ -404,84 +436,97 @@ namespace Mono.Data.SqliteClient
public SqliteDataReader ExecuteReader (CommandBehavior behavior, bool want_results, out int rows_affected)
{
- SqliteDataReader reader = null;
- SqliteError err = SqliteError.OK;
- IntPtr errMsg = IntPtr.Zero;
+ Prepare ();
+
+ // The SQL string may contain multiple sql commands, so the main
+ // thing to do is have Sqlite iterate through the commands.
+ // If want_results, only the last command is returned as a
+ // DataReader. Otherwise, no command is returned as a
+ // DataReader.
+
+ IntPtr psql; // pointer to SQL command
+
+ // Sqlite 2 docs say this: By default, SQLite assumes that all data uses a fixed-size 8-bit
+ // character (iso8859). But if you give the --enable-utf8 option to the configure script, then the
+ // library assumes UTF-8 variable sized characters. This makes a difference for the LIKE and GLOB
+ // operators and the LENGTH() and SUBSTR() functions. The static string sqlite_encoding will be set
+ // to either "UTF-8" or "iso8859" to indicate how the library was compiled. In addition, the sqlite.h
+ // header file will define one of the macros SQLITE_UTF8 or SQLITE_ISO8859, as appropriate.
+ //
+ // We have no way of knowing whether Sqlite 2 expects ISO8859 or UTF-8, but ISO8859 seems to be the
+ // default. Therefore, we need to use an ISO8859(-1) compatible encoding, like ANSI.
+ // OTOH, the user may want to specify the encoding of the bytes stored in the database, regardless
+ // of what Sqlite is treating them as,
+
+ // For Sqlite 3, we use the UTF-16 prepare function, so we need a UTF-16 string.
+
+ if (parent_conn.Version == 2)
+ psql = Sqlite.StringToHeap (sql.Trim(), parent_conn.Encoding);
+ else
+ psql = Marshal.StringToCoTaskMemUni (sql.Trim());
+
+ IntPtr pzTail = psql;
+ IntPtr errMsgPtr;
+
parent_conn.StartExec ();
-
- try
- {
- if (!prepared)
- {
- Prepare ();
- }
- for (int i = 0; i < pStmts.Count; i++) {
- IntPtr pStmt = (IntPtr)pStmts[i];
-
- // If want_results, return the results of the last statement
- // via the SqliteDataReader, and execute but ignore the results
- // of the other statements.
- if (i == pStmts.Count-1 && want_results)
- {
- reader = new SqliteDataReader (this, pStmt, parent_conn.Version);
- break;
- }
-
- // Execute but ignore the results of these statements.
+
+ rows_affected = 0;
+
+ try {
+ while (true) {
+ IntPtr pStmt;
+
+ GetNextStatement(pzTail, out pzTail, out pStmt);
+
+ if (pStmt == IntPtr.Zero)
+ throw new Exception();
+
+ // pzTail is positioned after the last byte in the
+ // statement, which will be the NULL character if
+ // this was the last statement.
+ bool last = Marshal.ReadByte(pzTail) == 0;
+
+ try {
+ if (parent_conn.Version == 3)
+ BindParameters3 (pStmt);
+
+ if (last && want_results)
+ return new SqliteDataReader (this, pStmt, parent_conn.Version);
- if (parent_conn.Version == 3)
- {
- err = Sqlite.sqlite3_step (pStmt);
- }
- else
- {
- int cols;
- IntPtr pazValue = IntPtr.Zero;
- IntPtr pazColName = IntPtr.Zero;
- err = Sqlite.sqlite_step (pStmt, out cols, out pazValue, out pazColName);
- }
- // On error, misuse, or busy, don't bother with the rest of the statements.
- if (err != SqliteError.ROW && err != SqliteError.DONE) break;
- }
- }
- finally
- {
- if (! want_results)
- foreach (IntPtr pStmt in pStmts) {
- if (parent_conn.Version == 3)
- {
- err = Sqlite.sqlite3_finalize (pStmt);
- }
- else
- {
- err = Sqlite.sqlite_finalize (pStmt, out errMsg);
+ ExecuteStatement(pStmt);
+
+ if (last) // rows_affected is only used if !want_results
+ rows_affected = NumChanges ();
+
+ } finally {
+ if (! want_results) {
+ if (parent_conn.Version == 3)
+ Sqlite.sqlite3_finalize (pStmt);
+ else
+ Sqlite.sqlite_finalize (pStmt, out errMsgPtr);
}
}
+
+ if (last) break;
+ }
+ return null;
+ } finally {
parent_conn.EndExec ();
- prepared = false;
+ Marshal.FreeCoTaskMem (psql);
}
-
- if (err != SqliteError.OK &&
- err != SqliteError.DONE &&
- err != SqliteError.ROW)
- {
- if (errMsg != IntPtr.Zero)
- {
- // TODO: Get the message text
- }
- throw new SqliteException (err);
- }
- rows_affected = NumChanges ();
- return reader;
}
-
+
public int LastInsertRowID ()
{
if (parent_conn.Version == 3)
return Sqlite.sqlite3_last_insert_rowid(parent_conn.Handle);
else
return Sqlite.sqlite_last_insert_rowid(parent_conn.Handle);
+ }
+
+ private string GetError3() {
+ return Marshal.PtrToStringUni (Sqlite.sqlite3_errmsg16 (parent_conn.Handle));
}
#endregion
}
Index: beagled/Mono.Data.SqliteClient/SqliteConnection.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/SqliteConnection.cs,v
retrieving revision 1.3
diff -u -B -p -r1.3 SqliteConnection.cs
--- beagled/Mono.Data.SqliteClient/SqliteConnection.cs 26 Jan 2006 19:47:01 -0000 1.3
+++ beagled/Mono.Data.SqliteClient/SqliteConnection.cs 2 Feb 2006 15:20:48 -0000
@@ -31,7 +31,7 @@
using System;
using System.Runtime.InteropServices;
using System.Data;
-using System.Globalization;
+using System.Text;
namespace Mono.Data.SqliteClient
{
@@ -46,7 +46,8 @@ namespace Mono.Data.SqliteClient
private int db_version;
private IntPtr sqlite_handle;
private ConnectionState state;
-
+ private Encoding encoding;
+
#endregion
#region Constructors and destructors
@@ -58,6 +59,7 @@ namespace Mono.Data.SqliteClient
db_version = 2;
state = ConnectionState.Closed;
sqlite_handle = IntPtr.Zero;
+ encoding = null;
}
public SqliteConnection (string connstring) : this ()
@@ -91,6 +93,10 @@ namespace Mono.Data.SqliteClient
get { return state; }
}
+ public Encoding Encoding {
+ get { return encoding; }
+ }
+
internal int Version {
get { return db_version; }
}
@@ -137,9 +143,9 @@ namespace Mono.Data.SqliteClient
if (arg_pieces.Length != 2) {
throw new InvalidOperationException ("Invalid connection string");
}
- string token = arg_pieces[0].ToLower (CultureInfo.InvariantCulture).Trim ();
+ string token = arg_pieces[0].ToLower (System.Globalization.CultureInfo.InvariantCulture).Trim ();
string tvalue = arg_pieces[1].Trim ();
- string tvalue_lc = arg_pieces[1].ToLower (CultureInfo.InvariantCulture).Trim ();
+ string tvalue_lc = arg_pieces[1].ToLower (System.Globalization.CultureInfo.InvariantCulture).Trim ();
if (token == "uri") {
if (tvalue_lc.StartsWith ("file://")) {
db_file = tvalue.Substring (7);
@@ -154,6 +160,8 @@ namespace Mono.Data.SqliteClient
db_mode = Convert.ToInt32 (tvalue);
} else if (token == "version") {
db_version = Convert.ToInt32 (tvalue);
+ } else if (token == "encoding") { // only for sqlite2
+ encoding = Encoding.GetEncoding (tvalue);
}
}
@@ -185,7 +193,7 @@ namespace Mono.Data.SqliteClient
public IDbTransaction BeginTransaction ()
{
if (state != ConnectionState.Open)
- throw new InvalidOperationException("Invalid operation: The connection is close");
+ throw new InvalidOperationException("Invalid operation: The connection is closed");
SqliteTransaction t = new SqliteTransaction();
t.Connection = this;
@@ -197,7 +205,7 @@ namespace Mono.Data.SqliteClient
public IDbTransaction BeginTransaction (IsolationLevel il)
{
- return null;
+ throw new InvalidOperationException();
}
public void Close ()
@@ -241,18 +249,24 @@ namespace Mono.Data.SqliteClient
}
IntPtr errmsg = IntPtr.Zero;
+
+ if (Version == 2){
+ try {
+ sqlite_handle = Sqlite.sqlite_open(db_file, db_mode, out errmsg);
+ if (errmsg != IntPtr.Zero) {
+ string msg = Marshal.PtrToStringAnsi (errmsg);
+ Sqlite.sqliteFree (errmsg);
+ throw new ApplicationException (msg);
+ }
+ } catch (DllNotFoundException dll) {
+ db_version = 3;
+ }
+ }
if (Version == 3) {
- int err = Sqlite.sqlite3_open(db_file, out sqlite_handle);
+ int err = Sqlite.sqlite3_open16(db_file, out sqlite_handle);
if (err == (int)SqliteError.ERROR)
- throw new ApplicationException (Marshal.PtrToStringAnsi( Sqlite.sqlite3_errmsg (sqlite_handle)));
+ throw new ApplicationException (Marshal.PtrToStringUni( Sqlite.sqlite3_errmsg16 (sqlite_handle)));
} else {
- sqlite_handle = Sqlite.sqlite_open(db_file, db_mode, out errmsg);
-
- if (errmsg != IntPtr.Zero) {
- string msg = Marshal.PtrToStringAnsi (errmsg);
- Sqlite.sqliteFree (errmsg);
- throw new ApplicationException (msg);
- }
}
state = ConnectionState.Open;
}
Index: beagled/Mono.Data.SqliteClient/SqliteDataReader.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/SqliteDataReader.cs,v
retrieving revision 1.2
diff -u -B -p -r1.2 SqliteDataReader.cs
--- beagled/Mono.Data.SqliteClient/SqliteDataReader.cs 24 Oct 2005 21:56:28 -0000 1.2
+++ beagled/Mono.Data.SqliteClient/SqliteDataReader.cs 2 Feb 2006 15:20:49 -0000
@@ -6,6 +6,7 @@
//
// Author(s): Vladimir Vukicevic
// Everaldo Canuto
+// Joshua Tauberer
//
// Copyright (C) 2002 Vladimir Vukicevic
//
@@ -45,12 +46,11 @@ namespace Mono.Data.SqliteClient
private SqliteCommand command;
private IntPtr pVm;
private int version;
-
private ArrayList current_row;
-
- private ArrayList columns;
- private Hashtable column_names;
+ private string[] columns;
+ private Hashtable column_names_sens, column_names_insens;
private bool closed;
+ private string[] decltypes;
#endregion
@@ -62,10 +62,10 @@ namespace Mono.Data.SqliteClient
pVm = _pVm;
version = _version;
- current_row = new ArrayList ();
+ current_row = new ArrayList();
- columns = new ArrayList ();
- column_names = new Hashtable ();
+ column_names_sens = new Hashtable ();
+ column_names_insens = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant, CaseInsensitiveComparer.DefaultInvariant);
closed = false;
}
@@ -78,15 +78,17 @@ namespace Mono.Data.SqliteClient
}
public int FieldCount {
- get { return columns.Count; }
+ get { return columns.Length; }
}
public object this[string name] {
- get { return current_row [(int) column_names[name]]; }
+ get {
+ return GetValue (GetOrdinal (name));
+ }
}
public object this[int i] {
- get { return current_row [i]; }
+ get { return GetValue (i); }
}
public bool IsClosed {
@@ -100,82 +102,109 @@ namespace Mono.Data.SqliteClient
#endregion
#region Internal Methods
-
+
internal bool ReadNextColumn ()
{
- int pN = 0;
- IntPtr pazValue = IntPtr.Zero;
- IntPtr pazColName = IntPtr.Zero;
- SqliteError res;
-
- if (version == 3) {
- res = Sqlite.sqlite3_step (pVm);
- pN = Sqlite.sqlite3_column_count (pVm);
- } else
- res = Sqlite.sqlite_step (pVm, out pN, out pazValue, out pazColName);
-
- if (res == SqliteError.DONE) {
- return false;
- }
-
- if (res != SqliteError.ROW)
- throw new SqliteException (res);
-
- // We have some data; lets read it
+ int pN;
+ IntPtr pazValue;
+ IntPtr pazColName;
+ bool first = true;
+
+ int[] declmode = null;
- // If we are reading the first column, populate the column names
- if (column_names.Count == 0) {
+ bool hasdata = command.ExecuteStatement(pVm, out pN, out pazValue, out pazColName);
+
+ // For the first row, get the column information (names and types)
+ if (columns == null) {
+ if (version == 3) {
+ // A decltype might be null if the type is unknown to sqlite.
+ decltypes = new string[pN];
+ declmode = new int[pN]; // 1 == integer, 2 == datetime
+ for (int i = 0; i < pN; i++) {
+ IntPtr decl = Sqlite.sqlite3_column_decltype16 (pVm, i);
+ if (decl != IntPtr.Zero) {
+ decltypes[i] = Marshal.PtrToStringUni (decl).ToLower(System.Globalization.CultureInfo.InvariantCulture);
+ if (decltypes[i] == "int" || decltypes[i] == "integer")
+ declmode[i] = 1;
+ else if (decltypes[i] == "date" || decltypes[i] == "datetime")
+ declmode[i] = 2;
+ }
+ }
+ }
+
+ columns = new string[pN];
for (int i = 0; i < pN; i++) {
- string colName = "";
+ string colName;
if (version == 2) {
IntPtr fieldPtr = (IntPtr)Marshal.ReadInt32 (pazColName, i*IntPtr.Size);
- colName = Marshal.PtrToStringAnsi (fieldPtr);
+ colName = Sqlite.HeapToString (fieldPtr, command.Connection.Encoding);
} else {
- colName = Marshal.PtrToStringAnsi (Sqlite.sqlite3_column_name (pVm, i));
+ colName = Marshal.PtrToStringUni (Sqlite.sqlite3_column_name16 (pVm, i));
}
- columns.Add (colName);
- column_names [colName] = i;
+ columns[i] = colName;
+ column_names_sens [colName] = i;
+ column_names_insens [colName] = i;
}
}
- // Now read the actual data
- current_row.Clear ();
+ if (!hasdata)
+ return false;
+
+ current_row.Clear();
for (int i = 0; i < pN; i++) {
- string colData = "";
if (version == 2) {
IntPtr fieldPtr = (IntPtr)Marshal.ReadInt32 (pazValue, i*IntPtr.Size);
- colData = Marshal.PtrToStringAnsi (fieldPtr);
- current_row.Add (Marshal.PtrToStringAnsi (fieldPtr));
+ current_row.Add (Sqlite.HeapToString (fieldPtr, command.Connection.Encoding));
} else {
switch (Sqlite.sqlite3_column_type (pVm, i)) {
- case 1:
- Int64 sqliteint64 = Sqlite.sqlite3_column_int64 (pVm, i);
- current_row.Add (sqliteint64.ToString ());
- break;
- case 2:
- double sqlitedouble = Sqlite.sqlite3_column_double (pVm, i);
- current_row.Add (sqlitedouble.ToString ());
- break;
- case 3:
- colData = Marshal.PtrToStringAnsi (Sqlite.sqlite3_column_text (pVm, i));
- current_row.Add (colData);
- break;
- case 4:
- int blobbytes = Sqlite.sqlite3_column_bytes (pVm, i);
- IntPtr blobptr = Sqlite.sqlite3_column_blob (pVm, i);
- byte[] blob = new byte[blobbytes];
- Marshal.Copy (blobptr, blob, 0, blobbytes);
- current_row.Add (blob);
- break;
- case 5:
- current_row.Add (null);
- break;
- default:
- throw new ApplicationException ("FATAL: Unknown sqlite3_column_type");
+ case 1:
+ long val = Sqlite.sqlite3_column_int64 (pVm, i);
+
+ // If the column was declared as an 'int' or 'integer', let's play
+ // nice and return an int (version 3 only).
+ if (declmode[i] == 1 && val >= int.MinValue && val <= int.MaxValue)
+ current_row.Add ((int)val);
+
+ // Or if it was declared a date or datetime, do the reverse of what we
+ // do for DateTime parameters.
+ else if (declmode[i] == 2)
+ current_row.Add (DateTime.FromFileTime(val));
+
+ else
+ current_row.Add (val);
+
+ break;
+ case 2:
+ current_row.Add (Sqlite.sqlite3_column_double (pVm, i));
+ break;
+ case 3:
+ string strval = Marshal.PtrToStringUni (Sqlite.sqlite3_column_text16 (pVm, i));
+ current_row.Add (Marshal.PtrToStringUni (Sqlite.sqlite3_column_text16 (pVm, i)));
+
+ // If the column was declared as a 'date' or 'datetime', let's play
+ // nice and return a DateTime (version 3 only).
+ if (declmode[i] == 2)
+ current_row.Add (DateTime.Parse (strval));
+
+ else
+ current_row.Add (strval);
+
+ break;
+ case 4:
+ int blobbytes = Sqlite.sqlite3_column_bytes16 (pVm, i);
+ IntPtr blobptr = Sqlite.sqlite3_column_blob (pVm, i);
+ byte[] blob = new byte[blobbytes];
+ Marshal.Copy (blobptr, blob, 0, blobbytes);
+ current_row.Add (blob);
+ break;
+ case 5:
+ current_row.Add (null);
+ break;
+ default:
+ throw new ApplicationException ("FATAL: Unknown sqlite3_column_type");
}
- }
+ }
}
-
return true;
}
@@ -277,7 +306,7 @@ namespace Mono.Data.SqliteClient
public bool Read ()
{
- return ReadNextColumn ();
+ return NextResult ();
}
#endregion
@@ -286,12 +315,12 @@ namespace Mono.Data.SqliteClient
public bool GetBoolean (int i)
{
- return Convert.ToBoolean ((string) current_row [i]);
+ return Convert.ToBoolean (current_row[i]);
}
public byte GetByte (int i)
{
- return Convert.ToByte ((string) current_row [i]);
+ return Convert.ToByte (current_row[i]);
}
public long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferOffset, int length)
@@ -301,7 +330,7 @@ namespace Mono.Data.SqliteClient
public char GetChar (int i)
{
- return Convert.ToChar ((string) current_row [i]);
+ return Convert.ToChar (current_row[i]);
}
public long GetChars (int i, long fieldOffset, char[] buffer, int bufferOffset, int length)
@@ -316,32 +345,37 @@ namespace Mono.Data.SqliteClient
public string GetDataTypeName (int i)
{
+ if (decltypes != null && decltypes[i] != null)
+ return decltypes[i];
return "text"; // SQL Lite data type
}
public DateTime GetDateTime (int i)
{
- return Convert.ToDateTime ((string) current_row [i]);
+ return Convert.ToDateTime (current_row[i]);
}
public decimal GetDecimal (int i)
{
- return Convert.ToDecimal ((string) current_row [i]);
+ return Convert.ToDecimal (current_row[i]);
}
public double GetDouble (int i)
{
- return Convert.ToDouble ((string) current_row [i]);
+ return Convert.ToDouble (current_row[i]);
}
public Type GetFieldType (int i)
{
- return System.Type.GetType ("System.String"); // .NET data type
+ if (current_row == null)
+ return null;
+
+ return current_row [i].GetType ();
}
public float GetFloat (int i)
{
- return Convert.ToSingle ((string) current_row [i]);
+ return Convert.ToSingle (current_row[i]);
}
public Guid GetGuid (int i)
@@ -351,45 +385,50 @@ namespace Mono.Data.SqliteClient
public short GetInt16 (int i)
{
- return Convert.ToInt16 ((string) current_row [i]);
+ return Convert.ToInt16 (current_row[i]);
}
public int GetInt32 (int i)
{
- return Convert.ToInt32 ((string) current_row [i]);
+ return Convert.ToInt32 (current_row[i]);
}
public long GetInt64 (int i)
{
- return Convert.ToInt64 ((string) current_row [i]);
+ return Convert.ToInt64 (current_row[i]);
}
public string GetName (int i)
{
- return (string) columns[i];
+ return columns[i];
}
public int GetOrdinal (string name)
{
- return (int) column_names[name];
+ object v = column_names_sens[name];
+ if (v == null)
+ v = column_names_insens[name];
+ if (v == null)
+ throw new ArgumentException("Column does not exist.");
+ return (int) v;
}
public string GetString (int i)
{
- return (string) current_row [i];
+ return current_row[i].ToString();
}
public object GetValue (int i)
{
- return current_row [i];
+ return current_row[i];
}
public int GetValues (object[] values)
{
- int num_to_fill = System.Math.Min (values.Length, columns.Count);
+ int num_to_fill = System.Math.Min (values.Length, columns.Length);
for (int i = 0; i < num_to_fill; i++) {
- if (current_row [i] != null) {
- values[i] = current_row [i];
+ if (current_row[i] != null) {
+ values[i] = current_row[i];
} else {
values[i] = DBNull.Value;
}
@@ -399,7 +438,7 @@ namespace Mono.Data.SqliteClient
public bool IsDBNull (int i)
{
- return current_row [i] == null;
+ return (current_row[i] == null);
}
#endregion
Index: beagled/Mono.Data.SqliteClient/SqliteParameter.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/SqliteParameter.cs,v
retrieving revision 1.1
diff -u -B -p -r1.1 SqliteParameter.cs
--- beagled/Mono.Data.SqliteClient/SqliteParameter.cs 7 Jun 2005 20:50:14 -0000 1.1
+++ beagled/Mono.Data.SqliteClient/SqliteParameter.cs 2 Feb 2006 15:20:49 -0000
@@ -59,26 +59,26 @@ namespace Mono.Data.SqliteClient
direction = ParameterDirection.Input;
}
- public SqliteParameter (string name_in, DbType type_in)
+ public SqliteParameter (string name, DbType type)
{
- name = name_in;
- type = type_in;
+ this.name = name;
+ this.type = type;
}
- public SqliteParameter (string name_in, object param_value_in)
+ public SqliteParameter (string name, object value)
{
- name = name_in;
+ this.name = name;
type = DbType.String;
- param_value = param_value_in;
+ param_value = value;
direction = ParameterDirection.Input;
}
- public SqliteParameter (string name_in, DbType type_in, int size_in) : this (name_in, type_in)
+ public SqliteParameter (string name, DbType type, int size) : this (name, type)
{
- size = size_in;
+ this.size = size;
}
- public SqliteParameter (string name_in, DbType type_in, int size, string src_column) : this (name_in ,type_in)
+ public SqliteParameter (string name, DbType type, int size, string src_column) : this (name ,type, size)
{
source_column = src_column;
}
Index: beagled/Mono.Data.SqliteClient/SqliteParameterCollection.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Mono.Data.SqliteClient/SqliteParameterCollection.cs,v
retrieving revision 1.2
diff -u -B -p -r1.2 SqliteParameterCollection.cs
--- beagled/Mono.Data.SqliteClient/SqliteParameterCollection.cs 24 Oct 2005 21:56:28 -0000 1.2
+++ beagled/Mono.Data.SqliteClient/SqliteParameterCollection.cs 2 Feb 2006 15:20:49 -0000
@@ -112,12 +112,19 @@ namespace Mono.Data.SqliteClient
}
}
+ private bool isPrefixed (string parameterName)
+ {
+ return parameterName.Length > 1 && (parameterName[0] == ':' || parameterName[0] == '$');
+ }
+
public SqliteParameter this[string parameterName]
{
get
{
if (this.Contains(parameterName))
return this[(int) named_param_hash[parameterName]];
+ else if (isPrefixed(parameterName) && this.Contains(parameterName.Substring(1)))
+ return this[(int) named_param_hash[parameterName.Substring(1)]];
else
throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
@@ -125,6 +132,8 @@ namespace Mono.Data.SqliteClient
{
if (this.Contains(parameterName))
numeric_param_list[(int) named_param_hash[parameterName]] = value;
+ else if (parameterName.Length > 1 && this.Contains(parameterName.Substring(1)))
+ numeric_param_list[(int) named_param_hash[parameterName.Substring(1)]] = value;
else
throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}