Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Mono.Data.SqliteClient / SqliteConnection.cs
blob4f785077cf681e5a3bf7e51e4b195d958a5217e6
1 //
2 // Mono.Data.SqliteClient.SqliteConnection.cs
3 //
4 // Represents an open connection to a Sqlite database file.
5 //
6 // Author(s): Vladimir Vukicevic <vladimir@pobox.com>
7 // Everaldo Canuto <everaldo_canuto@yahoo.com.br>
8 //
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:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
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.
31 using System;
32 using System.Runtime.InteropServices;
33 using System.Data;
35 namespace Mono.Data.SqliteClient
37 public class SqliteConnection : IDbConnection
40 #region Fields
42 private string conn_str;
43 private string db_file;
44 private int db_mode;
45 private int db_version;
46 private IntPtr sqlite_handle;
47 private ConnectionState state;
49 #endregion
51 #region Constructors and destructors
53 public SqliteConnection ()
55 db_file = null;
56 db_mode = 0644;
57 db_version = 2;
58 state = ConnectionState.Closed;
59 sqlite_handle = IntPtr.Zero;
62 public SqliteConnection (string connstring) : this ()
64 ConnectionString = connstring;
67 public void Dispose ()
69 Close ();
72 #endregion
74 #region Properties
76 public string ConnectionString {
77 get { return conn_str; }
78 set { SetConnectionString(value); }
81 public int ConnectionTimeout {
82 get { return 0; }
85 public string Database {
86 get { return db_file; }
89 public ConnectionState State {
90 get { return state; }
93 internal int Version {
94 get { return db_version; }
97 internal IntPtr Handle {
98 get { return sqlite_handle; }
101 public int LastInsertRowId {
102 get {
103 if (Version == 3)
104 return Sqlite.sqlite3_last_insert_rowid (Handle);
105 else
106 return Sqlite.sqlite_last_insert_rowid (Handle);
110 #endregion
112 #region Private Methods
114 private void SetConnectionString(string connstring)
116 if (connstring == null) {
117 Close ();
118 conn_str = null;
119 return;
122 if (connstring != conn_str) {
123 Close ();
124 conn_str = connstring;
126 db_file = null;
127 db_mode = 0644;
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
133 continue;
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 ("/")) {
148 db_file = tvalue;
149 } else {
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");
165 #endregion
167 #region Internal Methods
169 internal void StartExec ()
171 // use a mutex here
172 state = ConnectionState.Executing;
175 internal void EndExec ()
177 state = ConnectionState.Open;
180 #endregion
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();
190 t.Connection = this;
191 SqliteCommand cmd = this.CreateCommand();
192 cmd.CommandText = "BEGIN";
193 cmd.ExecuteNonQuery();
194 return t;
197 public IDbTransaction BeginTransaction (IsolationLevel il)
199 return null;
202 public void Close ()
204 if (state != ConnectionState.Open) {
205 return;
208 state = ConnectionState.Closed;
210 if (Version == 3)
211 Sqlite.sqlite3_close (sqlite_handle);
212 else
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);
232 public void Open ()
234 if (conn_str == null) {
235 throw new InvalidOperationException ("No database specified");
238 if (state != ConnectionState.Closed) {
239 return;
242 IntPtr errmsg = IntPtr.Zero;
243 if (Version == 3) {
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));
247 } else {
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;
259 #endregion