2 // Mono.Data.SqliteClient.SqliteConnection.cs
4 // Represents an open connection to a Sqlite database file.
6 // Author(s): Vladimir Vukicevic <vladimir@pobox.com>
7 // Everaldo Canuto <everaldo_canuto@yahoo.com.br>
9 // Copyright (C) 2002 Vladimir Vukicevic
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System
.Runtime
.InteropServices
;
36 namespace Mono
.Data
.SqliteClient
38 public class SqliteConnection
: IDbConnection
43 private string conn_str
;
44 private string db_file
;
46 private int db_version
;
47 private IntPtr sqlite_handle
;
48 private ConnectionState state
;
49 private Encoding encoding
;
53 #region Constructors and destructors
55 public SqliteConnection ()
60 state
= ConnectionState
.Closed
;
61 sqlite_handle
= IntPtr
.Zero
;
65 public SqliteConnection (string connstring
) : this ()
67 ConnectionString
= connstring
;
70 public void Dispose ()
79 public string ConnectionString
{
80 get { return conn_str; }
81 set { SetConnectionString(value); }
84 public int ConnectionTimeout
{
88 public string Database
{
89 get { return db_file; }
92 public ConnectionState State
{
96 public Encoding Encoding
{
97 get { return encoding; }
100 internal int Version
{
101 get { return db_version; }
104 internal IntPtr Handle
{
105 get { return sqlite_handle; }
108 public int LastInsertRowId
{
111 return Sqlite
.sqlite3_last_insert_rowid (Handle
);
113 return Sqlite
.sqlite_last_insert_rowid (Handle
);
119 #region Private Methods
121 private void SetConnectionString(string connstring
)
123 if (connstring
== null) {
129 if (connstring
!= conn_str
) {
131 conn_str
= connstring
;
136 string[] conn_pieces
= connstring
.Split (',');
137 for (int i
= 0; i
< conn_pieces
.Length
; i
++) {
138 string piece
= conn_pieces
[i
].Trim ();
139 if (piece
.Length
== 0) { // ignore empty elements
142 string[] arg_pieces
= piece
.Split ('=');
143 if (arg_pieces
.Length
!= 2) {
144 throw new InvalidOperationException ("Invalid connection string");
146 string token
= arg_pieces
[0].ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
).Trim ();
147 string tvalue
= arg_pieces
[1].Trim ();
148 string tvalue_lc
= arg_pieces
[1].ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
).Trim ();
149 if (token
== "uri") {
150 if (tvalue_lc
.StartsWith ("file://")) {
151 db_file
= tvalue
.Substring (7);
152 } else if (tvalue_lc
.StartsWith ("file:")) {
153 db_file
= tvalue
.Substring (5);
154 } else if (tvalue_lc
.StartsWith ("/")) {
157 throw new InvalidOperationException ("Invalid connection string: invalid URI");
159 } else if (token
== "mode") {
160 db_mode
= Convert
.ToInt32 (tvalue
);
161 } else if (token
== "version") {
162 db_version
= Convert
.ToInt32 (tvalue
);
163 } else if (token
== "encoding") { // only for sqlite2
164 encoding
= Encoding
.GetEncoding (tvalue
);
168 if (db_file
== null) {
169 throw new InvalidOperationException ("Invalid connection string: no URI");
176 #region Internal Methods
178 internal void StartExec ()
181 state
= ConnectionState
.Executing
;
184 internal void EndExec ()
186 state
= ConnectionState
.Open
;
191 #region Public Methods
193 public IDbTransaction
BeginTransaction ()
195 if (state
!= ConnectionState
.Open
)
196 throw new InvalidOperationException("Invalid operation: The connection is closed");
198 SqliteTransaction t
= new SqliteTransaction();
200 SqliteCommand cmd
= this.CreateCommand();
201 cmd
.CommandText
= "BEGIN";
202 cmd
.ExecuteNonQuery();
206 public IDbTransaction
BeginTransaction (IsolationLevel il
)
208 throw new InvalidOperationException();
213 if (state
!= ConnectionState
.Open
) {
217 state
= ConnectionState
.Closed
;
220 Sqlite
.sqlite3_close (sqlite_handle
);
222 Sqlite
.sqlite_close(sqlite_handle
);
223 sqlite_handle
= IntPtr
.Zero
;
226 public void ChangeDatabase (string databaseName
)
228 throw new NotImplementedException ();
231 IDbCommand IDbConnection
.CreateCommand ()
233 return CreateCommand ();
236 public SqliteCommand
CreateCommand ()
238 return new SqliteCommand (null, this);
243 if (conn_str
== null) {
244 throw new InvalidOperationException ("No database specified");
247 if (state
!= ConnectionState
.Closed
) {
251 IntPtr errmsg
= IntPtr
.Zero
;
255 sqlite_handle
= Sqlite
.sqlite_open(db_file
, db_mode
, out errmsg
);
256 if (errmsg
!= IntPtr
.Zero
) {
257 string msg
= Marshal
.PtrToStringAnsi (errmsg
);
258 Sqlite
.sqliteFree (errmsg
);
259 throw new ApplicationException (msg
);
261 } catch (DllNotFoundException dll
) {
266 int err
= Sqlite
.sqlite3_open16(db_file
, out sqlite_handle
);
267 if (err
== (int)SqliteError
.ERROR
)
268 throw new ApplicationException (Marshal
.PtrToStringUni( Sqlite
.sqlite3_errmsg16 (sqlite_handle
)));
271 state
= ConnectionState
.Open
;