2 // Mono.Data.SqliteClient.Sqlite.cs
4 // Provides C# bindings to the library sqlite.dll
6 // Everaldo Canuto <everaldo_canuto@yahoo.com.br>
7 // Chris Turchin <chris@turchin.net>
8 // Jeroen Zwartepoorte <jeroen@xs4all.nl>
9 // Thomas Zoechling <thomas.zoechling@gmx.at>
11 // Copyright (C) 2004 Everaldo Canuto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Security
;
35 using System
.Runtime
.InteropServices
;
38 namespace Mono
.Data
.SqliteClient
41 /// Represents the return values for sqlite_exec() and sqlite_step()
43 internal enum SqliteError
: int {
44 /// <value>Successful result</value>
46 /// <value>SQL error or missing database</value>
48 /// <value>An internal logic error in SQLite</value>
50 /// <value>Access permission denied</value>
52 /// <value>Callback routine requested an abort</value>
54 /// <value>The database file is locked</value>
56 /// <value>A table in the database is locked</value>
58 /// <value>A malloc() failed</value>
60 /// <value>Attempt to write a readonly database</value>
62 /// <value>Operation terminated by public const int interrupt()</value>
64 /// <value>Some kind of disk I/O error occurred</value>
66 /// <value>The database disk image is malformed</value>
68 /// <value>(Internal Only) Table or record not found</value>
70 /// <value>Insertion failed because database is full</value>
72 /// <value>Unable to open the database file</value>
74 /// <value>Database lock protocol error</value>
76 /// <value>(Internal Only) Database table is empty</value>
78 /// <value>The database schema changed</value>
80 /// <value>Too much data for one row of a table</value>
82 /// <value>Abort due to contraint violation</value>
84 /// <value>Data type mismatch</value>
86 /// <value>Library used incorrectly</value>
88 /// <value>Uses OS features not supported on host</value>
90 /// <value>Authorization denied</value>
92 /// <value>Auxiliary database format error</value>
94 /// <value>2nd parameter to sqlite_bind out of range</value>
96 /// <value>File opened that is not a database file</value>
98 /// <value>sqlite_step() has another row ready</value>
100 /// <value>sqlite_step() has finished executing</value>
105 /// Provides the core of C# bindings to the library sqlite.dll
107 internal sealed class Sqlite
{
109 #region PInvoke Functions
111 [DllImport("sqlite")]
112 internal static extern IntPtr
sqlite_open (string dbname
, int db_mode
, out IntPtr errstr
);
114 [DllImport("sqlite")]
115 internal static extern void sqlite_close (IntPtr sqlite_handle
);
117 [DllImport("sqlite")]
118 internal static extern int sqlite_changes (IntPtr handle
);
120 [DllImport("sqlite")]
121 internal static extern int sqlite_last_insert_rowid (IntPtr sqlite_handle
);
123 [DllImport ("sqlite")]
124 internal static extern void sqliteFree (IntPtr ptr
);
126 [DllImport ("sqlite")]
127 internal static extern SqliteError
sqlite_compile (IntPtr sqlite_handle
, IntPtr zSql
, out IntPtr pzTail
, out IntPtr pVm
, out IntPtr errstr
);
129 [DllImport ("sqlite")]
130 internal static extern SqliteError
sqlite_step (IntPtr pVm
, out int pN
, out IntPtr pazValue
, out IntPtr pazColName
);
132 [DllImport ("sqlite")]
133 internal static extern SqliteError
sqlite_finalize (IntPtr pVm
, out IntPtr pzErrMsg
);
135 [DllImport ("sqlite")]
136 internal static extern SqliteError
sqlite_exec (IntPtr handle
, string sql
, IntPtr callback
, IntPtr user_data
, out IntPtr errstr_ptr
);
138 [DllImport("sqlite3", CharSet
= CharSet
.Unicode
)]
139 internal static extern int sqlite3_open16 (string dbname
, out IntPtr handle
);
141 [DllImport("sqlite3")]
142 internal static extern void sqlite3_close (IntPtr sqlite_handle
);
144 [DllImport("sqlite3")]
145 internal static extern IntPtr
sqlite3_errmsg16 (IntPtr sqlite_handle
);
147 [DllImport("sqlite3")]
148 internal static extern int sqlite3_changes (IntPtr handle
);
150 [DllImport("sqlite3")]
151 internal static extern int sqlite3_last_insert_rowid (IntPtr sqlite_handle
);
153 [DllImport ("sqlite3")]
154 internal static extern SqliteError
sqlite3_prepare16 (IntPtr sqlite_handle
, IntPtr zSql
, int zSqllen
, out IntPtr pVm
, out IntPtr pzTail
);
156 [DllImport ("sqlite3")]
157 internal static extern SqliteError
sqlite3_step (IntPtr pVm
);
159 [DllImport ("sqlite3")]
160 internal static extern SqliteError
sqlite3_finalize (IntPtr pVm
);
162 [DllImport ("sqlite3")]
163 internal static extern SqliteError
sqlite3_exec (IntPtr handle
, string sql
, IntPtr callback
, IntPtr user_data
, out IntPtr errstr_ptr
);
165 [DllImport ("sqlite3")]
166 internal static extern IntPtr
sqlite3_column_name16 (IntPtr pVm
, int col
);
168 [DllImport ("sqlite3")]
169 internal static extern IntPtr
sqlite3_column_text16 (IntPtr pVm
, int col
);
171 [DllImport ("sqlite3")]
172 internal static extern IntPtr
sqlite3_column_blob (IntPtr pVm
, int col
);
174 [DllImport ("sqlite3")]
175 internal static extern int sqlite3_column_bytes16 (IntPtr pVm
, int col
);
177 [DllImport ("sqlite3")]
178 internal static extern int sqlite3_column_count (IntPtr pVm
);
180 [DllImport ("sqlite3")]
181 internal static extern int sqlite3_column_type (IntPtr pVm
, int col
);
183 [DllImport ("sqlite3")]
184 internal static extern Int64
sqlite3_column_int64 (IntPtr pVm
, int col
);
186 [DllImport ("sqlite3")]
187 internal static extern double sqlite3_column_double (IntPtr pVm
, int col
);
189 [DllImport ("sqlite3")]
190 internal static extern IntPtr
sqlite3_column_decltype16 (IntPtr pVm
, int col
);
192 [DllImport ("sqlite3")]
193 internal static extern int sqlite3_bind_parameter_count (IntPtr pStmt
);
195 [DllImport ("sqlite3")]
196 internal static extern IntPtr
sqlite3_bind_parameter_name (IntPtr pStmt
, int n
); // UTF-8 encoded return
198 [DllImport ("sqlite3")]
199 internal static extern SqliteError
sqlite3_bind_blob (IntPtr pStmt
, int n
, byte[] blob
, int length
, IntPtr freetype
);
201 [DllImport ("sqlite3")]
202 internal static extern SqliteError
sqlite3_bind_double (IntPtr pStmt
, int n
, double value);
204 [DllImport ("sqlite3")]
205 internal static extern SqliteError
sqlite3_bind_int (IntPtr pStmt
, int n
, int value);
207 [DllImport ("sqlite3")]
208 internal static extern SqliteError
sqlite3_bind_int64 (IntPtr pStmt
, int n
, long value);
210 [DllImport ("sqlite3")]
211 internal static extern SqliteError
sqlite3_bind_null (IntPtr pStmt
, int n
);
213 [DllImport ("sqlite3", CharSet
= CharSet
.Unicode
)]
214 internal static extern SqliteError
sqlite3_bind_text16 (IntPtr pStmt
, int n
, string value, int length
, IntPtr freetype
);
218 // These are adapted from Mono.Unix. When encoding is null,
219 // use Ansi encoding, which is a superset of the default
220 // expected encoding (ISO-8859-1).
222 public static IntPtr
StringToHeap (string s
, Encoding encoding
)
224 if (encoding
== null)
225 return Marshal
.StringToCoTaskMemAnsi (s
);
227 int min_byte_count
= encoding
.GetMaxByteCount(1);
228 char[] copy
= s
.ToCharArray ();
229 byte[] marshal
= new byte [encoding
.GetByteCount (copy
) + min_byte_count
];
231 int bytes_copied
= encoding
.GetBytes (copy
, 0, copy
.Length
, marshal
, 0);
233 if (bytes_copied
!= (marshal
.Length
-min_byte_count
))
234 throw new NotSupportedException ("encoding.GetBytes() doesn't equal encoding.GetByteCount()!");
236 IntPtr mem
= Marshal
.AllocCoTaskMem (marshal
.Length
);
237 if (mem
== IntPtr
.Zero
)
238 throw new OutOfMemoryException ();
242 Marshal
.Copy (marshal
, 0, mem
, marshal
.Length
);
247 Marshal
.FreeCoTaskMem (mem
);
253 public static unsafe string HeapToString (IntPtr p
, Encoding encoding
)
255 if (encoding
== null)
256 return Marshal
.PtrToStringAnsi (p
);
258 if (p
== IntPtr
.Zero
)
261 // This assumes a single byte terminates the string.
264 while (Marshal
.ReadByte (p
, len
) != 0)
267 string s
= new string ((sbyte*) p
, 0, len
, encoding
);
269 while (len
> 0 && s
[len
-1] == 0)
273 return s
.Substring (0, len
);