Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch marshalFixes Excluding Merge-Ins
This is equivalent to a diff from a3798d45f4 to c365a97aa9
2013-07-15
| ||
07:08 | Fix several issues with the managed virtual table support. Use the correct methods overloads for Marshal.PtrToStructure. Correct handling of native structure padding when running on 64-bit operating systems. Make sure connections released to the pool do not hold onto modules. Call sqlite3_dispose_module with the correct native module pointer. Modify all classes implementing the IDisposable pattern to set the disposed flag after their base classes have been disposed. Add LogExceptionsNoThrow and LogErrorsNoThrow to avoid throwing ObjectDisposedException when logging during derived class disposal. check-in: d60eb09374 user: mistachkin tags: trunk | |
07:00 | Fix typo. Closed-Leaf check-in: c365a97aa9 user: mistachkin tags: marshalFixes | |
06:53 | Add virtual table test to cover the marshalling performed with xBestIndex. check-in: e1483fef81 user: mistachkin tags: marshalFixes | |
03:57 | Virtual table marshalling fixes. check-in: e7b11da35f user: mistachkin tags: marshalFixes | |
2013-07-11
| ||
15:49 | Add GetSqlForDeclareTable method to the SQLiteModuleEnumerable class to allow derived classes to override the SQL statement used to declare the virtual table schema. check-in: a3798d45f4 user: mistachkin tags: trunk | |
2013-07-10
| ||
02:51 | Add another test for the SQLiteConvert.TypeNameToDbType method. check-in: 0654be8b4b user: mistachkin tags: trunk | |
Changes to SQLite.Interop/src/win/interop.c.
︙ | ︙ | |||
387 388 389 390 391 392 393 | pModule->xFindFunction = xFindFunction; pModule->xRename = xRename; pModule->xSavepoint = xSavepoint; pModule->xRelease = xRelease; pModule->xRollbackTo = xRollbackTo; return sqlite3_create_disposable_module(db, zName, pModule, pClientData, xDestroyModule); } | < < < < < | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | pModule->xFindFunction = xFindFunction; pModule->xRename = xRename; pModule->xSavepoint = xSavepoint; pModule->xRelease = xRelease; pModule->xRollbackTo = xRollbackTo; return sqlite3_create_disposable_module(db, zName, pModule, pClientData, xDestroyModule); } #endif SQLITE_API int WINAPI sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val) { return sqlite3_bind_double(stmt,iCol,*val); } |
︙ | ︙ |
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
157 158 159 160 161 162 163 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// #if INTEROP_VIRTUAL_TABLE | < < < < < < < < < < < < < < < | < < < < | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// #if INTEROP_VIRTUAL_TABLE DisposeModules(); #endif Close(false); /* Disposing, cannot throw. */ } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// #if INTEROP_VIRTUAL_TABLE /// <summary> /// This method attempts to dispose of all the <see cref="SQLiteModule" /> derived /// object instances currently associated with the native database connection. /// </summary> private void DisposeModules() { // // NOTE: If any modules were created, attempt to dispose of // them now. This code is designed to avoid throwing // exceptions unless the Dispose method of the module // itself throws an exception. // if (_modules != null) { foreach (KeyValuePair<string, SQLiteModule> pair in _modules) { SQLiteModule module = pair.Value; if (module == null) continue; module.Dispose(); } } } #endif /////////////////////////////////////////////////////////////////////////////////////////////// // It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SQLiteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. |
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | return; } if (_usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, canThrow)) { SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion); #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Close (Pool) Success: {0}", _sql)); #endif } #if !NET_COMPACT_20 && TRACE_CONNECTION | > > > > | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | return; } if (_usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, canThrow)) { #if INTEROP_VIRTUAL_TABLE DisposeModules(); #endif SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion); #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Close (Pool) Success: {0}", _sql)); #endif } #if !NET_COMPACT_20 && TRACE_CONNECTION |
︙ | ︙ | |||
1707 1708 1709 1710 1711 1712 1713 | if (_sql == null) throw new SQLiteException("connection has an invalid handle"); SetLoadExtension(true); LoadExtension(UnsafeNativeMethods.SQLITE_DLL, "sqlite3_vtshim_init"); | < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | < < < < < < < < < < | 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 | if (_sql == null) throw new SQLiteException("connection has an invalid handle"); SetLoadExtension(true); LoadExtension(UnsafeNativeMethods.SQLITE_DLL, "sqlite3_vtshim_init"); if (module.CreateDisposableModule(_sql)) { if (_modules == null) _modules = new Dictionary<string, SQLiteModule>(); _modules.Add(module.Name, module); } else { throw new SQLiteException(GetLastError()); } } /// <summary> /// Calls the native SQLite core library in order to cleanup the resources /// associated with a module containing the implementation of a virtual table. /// </summary> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLite3_UTF16.cs.
︙ | ︙ | |||
86 87 88 89 90 91 92 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteCommand.cs.
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 | /// <summary> /// Disposes of the command and clears all member variables /// </summary> /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param> protected override void Dispose(bool disposing) { try { if (!disposed) { if (disposing) { //////////////////////////////////// | > > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | /// <summary> /// Disposes of the command and clears all member variables /// </summary> /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param> protected override void Dispose(bool disposing) { bool skippedDispose = false; try { if (!disposed) { if (disposing) { //////////////////////////////////// |
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | } } if (reader != null) { reader._disposeCommand = true; _activeReader = null; return; } Connection = null; _parameterCollection.Clear(); _commandText = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | > < < > > | > > > > > > | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | } } if (reader != null) { reader._disposeCommand = true; _activeReader = null; skippedDispose = true; return; } Connection = null; _parameterCollection.Clear(); _commandText = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { if (!skippedDispose) { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteCommandBuilder.cs.
1 2 3 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) | | | 1 2 3 4 5 6 7 8 9 10 11 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; using System.Data; |
︙ | ︙ | |||
62 63 64 65 66 67 68 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ | |||
375 376 377 378 379 380 381 | return schema; } } private bool HasSchemaPrimaryKey(DataTable schema) { DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey]; | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | return schema; } } private bool HasSchemaPrimaryKey(DataTable schema) { DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey]; foreach (DataRow schemaRow in schema.Rows) { if ((bool)schemaRow[IsKeyColumn] == true) return true; } return false; |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
974 975 976 977 978 979 980 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); | < < > > > > > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteDataAdapter.cs.
︙ | ︙ | |||
175 176 177 178 179 180 181 | DeleteCommand = null; } } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | DeleteCommand = null; } } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteDataReader.cs.
︙ | ︙ | |||
144 145 146 147 148 149 150 | ////////////////////////////////////// // // NOTE: Fix for ticket [e1b2e0f769], do NOT throw exceptions // while we are being disposed. // _throwOnDisposed = false; | < > > > > > | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | ////////////////////////////////////// // // NOTE: Fix for ticket [e1b2e0f769], do NOT throw exceptions // while we are being disposed. // _throwOnDisposed = false; } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// internal void Cancel() |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteFunction.cs.
︙ | ︙ | |||
883 884 885 886 887 888 889 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } /// <summary> /// The type of user-defined function to declare |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModule.cs.
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | if (pIndex == IntPtr.Zero) return; int offset = 0; int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset); | | | | | > > > > > | < | < < | | > > > > > | < | < | 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 | if (pIndex == IntPtr.Zero) return; int offset = 0; int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset); offset += SQLiteMarshal.SizeOfStructInt(); IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(pIndex, offset); offset += IntPtr.Size; int nOrderBy = SQLiteMarshal.ReadInt32(pIndex, offset); offset += SQLiteMarshal.SizeOfStructInt(); IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(pIndex, offset); index = new SQLiteIndex(nConstraint, nOrderBy); Type indexConstraintType = typeof( UnsafeNativeMethods.sqlite3_index_constraint); int sizeOfConstraintType = Marshal.SizeOf(indexConstraintType); for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++) { IntPtr pOffset = SQLiteMarshal.IntPtrForOffset( pConstraint, iConstraint * sizeOfConstraintType); UnsafeNativeMethods.sqlite3_index_constraint constraint = (UnsafeNativeMethods.sqlite3_index_constraint) Marshal.PtrToStructure(pOffset, indexConstraintType); index.Inputs.Constraints[iConstraint] = new SQLiteIndexConstraint(constraint); } Type indexOrderByType = typeof( UnsafeNativeMethods.sqlite3_index_orderby); int sizeOfOrderByType = Marshal.SizeOf(indexOrderByType); for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++) { IntPtr pOffset = SQLiteMarshal.IntPtrForOffset( pOrderBy, iOrderBy * sizeOfOrderByType); UnsafeNativeMethods.sqlite3_index_orderby orderBy = (UnsafeNativeMethods.sqlite3_index_orderby) Marshal.PtrToStructure(pOffset, indexOrderByType); index.Inputs.OrderBys[iOrderBy] = new SQLiteIndexOrderBy(orderBy); } } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1187 1188 1189 1190 1191 1192 1193 | if (nConstraint != index.Inputs.Constraints.Length) return; if (nConstraint != index.Outputs.ConstraintUsages.Length) return; | | > < < < | | | | 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 | if (nConstraint != index.Inputs.Constraints.Length) return; if (nConstraint != index.Outputs.ConstraintUsages.Length) return; offset += SQLiteMarshal.SizeOfStructInt() + IntPtr.Size + SQLiteMarshal.SizeOfStructInt() + IntPtr.Size; IntPtr pConstraintUsage = SQLiteMarshal.ReadIntPtr(pIndex, offset); int sizeOfConstraintUsageType = Marshal.SizeOf(typeof( UnsafeNativeMethods.sqlite3_index_constraint_usage)); for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++) { UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage = new UnsafeNativeMethods.sqlite3_index_constraint_usage( index.Outputs.ConstraintUsages[iConstraint]); Marshal.StructureToPtr( constraintUsage, SQLiteMarshal.IntPtrForOffset( pConstraintUsage, iConstraint * sizeOfConstraintUsageType), false); } offset += IntPtr.Size; SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.IndexNumber); offset += SQLiteMarshal.SizeOfStructInt(); SQLiteMarshal.WriteIntPtr(pIndex, offset, SQLiteString.Utf8IntPtrFromString(index.Outputs.IndexString)); offset += IntPtr.Size; // // NOTE: We just allocated the IndexString field; therefore, we // need to set the NeedToFreeIndexString field to non-zero. // SQLiteMarshal.WriteInt32(pIndex, offset, 1); offset += SQLiteMarshal.SizeOfStructInt(); SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.OrderByConsumed); offset += SQLiteMarshal.SizeOfStructInt(); SQLiteMarshal.WriteDouble(pIndex, offset, index.Outputs.EstimatedCost); } #endregion /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 | public static IntPtr IntPtrForOffset( IntPtr pointer, int offset ) { return new IntPtr(pointer.ToInt64() + offset); } #endregion /////////////////////////////////////////////////////////////////////// #region Marshal Read Helper Methods /// <summary> /// Reads a <see cref="Int32" /> value from the specified memory | > > > > > > > > > > > > > > > | 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 | public static IntPtr IntPtrForOffset( IntPtr pointer, int offset ) { return new IntPtr(pointer.ToInt64() + offset); } /////////////////////////////////////////////////////////////////////// /// <summary> /// Determines the size of a <see cref="Int32" /> when it resides /// inside of a native structure. /// </summary> /// <returns> /// The size of the <see cref="Int32" /> type, in bytes, when it /// resides inside a native structure. /// </returns> public static int SizeOfStructInt() { return IntPtr.Size; } #endregion /////////////////////////////////////////////////////////////////////// #region Marshal Read Helper Methods /// <summary> /// Reads a <see cref="Int32" /> value from the specified memory |
︙ | ︙ | |||
5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 | /// This field is used to store the native sqlite3_module structure /// associated with this object instance. /// </summary> private UnsafeNativeMethods.sqlite3_module nativeModule; /////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK /// <summary> /// This field is used to hold the block of native memory that contains /// the native sqlite3_module structure associated with this object /// instance when running on the .NET Compact Framework. /// </summary> private IntPtr pNativeModule; | > > > > > > > > > | 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 | /// This field is used to store the native sqlite3_module structure /// associated with this object instance. /// </summary> private UnsafeNativeMethods.sqlite3_module nativeModule; /////////////////////////////////////////////////////////////////////// /// <summary> /// This field is used to store a pointer to the native sqlite3_module /// structure returned by the sqlite3_create_disposable_module /// function. /// </summary> private IntPtr disposableModule; /////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK /// <summary> /// This field is used to hold the block of native memory that contains /// the native sqlite3_module structure associated with this object /// instance when running on the .NET Compact Framework. /// </summary> private IntPtr pNativeModule; |
︙ | ︙ | |||
5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 | this.functions = new Dictionary<string, SQLiteFunction>(); } #endregion /////////////////////////////////////////////////////////////////////// #region Internal Methods /// <summary> /// Creates and returns the native sqlite_module structure using the /// configured (or default) <see cref="ISQLiteNativeModule" /> /// interface implementation. /// </summary> /// <returns> /// The native sqlite_module structure using the configured (or /// default) <see cref="ISQLiteNativeModule" /> interface /// implementation. /// </returns> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | < < | | 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 | this.functions = new Dictionary<string, SQLiteFunction>(); } #endregion /////////////////////////////////////////////////////////////////////// #region Internal Methods /// <summary> /// Calls the native SQLite core library in order to create a new /// disposable module containing the implementation of a virtual table. /// </summary> /// <param name="pDb"> /// The native database connection pointer to use. /// </param> /// <returns> /// Non-zero upon success. /// </returns> internal bool CreateDisposableModule( IntPtr pDb ) { if (disposableModule != IntPtr.Zero) return true; IntPtr pName = IntPtr.Zero; try { pName = SQLiteString.Utf8IntPtrFromString(name); UnsafeNativeMethods.sqlite3_module nativeModule = AllocateNativeModule(); #if !PLATFORM_COMPACTFRAMEWORK disposableModule = UnsafeNativeMethods.sqlite3_create_disposable_module( pDb, pName, ref nativeModule, IntPtr.Zero, null); return (disposableModule != IntPtr.Zero); #elif !SQLITE_STANDARD disposableModule = UnsafeNativeMethods.sqlite3_create_disposable_module_interop( pDb, pName, AllocateNativeModuleInterop(), nativeModule.iVersion, nativeModule.xCreate, nativeModule.xConnect, nativeModule.xBestIndex, nativeModule.xDisconnect, nativeModule.xDestroy, nativeModule.xOpen, nativeModule.xClose, nativeModule.xFilter, nativeModule.xNext, nativeModule.xEof, nativeModule.xColumn, nativeModule.xRowId, nativeModule.xUpdate, nativeModule.xBegin, nativeModule.xSync, nativeModule.xCommit, nativeModule.xRollback, nativeModule.xFindFunction, nativeModule.xRename, nativeModule.xSavepoint, nativeModule.xRelease, nativeModule.xRollbackTo, IntPtr.Zero, null); return (disposableModule != IntPtr.Zero); #else throw new NotImplementedException(); #endif } finally { if (pName != IntPtr.Zero) { SQLiteMemory.Free(pName); pName = IntPtr.Zero; } } } #endregion /////////////////////////////////////////////////////////////////////// #region Private Methods /// <summary> /// Creates and returns the native sqlite_module structure using the /// configured (or default) <see cref="ISQLiteNativeModule" /> /// interface implementation. /// </summary> /// <returns> /// The native sqlite_module structure using the configured (or /// default) <see cref="ISQLiteNativeModule" /> interface /// implementation. /// </returns> private UnsafeNativeMethods.sqlite3_module AllocateNativeModule() { return AllocateNativeModule(GetNativeModuleImpl()); } /////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK /// <summary> /// Creates and returns a memory block obtained from the SQLite core /// library used to store the native sqlite3_module structure for this /// object instance when running on the .NET Compact Framework. /// </summary> /// <returns> /// The native pointer to the native sqlite3_module structure. /// </returns> private IntPtr AllocateNativeModuleInterop() { if (pNativeModule == IntPtr.Zero) { // // HACK: No easy way to determine the size of the native // sqlite_module structure when running on the .NET // Compact Framework; therefore, just base the size // on what we know: // // There is one integer member. // There are 22 function pointer members. // pNativeModule = SQLiteMemory.Allocate( SQLiteMarshal.SizeOfStructInt() + (22 * IntPtr.Size)); if (pNativeModule == IntPtr.Zero) throw new OutOfMemoryException("sqlite3_module"); } return pNativeModule; } #endif /////////////////////////////////////////////////////////////////////// /// <summary> /// Creates and returns the native sqlite_module structure using the /// specified <see cref="ISQLiteNativeModule" /> interface /// implementation. /// </summary> /// <param name="module"> /// The <see cref="ISQLiteNativeModule" /> interface implementation to /// use. /// </param> /// <returns> /// The native sqlite_module structure using the specified /// <see cref="ISQLiteNativeModule" /> interface implementation. /// </returns> private UnsafeNativeMethods.sqlite3_module AllocateNativeModule( ISQLiteNativeModule module ) { nativeModule = new UnsafeNativeMethods.sqlite3_module(); nativeModule.iVersion = DefaultModuleVersion; if (module != null) |
︙ | ︙ | |||
5662 5663 5664 5665 5666 5667 5668 | // // NOTE: At this point, there is no way to report the error // condition back to the caller; therefore, use the // logging facility instead. // try { | | | 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 | // // NOTE: At this point, there is no way to report the error // condition back to the caller; therefore, use the // logging facility instead. // try { if (LogExceptionsNoThrow) { /* throw */ SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION, String.Format(CultureInfo.CurrentCulture, "Caught exception in \"{0}\" method: {1}", destroy ? "xDestroy" : "xDisconnect", e)); } |
︙ | ︙ | |||
5732 5733 5734 5735 5736 5737 5738 | { // do nothing. } if (pVtab == IntPtr.Zero) return false; | | | 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 | { // do nothing. } if (pVtab == IntPtr.Zero) return false; int offset = IntPtr.Size + SQLiteMarshal.SizeOfStructInt(); IntPtr pError = SQLiteMarshal.ReadIntPtr(pVtab, offset); if (pError != IntPtr.Zero) { SQLiteMemory.Free(pError); pError = IntPtr.Zero; SQLiteMarshal.WriteIntPtr(pVtab, offset, pError); } |
︙ | ︙ | |||
5977 5978 5979 5980 5981 5982 5983 | SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero); offset += IntPtr.Size; SQLiteMarshal.WriteInt32(pVtab, offset, 0); | | | 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 | SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero); offset += IntPtr.Size; SQLiteMarshal.WriteInt32(pVtab, offset, 0); offset += SQLiteMarshal.SizeOfStructInt(); SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero); } /////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ | |||
6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 | return sqliteBase.DeclareVirtualFunction( this, argumentCount, name, ref error); } #endregion /////////////////////////////////////////////////////////////////////// #region Error Handling Helper Methods /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="pVtab"> /// The native pointer to the sqlite3_vtab derived structure. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetTableError( IntPtr pVtab, string error ) { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 | return sqliteBase.DeclareVirtualFunction( this, argumentCount, name, ref error); } #endregion /////////////////////////////////////////////////////////////////////// #region Error Handling Properties private bool logErrors; /// <summary> /// Returns or sets a boolean value indicating whether virtual table /// errors should be logged using the <see cref="SQLiteLog" /> class. /// </summary> protected virtual bool LogErrorsNoThrow { get { return logErrors; } set { logErrors = value; } } /////////////////////////////////////////////////////////////////////// private bool logExceptions; /// <summary> /// Returns or sets a boolean value indicating whether exceptions /// caught in the /// <see cref="ISQLiteNativeModule.xDisconnect" /> method, /// <see cref="ISQLiteNativeModule.xDestroy" /> method, and the /// <see cref="Dispose()" /> method should be logged using the /// <see cref="SQLiteLog" /> class. /// </summary> protected virtual bool LogExceptionsNoThrow { get { return logExceptions; } set { logExceptions = value; } } #endregion /////////////////////////////////////////////////////////////////////// #region Error Handling Helper Methods /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="pVtab"> /// The native pointer to the sqlite3_vtab derived structure. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetTableError( IntPtr pVtab, string error ) { return SetTableError(this, pVtab, LogErrorsNoThrow, error); } /////////////////////////////////////////////////////////////////////// /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the |
︙ | ︙ | |||
6461 6462 6463 6464 6465 6466 6467 | /// Non-zero upon success. /// </returns> protected virtual bool SetTableError( SQLiteVirtualTable table, string error ) { | | | 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 | /// Non-zero upon success. /// </returns> protected virtual bool SetTableError( SQLiteVirtualTable table, string error ) { return SetTableError(this, table, LogErrorsNoThrow, error); } /////////////////////////////////////////////////////////////////////// /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the |
︙ | ︙ | |||
6486 6487 6488 6489 6490 6491 6492 | /// Non-zero upon success. /// </returns> protected virtual bool SetCursorError( SQLiteVirtualTableCursor cursor, string error ) { | | | 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 | /// Non-zero upon success. /// </returns> protected virtual bool SetCursorError( SQLiteVirtualTableCursor cursor, string error ) { return SetCursorError(this, cursor, LogErrorsNoThrow, error); } #endregion /////////////////////////////////////////////////////////////////////// #region Index Handling Helper Methods /// <summary> |
︙ | ︙ | |||
6542 6543 6544 6545 6546 6547 6548 | } #endregion #endregion /////////////////////////////////////////////////////////////////////// #region Public Properties | < | | < | | | 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 | } #endregion #endregion /////////////////////////////////////////////////////////////////////// #region Public Properties /// <summary> /// Returns or sets a boolean value indicating whether virtual table /// errors should be logged using the <see cref="SQLiteLog" /> class. /// </summary> public virtual bool LogErrors { get { CheckDisposed(); return LogErrorsNoThrow; } set { CheckDisposed(); LogErrorsNoThrow = value; } } /////////////////////////////////////////////////////////////////////// /// <summary> /// Returns or sets a boolean value indicating whether exceptions /// caught in the /// <see cref="ISQLiteNativeModule.xDisconnect" /> method, /// <see cref="ISQLiteNativeModule.xDestroy" /> method, and the /// <see cref="Dispose()" /> method should be logged using the /// <see cref="SQLiteLog" /> class. /// </summary> public virtual bool LogExceptions { get { CheckDisposed(); return LogExceptionsNoThrow; } set { CheckDisposed(); LogExceptionsNoThrow = value; } } #endregion /////////////////////////////////////////////////////////////////////// #region ISQLiteNativeModule Members /// <summary> |
︙ | ︙ | |||
8030 8031 8032 8033 8034 8035 8036 | ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { | < < < < | < < | | | < < | | < < < < | > > > > > > > > > > | 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 | ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { if (disposableModule != IntPtr.Zero) { UnsafeNativeMethods.sqlite3_dispose_module( disposableModule); disposableModule = IntPtr.Zero; } } catch (Exception e) { try { if (LogExceptionsNoThrow) { SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION, String.Format(CultureInfo.CurrentCulture, "Caught exception in \"Dispose\" method: {0}", e)); /* throw */ } } catch { // do nothing. } } #if PLATFORM_COMPACTFRAMEWORK finally { if (pNativeModule != IntPtr.Zero) { SQLiteMemory.Free(pNativeModule); pNativeModule = IntPtr.Zero; } } #endif disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////// |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModuleEnumerable.cs.
︙ | ︙ | |||
223 224 225 226 227 228 229 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); | < < > > > > > | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } #endregion /////////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
941 942 943 944 945 946 947 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } #endregion } #endregion |
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); | < < > > > > > | 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// Close(); } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } #endregion /////////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1265 1266 1267 1268 1269 1270 1271 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } #endregion } #endregion |
Changes to System.Data.SQLite/SQLiteModuleNoop.cs.
︙ | ︙ | |||
765 766 767 768 769 770 771 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion } } |
Changes to System.Data.SQLite/SQLiteTransaction.cs.
1 2 3 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) | | | 1 2 3 4 5 6 7 8 9 10 11 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; using System.Data; |
︙ | ︙ | |||
93 94 95 96 97 98 99 | IssueRollback(false); } } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | < < > > > > > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | IssueRollback(false); } } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
1603 1604 1605 1606 1607 1608 1609 | internal static extern IntPtr sqlite3_create_disposable_module(IntPtr db, IntPtr name, ref sqlite3_module module, IntPtr pClientData, xDestroyModule xDestroy); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif | | | 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 | internal static extern IntPtr sqlite3_create_disposable_module(IntPtr db, IntPtr name, ref sqlite3_module module, IntPtr pClientData, xDestroyModule xDestroy); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern void sqlite3_dispose_module(IntPtr pModule); #endif #endregion /////////////////////////////////////////////////////////////////////////// #region sqlite interop api calls (.NET Compact Framework only) #if PLATFORM_COMPACTFRAMEWORK && !SQLITE_STANDARD |
︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 | xConnect xConnect, xBestIndex xBestIndex, xDisconnect xDisconnect, xDestroy xDestroy, xOpen xOpen, xClose xClose, xFilter xFilter, xNext xNext, xEof xEof, xColumn xColumn, xRowId xRowId, xUpdate xUpdate, xBegin xBegin, xSync xSync, xCommit xCommit, xRollback xRollback, xFindFunction xFindFunction, xRename xRename, xSavepoint xSavepoint, xRelease xRelease, xRollbackTo xRollbackTo, IntPtr pClientData, xDestroyModule xDestroyModule); | < < < | 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | xConnect xConnect, xBestIndex xBestIndex, xDisconnect xDisconnect, xDestroy xDestroy, xOpen xOpen, xClose xClose, xFilter xFilter, xNext xNext, xEof xEof, xColumn xColumn, xRowId xRowId, xUpdate xUpdate, xBegin xBegin, xSync xSync, xCommit xCommit, xRollback xRollback, xFindFunction xFindFunction, xRename xRename, xSavepoint xSavepoint, xRelease xRelease, xRollbackTo xRollbackTo, IntPtr pClientData, xDestroyModule xDestroyModule); #endif // PLATFORM_COMPACTFRAMEWORK && !SQLITE_STANDARD #endregion /////////////////////////////////////////////////////////////////////////// #region Native Delegates |
︙ | ︙ |
Changes to Tests/vtab.eagle.
︙ | ︙ | |||
206 207 208 209 210 211 212 | cleanupDb $fileName unset -nocomplain result code results errors sql dataSource id fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\ defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \ [string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\ | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | cleanupDb $fileName unset -nocomplain result code results errors sql dataSource id fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\ defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \ [string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\ \{\} 0 \{one two three 4 5\.0 Error \{SQL logic error or missing database virtual table "t\d+" is read-only\}\}$}]} ############################################################################### runTest {test vtab-1.3 {IEnumerable<T> virtual table} -setup { set fileName vtab-1.3.db } -body { |
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 | unset -nocomplain result code results errors sql dataSource id fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\ defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \ [string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\ \{\} 0 \{\{\} t\d+ \{\} x\d+\}$}]} ############################################################################### runSQLiteTestEpilogue runTestEpilogue | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | unset -nocomplain result code results errors sql dataSource id fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\ defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \ [string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\ \{\} 0 \{\{\} t\d+ \{\} x\d+\}$}]} ############################################################################### runTest {test vtab-1.7 {virtual table xBestIndex marshalling} -setup { set fileName vtab-1.7.db } -body { set id [object invoke Interpreter.GetActive NextId] set dataSource [file join [getDatabaseDirectory] $fileName] set sql(1) { \ CREATE TABLE t${id}(y CHAR(10) NOT NULL PRIMARY KEY); \ CREATE VIRTUAL TABLE u${id} USING mod${id}; \ } set sql(2) { \ INSERT INTO t${id} SELECT x FROM u${id}; \ } set sql(3) { \ SELECT v${id}.y FROM t${id} v${id} LEFT OUTER JOIN \ u${id} ON u${id}.x = v${id}.y WHERE u${id}.x IS NOT NULL \ ORDER BY v${id}.y DESC; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { using System; using System.Data.SQLite; using Eagle._Containers.Public; namespace _Dynamic${id} { public static class Test${id} { public static StringList GetList(params string\[\] strings) { StringList result = new StringList(); using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) { connection.Open(); connection.CreateModule(new SQLiteModuleEnumerable( "mod${id}", strings)); using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "[subst ${sql(1)}]"; result.Add(command.ExecuteNonQuery().ToString()); } using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "[subst ${sql(2)}]"; result.Add(command.ExecuteNonQuery().ToString()); } using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "[subst ${sql(3)}]"; using (SQLiteDataReader dataReader = command.ExecuteReader()) { while (dataReader.Read()) result.Add(dataReader\[0\].ToString()); } } connection.Close(); } return result; } /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } } } }] true true true results errors [list System.Data.SQLite.dll Eagle.dll]] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} GetList one two three 4 5.0 } result] : [set result ""]}] $result } -cleanup { cleanupDb $fileName unset -nocomplain result code results errors sql dataSource id fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\ defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \ [string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\ \{\} 0 \{0 5 two three one 5\.0 4\}$}]} ############################################################################### runSQLiteTestEpilogue runTestEpilogue |