2010-06-21 Marek Habersack <mhabersack@novell.com>
[mcs.git] / class / Mono.Data.Sqlite / Mono.Data.Sqlite / Sqlite.cs
blobece0ec2b4e09e265294f41bf6a7c481c9d6d452e
1 //
2 // Mono.Data.Sqlite.Sqlite.cs
3 //
4 // Provides C# bindings to the library sqlite.dll
5 //
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:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
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.
32 #if !NET_2_0
33 using System;
34 using System.Security;
35 using System.Runtime.InteropServices;
36 using System.Text;
38 namespace Mono.Data.Sqlite
40 /// <summary>
41 /// Represents the return values for sqlite_exec() and sqlite_step()
42 /// </summary>
43 internal enum SqliteError : int {
44 /// <value>Successful result</value>
45 OK = 0,
46 /// <value>SQL error or missing database</value>
47 ERROR = 1,
48 /// <value>An internal logic error in SQLite</value>
49 INTERNAL = 2,
50 /// <value>Access permission denied</value>
51 PERM = 3,
52 /// <value>Callback routine requested an abort</value>
53 ABORT = 4,
54 /// <value>The database file is locked</value>
55 BUSY = 5,
56 /// <value>A table in the database is locked</value>
57 LOCKED = 6,
58 /// <value>A malloc() failed</value>
59 NOMEM = 7,
60 /// <value>Attempt to write a readonly database</value>
61 READONLY = 8,
62 /// <value>Operation terminated by public const int interrupt()</value>
63 INTERRUPT = 9,
64 /// <value>Some kind of disk I/O error occurred</value>
65 IOERR = 10,
66 /// <value>The database disk image is malformed</value>
67 CORRUPT = 11,
68 /// <value>(Internal Only) Table or record not found</value>
69 NOTFOUND = 12,
70 /// <value>Insertion failed because database is full</value>
71 FULL = 13,
72 /// <value>Unable to open the database file</value>
73 CANTOPEN = 14,
74 /// <value>Database lock protocol error</value>
75 PROTOCOL = 15,
76 /// <value>(Internal Only) Database table is empty</value>
77 EMPTY = 16,
78 /// <value>The database schema changed</value>
79 SCHEMA = 17,
80 /// <value>Too much data for one row of a table</value>
81 TOOBIG = 18,
82 /// <value>Abort due to contraint violation</value>
83 CONSTRAINT= 19,
84 /// <value>Data type mismatch</value>
85 MISMATCH = 20,
86 /// <value>Library used incorrectly</value>
87 MISUSE = 21,
88 /// <value>Uses OS features not supported on host</value>
89 NOLFS = 22,
90 /// <value>Authorization denied</value>
91 AUTH = 23,
92 /// <value>Auxiliary database format error</value>
93 FORMAT = 24,
94 /// <value>2nd parameter to sqlite_bind out of range</value>
95 RANGE = 25,
96 /// <value>File opened that is not a database file</value>
97 NOTADB = 26,
98 /// <value>sqlite_step() has another row ready</value>
99 ROW = 100,
100 /// <value>sqlite_step() has finished executing</value>
101 DONE = 101
104 /// <summary>
105 /// Provides the core of C# bindings to the library sqlite.dll
106 /// </summary>
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 ("sqlite")]
139 internal static extern void sqlite_busy_timeout (IntPtr handle, int ms);
141 [DllImport("sqlite3", CharSet = CharSet.Unicode)]
142 internal static extern int sqlite3_open16 (string dbname, out IntPtr handle);
144 [DllImport("sqlite3")]
145 internal static extern void sqlite3_close (IntPtr sqlite_handle);
147 [DllImport("sqlite3")]
148 internal static extern IntPtr sqlite3_errmsg16 (IntPtr sqlite_handle);
150 [DllImport("sqlite3")]
151 internal static extern int sqlite3_changes (IntPtr handle);
153 [DllImport("sqlite3")]
154 internal static extern long sqlite3_last_insert_rowid (IntPtr sqlite_handle);
156 [DllImport ("sqlite3")]
157 internal static extern SqliteError sqlite3_prepare16 (IntPtr sqlite_handle, IntPtr zSql, int zSqllen, out IntPtr pVm, out IntPtr pzTail);
159 [DllImport ("sqlite3")]
160 internal static extern SqliteError sqlite3_step (IntPtr pVm);
162 [DllImport ("sqlite3")]
163 internal static extern SqliteError sqlite3_finalize (IntPtr pVm);
165 [DllImport ("sqlite3")]
166 internal static extern SqliteError sqlite3_exec (IntPtr handle, string sql, IntPtr callback, IntPtr user_data, out IntPtr errstr_ptr);
168 [DllImport ("sqlite3")]
169 internal static extern IntPtr sqlite3_column_name16 (IntPtr pVm, int col);
171 [DllImport ("sqlite3")]
172 internal static extern IntPtr sqlite3_column_text16 (IntPtr pVm, int col);
174 [DllImport ("sqlite3")]
175 internal static extern IntPtr sqlite3_column_blob (IntPtr pVm, int col);
177 [DllImport ("sqlite3")]
178 internal static extern int sqlite3_column_bytes16 (IntPtr pVm, int col);
180 [DllImport ("sqlite3")]
181 internal static extern int sqlite3_column_count (IntPtr pVm);
183 [DllImport ("sqlite3")]
184 internal static extern int sqlite3_column_type (IntPtr pVm, int col);
186 [DllImport ("sqlite3")]
187 internal static extern Int64 sqlite3_column_int64 (IntPtr pVm, int col);
189 [DllImport ("sqlite3")]
190 internal static extern double sqlite3_column_double (IntPtr pVm, int col);
192 [DllImport ("sqlite3")]
193 internal static extern IntPtr sqlite3_column_decltype16 (IntPtr pVm, int col);
195 [DllImport ("sqlite3")]
196 internal static extern int sqlite3_bind_parameter_count (IntPtr pStmt);
198 [DllImport ("sqlite3")]
199 internal static extern IntPtr sqlite3_bind_parameter_name (IntPtr pStmt, int n); // UTF-8 encoded return
201 [DllImport ("sqlite3")]
202 internal static extern SqliteError sqlite3_bind_blob (IntPtr pStmt, int n, byte[] blob, int length, IntPtr freetype);
204 [DllImport ("sqlite3")]
205 internal static extern SqliteError sqlite3_bind_double (IntPtr pStmt, int n, double value);
207 [DllImport ("sqlite3")]
208 internal static extern SqliteError sqlite3_bind_int (IntPtr pStmt, int n, int value);
210 [DllImport ("sqlite3")]
211 internal static extern SqliteError sqlite3_bind_int64 (IntPtr pStmt, int n, long value);
213 [DllImport ("sqlite3")]
214 internal static extern SqliteError sqlite3_bind_null (IntPtr pStmt, int n);
216 [DllImport ("sqlite3", CharSet = CharSet.Unicode)]
217 internal static extern SqliteError sqlite3_bind_text16 (IntPtr pStmt, int n, string value, int length, IntPtr freetype);
219 [DllImport ("sqlite3")]
220 internal static extern void sqlite3_busy_timeout (IntPtr handle, int ms);
222 #endregion
224 // These are adapted from Mono.Unix. When encoding is null,
225 // use Ansi encoding, which is a superset of the default
226 // expected encoding (ISO-8859-1).
228 public static IntPtr StringToHeap (string s, Encoding encoding)
230 if (encoding == null)
231 return Marshal.StringToHGlobalAnsi (s);
233 int min_byte_count = encoding.GetMaxByteCount(1);
234 char[] copy = s.ToCharArray ();
235 byte[] marshal = new byte [encoding.GetByteCount (copy) + min_byte_count];
237 int bytes_copied = encoding.GetBytes (copy, 0, copy.Length, marshal, 0);
239 if (bytes_copied != (marshal.Length-min_byte_count))
240 throw new NotSupportedException ("encoding.GetBytes() doesn't equal encoding.GetByteCount()!");
242 IntPtr mem = Marshal.AllocHGlobal (marshal.Length);
243 if (mem == IntPtr.Zero)
244 throw new OutOfMemoryException ();
246 bool copied = false;
247 try {
248 Marshal.Copy (marshal, 0, mem, marshal.Length);
249 copied = true;
251 finally {
252 if (!copied)
253 Marshal.FreeHGlobal (mem);
256 return mem;
259 public static unsafe string HeapToString (IntPtr p, Encoding encoding)
261 if (encoding == null)
262 return Marshal.PtrToStringAnsi (p);
264 if (p == IntPtr.Zero)
265 return null;
267 // This assumes a single byte terminates the string.
269 int len = 0;
270 while (Marshal.ReadByte (p, len) != 0)
271 checked {++len;}
273 string s = new string ((sbyte*) p, 0, len, encoding);
274 len = s.Length;
275 while (len > 0 && s [len-1] == 0)
276 --len;
277 if (len == s.Length)
278 return s;
279 return s.Substring (0, len);
286 #endif