New test.
[mono.git] / mcs / class / Mono.Data.SqliteClient / Mono.Data.SqliteClient / SqliteConnection.cs
index 4f785077cf681e5a3bf7e51e4b195d958a5217e6..1daa8fd05301855d1b40fad8bd0128f543fe71c9 100644 (file)
@@ -31,6 +31,7 @@
 using System;
 using System.Runtime.InteropServices;
 using System.Data;
+using System.Text;
 
 namespace Mono.Data.SqliteClient
 {
@@ -45,7 +46,9 @@ namespace Mono.Data.SqliteClient
                private int db_version;
                private IntPtr sqlite_handle;
                private ConnectionState state;
-               
+               private Encoding encoding;
+               private int busy_timeout;
+
                #endregion
 
                #region Constructors and destructors
@@ -57,6 +60,8 @@ namespace Mono.Data.SqliteClient
                        db_version = 2;
                        state = ConnectionState.Closed;
                        sqlite_handle = IntPtr.Zero;
+                       encoding = null;
+                       busy_timeout = 0;
                }
                
                public SqliteConnection (string connstring) : this ()
@@ -90,7 +95,11 @@ namespace Mono.Data.SqliteClient
                        get { return state; }
                }
                
-               internal int Version {
+               public Encoding Encoding {
+                       get { return encoding; }
+               }
+
+               public int Version {
                        get { return db_version; }
                }
 
@@ -101,11 +110,20 @@ namespace Mono.Data.SqliteClient
                public int LastInsertRowId {
                        get {
                                if (Version == 3)
-                                       return Sqlite.sqlite3_last_insert_rowid (Handle);
+                                       return (int)Sqlite.sqlite3_last_insert_rowid (Handle);
                                else
                                        return Sqlite.sqlite_last_insert_rowid (Handle);
                        }
                }
+
+               public int BusyTimeout {
+                       get {
+                               return busy_timeout;  
+                       }
+                       set {
+                               busy_timeout = value < 0 ? 0 : value;
+                       }
+               }
                
                #endregion
 
@@ -127,19 +145,20 @@ namespace Mono.Data.SqliteClient
                                db_mode = 0644;
                                
                                string[] conn_pieces = connstring.Split (',');
-                                for (int i = 0; i < conn_pieces.Length; i++) {
+                               for (int i = 0; i < conn_pieces.Length; i++) {
                                        string piece = conn_pieces [i].Trim ();
-                                        if (piece.Length == 0) { // ignore empty elements
+                                       if (piece.Length == 0) { // ignore empty elements
                                                 continue;
-                                        }
+                                       }
                                        string[] arg_pieces = piece.Split ('=');
                                        if (arg_pieces.Length != 2) {
                                                throw new InvalidOperationException ("Invalid connection string");
                                        }
-                                       string token = arg_pieces[0].ToLower ().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 ().Trim ();
-                                       if (token == "uri") {
+                                       string tvalue_lc = arg_pieces[1].ToLower (System.Globalization.CultureInfo.InvariantCulture).Trim ();
+                                       switch (token) {
+                                       case "uri": 
                                                if (tvalue_lc.StartsWith ("file://")) {
                                                        db_file = tvalue.Substring (7);
                                                } else if (tvalue_lc.StartsWith ("file:")) {
@@ -149,10 +168,23 @@ namespace Mono.Data.SqliteClient
                                                } else {
                                                        throw new InvalidOperationException ("Invalid connection string: invalid URI");
                                                }
-                                       } else if (token == "mode") {
+                                               break;
+
+                                       case "mode": 
                                                db_mode = Convert.ToInt32 (tvalue);
-                                       } else if (token == "version") {
+                                               break;
+
+                                       case "version":
                                                db_version = Convert.ToInt32 (tvalue);
+                                               break;
+
+                                       case "encoding": // only for sqlite2
+                                               encoding = Encoding.GetEncoding (tvalue);
+                                               break;
+
+                                       case "busy_timeout":
+                                               busy_timeout = Convert.ToInt32 (tvalue);
+                                               break;
                                        }
                                }
                                
@@ -184,7 +216,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;
@@ -196,7 +228,7 @@ namespace Mono.Data.SqliteClient
                
                public IDbTransaction BeginTransaction (IsolationLevel il)
                {
-                       return null;
+                       throw new InvalidOperationException();
                }
                
                public void Close ()
@@ -240,18 +272,28 @@ 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 (busy_timeout != 0)
+                                       Sqlite.sqlite_busy_timeout (sqlite_handle, busy_timeout);
+                       }
                        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 (Sqlite.sqlite3_errmsg (sqlite_handle));
+                                       throw new ApplicationException (Marshal.PtrToStringUni( Sqlite.sqlite3_errmsg16 (sqlite_handle)));
+                               if (busy_timeout != 0)
+                                       Sqlite.sqlite3_busy_timeout (sqlite_handle, busy_timeout);
                        } 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;
                }