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
;
35 namespace Mono
.Data
.SqliteClient
37 public class SqliteConnection
: IDbConnection
42 private string conn_str
;
43 private string db_file
;
45 private int db_version
;
46 private IntPtr sqlite_handle
;
47 private ConnectionState state
;
51 #region Constructors and destructors
53 public SqliteConnection ()
58 state
= ConnectionState
.Closed
;
59 sqlite_handle
= IntPtr
.Zero
;
62 public SqliteConnection (string connstring
) : this ()
64 ConnectionString
= connstring
;
67 public void Dispose ()
76 public string ConnectionString
{
77 get { return conn_str; }
78 set { SetConnectionString(value); }
81 public int ConnectionTimeout
{
85 public string Database
{
86 get { return db_file; }
89 public ConnectionState State
{
93 internal int Version
{
94 get { return db_version; }
97 internal IntPtr Handle
{
98 get { return sqlite_handle; }
101 public int LastInsertRowId
{
104 return Sqlite
.sqlite3_last_insert_rowid (Handle
);
106 return Sqlite
.sqlite_last_insert_rowid (Handle
);
112 #region Private Methods
114 private void SetConnectionString(string connstring
)
116 if (connstring
== null) {
122 if (connstring
!= conn_str
) {
124 conn_str
= connstring
;
129 string[] conn_pieces
= connstring
.Split (',');
130 for (int i
= 0; i
< conn_pieces
.Length
; i
++) {
131 string piece
= conn_pieces
[i
].Trim ();
132 if (piece
.Length
== 0) { // ignore empty elements
135 string[] arg_pieces
= piece
.Split ('=');
136 if (arg_pieces
.Length
!= 2) {
137 throw new InvalidOperationException ("Invalid connection string");
139 string token
= arg_pieces
[0].ToLower ().Trim ();
140 string tvalue
= arg_pieces
[1].Trim ();
141 string tvalue_lc
= arg_pieces
[1].ToLower ().Trim ();
142 if (token
== "uri") {
143 if (tvalue_lc
.StartsWith ("file://")) {
144 db_file
= tvalue
.Substring (7);
145 } else if (tvalue_lc
.StartsWith ("file:")) {
146 db_file
= tvalue
.Substring (5);
147 } else if (tvalue_lc
.StartsWith ("/")) {
150 throw new InvalidOperationException ("Invalid connection string: invalid URI");
152 } else if (token
== "mode") {
153 db_mode
= Convert
.ToInt32 (tvalue
);
154 } else if (token
== "version") {
155 db_version
= Convert
.ToInt32 (tvalue
);
159 if (db_file
== null) {
160 throw new InvalidOperationException ("Invalid connection string: no URI");
167 #region Internal Methods
169 internal void StartExec ()
172 state
= ConnectionState
.Executing
;
175 internal void EndExec ()
177 state
= ConnectionState
.Open
;
182 #region Public Methods
184 public IDbTransaction
BeginTransaction ()
186 if (state
!= ConnectionState
.Open
)
187 throw new InvalidOperationException("Invalid operation: The connection is close");
189 SqliteTransaction t
= new SqliteTransaction();
191 SqliteCommand cmd
= this.CreateCommand();
192 cmd
.CommandText
= "BEGIN";
193 cmd
.ExecuteNonQuery();
197 public IDbTransaction
BeginTransaction (IsolationLevel il
)
204 if (state
!= ConnectionState
.Open
) {
208 state
= ConnectionState
.Closed
;
211 Sqlite
.sqlite3_close (sqlite_handle
);
213 Sqlite
.sqlite_close(sqlite_handle
);
214 sqlite_handle
= IntPtr
.Zero
;
217 public void ChangeDatabase (string databaseName
)
219 throw new NotImplementedException ();
222 IDbCommand IDbConnection
.CreateCommand ()
224 return CreateCommand ();
227 public SqliteCommand
CreateCommand ()
229 return new SqliteCommand (null, this);
234 if (conn_str
== null) {
235 throw new InvalidOperationException ("No database specified");
238 if (state
!= ConnectionState
.Closed
) {
242 IntPtr errmsg
= IntPtr
.Zero
;
244 int err
= Sqlite
.sqlite3_open(db_file
, out sqlite_handle
);
245 if (err
== (int)SqliteError
.ERROR
)
246 throw new ApplicationException (Sqlite
.sqlite3_errmsg (sqlite_handle
));
248 sqlite_handle
= Sqlite
.sqlite_open(db_file
, db_mode
, out errmsg
);
250 if (errmsg
!= IntPtr
.Zero
) {
251 string msg
= Marshal
.PtrToStringAnsi (errmsg
);
252 Sqlite
.sqliteFree (errmsg
);
253 throw new ApplicationException (msg
);
256 state
= ConnectionState
.Open
;