public void Fts5CommandRank([IncludeDataSources(TestProvName.AllSQLite)] string context) { using (var db = GetDataConnection(context)) { var commandInterceptor = new SaveCommandInterceptor(); db.AddInterceptor(commandInterceptor); db.AddMappingSchema(SetupFtsMapping(SQLiteFTS.FTS5)); try { db.FTS5Rank(db.GetTable <FtsTable>(), "strange('function\")"); } catch { // we don't have FTS5 table, but we need to get sql for validation } finally { Assert.AreEqual("INSERT INTO [FTS5_TABLE]([FTS5_TABLE], rank) VALUES('rank', @rank)", db.LastQuery); Assert.AreEqual(1, commandInterceptor.Parameters.Length); Assert.AreEqual("strange('function\")", commandInterceptor.Parameters[0].Value); } } }
public void Fts5CommandDelete([IncludeDataSources(TestProvName.AllSQLite)] string context) { using (var db = GetDataConnection(context)) { var commandInterceptor = new SaveCommandInterceptor(); db.AddInterceptor(commandInterceptor); db.AddMappingSchema(SetupFtsMapping(SQLiteFTS.FTS5)); try { var record = new FtsTable() { text1 = "one", text2 = "two" }; db.FTS5Delete(db.GetTable <FtsTable>(), 2, record); } catch { // we don't have FTS5 table, but we need to get sql for validation } finally { Assert.AreEqual("INSERT INTO [FTS5_TABLE]([FTS5_TABLE], rowid, [text1], [text2]) VALUES('delete', 2, @p0, @p1)", db.LastQuery); Assert.AreEqual(2, commandInterceptor.Parameters.Length); Assert.True(commandInterceptor.Parameters.Any(p => p.Value !.Equals("one"))); Assert.True(commandInterceptor.Parameters.Any(p => p.Value !.Equals("two"))); } } }
public void Test2([IncludeDataSources(TestProvName.AllSQLite)] string context) { using (var db = GetDataConnection(context)) { var commandInterceptor = new SaveCommandInterceptor(); db.AddInterceptor(commandInterceptor); var date = TestData.Date; var q = (from t1 in db.GetTable <LinqDataTypes>() where t1.DateTimeValue == date select t1); var _ = q.FirstOrDefault(); var dc = (DataConnection)db; Assert.AreEqual(2, commandInterceptor.Parameters.Length); Assert.AreEqual(1, commandInterceptor.Parameters.Count(p => p.DbType == DbType.Date)); } }
public void ConcurrentRunner <TParam, TResult>(DataConnection dc, string context, int threadsPerParam, Func <DataConnection, TParam, TResult> queryFunc, Action <TResult, TParam> checkAction, params TParam[] parameters) { var threadCount = threadsPerParam * parameters.Length; if (threadCount <= 0) { throw new InvalidOperationException(); } // maximum Provider pool count const int poolCount = 10; var semaphore = new Semaphore(0, poolCount); var threads = new Thread[threadCount]; var results = new Tuple <TParam, TResult, string, DbParameter[], Exception?> [threadCount]; for (var i = 0; i < threadCount; i++) { var param = parameters[i % parameters.Length]; var n = i; threads[i] = new Thread(() => { semaphore.WaitOne(); try { try { using (var threadDb = (DataConnection)GetDataContext(context)) { var commandInterceptor = new SaveCommandInterceptor(); threadDb.AddInterceptor(commandInterceptor); var result = queryFunc(threadDb, param); results[n] = Tuple.Create(param, result, threadDb.LastQuery !, commandInterceptor.Parameters, (Exception?)null); } } catch (Exception e) { results[n] = Tuple.Create(param, default(TResult), "", (DbParameter[]?)null, e) !; } } finally { semaphore.Release(); } }); } for (int i = 0; i < threads.Length; i++) { threads[i].Start(); } semaphore.Release(poolCount); for (int i = 0; i < threads.Length; i++) { threads[i].Join(); } for (int i = 0; i < threads.Length; i++) { var result = results[i]; if (result.Item5 != null) { TestContext.WriteLine($"Exception in query ({result.Item1}):\n\n{result.Item5}"); throw result.Item5; } try { checkAction(result.Item2, result.Item1); } catch { var testResult = queryFunc(dc, result !.Item1); TestContext.WriteLine($"Failed query ({result.Item1}):\n"); if (result.Item4 != null) { var sb = new StringBuilder(); dc.DataProvider.CreateSqlBuilder(dc.MappingSchema).PrintParameters(dc, sb, result.Item4.OfType <DbParameter>()); TestContext.WriteLine(sb); } TestContext.WriteLine(); TestContext.WriteLine(result.Item3); DumpObject(result.Item2); DumpObject(testResult); throw; } } }
public void GuidMappingTest([IncludeDataSources(TestProvName.AllSQLite)] string context) { using var db = GetDataConnection(context); var interceptor = new SaveCommandInterceptor(); db.AddInterceptor(interceptor); using var table = db.CreateLocalTable <GuidMapping>(); var data = new GuidMapping[] { new () { BlobGuid1 = TestData.Guid1, BlobGuid2 = TestData.Guid1, BlobGuid3 = TestData.Guid1, BlobGuid4 = TestData.Guid1, TextGuid1 = TestData.Guid1, TextGuid2 = TestData.Guid1, } }; var comparer = ComparerBuilder.GetEqualityComparer <GuidMapping>(); // test literal passed with proper type db.InlineParameters = true; table.Insert(() => new() { BlobGuid1 = TestData.Guid1 }); TestWrite("BlobGuid1", "blob", true); table.Insert(() => new() { BlobGuid2 = TestData.Guid1 }); TestWrite("BlobGuid2", "blob", true); table.Insert(() => new() { BlobGuid3 = TestData.Guid1 }); TestWrite("BlobGuid3", "blob", true); table.Insert(() => new() { BlobGuid4 = TestData.Guid1 }); TestWrite("BlobGuid4", "blob", true); table.Insert(() => new() { TextGuid1 = TestData.Guid1 }); TestWrite("TextGuid1", "text", true); table.Insert(() => new() { TextGuid2 = TestData.Guid1 }); TestWrite("TextGuid2", "text", true); // test parameter passed with proper type db.InlineParameters = false; table.Insert(() => new() { BlobGuid1 = TestData.Guid1 }); TestWrite("BlobGuid1", "blob", false); table.Insert(() => new() { BlobGuid2 = TestData.Guid1 }); TestWrite("BlobGuid2", "blob", false); table.Insert(() => new() { BlobGuid3 = TestData.Guid1 }); TestWrite("BlobGuid3", "blob", false); table.Insert(() => new() { BlobGuid4 = TestData.Guid1 }); TestWrite("BlobGuid4", "blob", false); table.Insert(() => new() { TextGuid1 = TestData.Guid1 }); TestWrite("TextGuid1", "text", false); table.Insert(() => new() { TextGuid2 = TestData.Guid1 }); TestWrite("TextGuid2", "text", false); // test bulk copy roundtrip table.BulkCopy(data); var result = table.ToArray(); AreEqual(data, result, comparer); table.Delete(); // test insert literals roundtrip db.InlineParameters = true; db.Insert(data[0]); Assert.AreEqual(0, interceptor.Parameters.Length); result = table.ToArray(); AreEqual(data, result, comparer); table.Delete(); // test insert parameters roundtrip db.InlineParameters = false; db.Insert(data[0]); Assert.AreEqual(6, interceptor.Parameters.Length); result = table.ToArray(); AreEqual(data, result, comparer); table.Delete(); // test mixed values read var value = $"'{TestData.Guid1.ToString().ToUpperInvariant()}'"; db.Execute($"INSERT INTO GuidMapping(BlobGuid1, BlobGuid2, BlobGuid3, BlobGuid4, TextGuid1, TextGuid2) VALUES({value}, {value}, {value}, {value}, {value}, {value})"); value = $"x'{string.Join(string.Empty, TestData.Guid1.ToByteArray().Select(x => $"{x:X2}"))}'"; db.Execute($"INSERT INTO GuidMapping(BlobGuid1, BlobGuid2, BlobGuid3, BlobGuid4, TextGuid1, TextGuid2) VALUES({value}, {value}, {value}, {value}, {value}, {value})"); result = table.ToArray(); AreEqual(data, new[] { result[0] }, comparer); AreEqual(data, new[] { result[1] }, comparer); void TestWrite(string FieldName, string expectedType, bool inline) { Assert.AreEqual(inline ? 0 : 1, interceptor.Parameters.Length); var type = db.Execute <string>($"SELECT typeof({FieldName}) FROM GuidMapping"); Assert.AreEqual(expectedType, type); // assert literal is uppercased (M.D.SQLite format) if (expectedType == "text") { Assert.AreEqual(TestData.Guid1.ToString().ToUpperInvariant(), db.Execute <string>($"SELECT {FieldName} FROM GuidMapping")); } table.Delete(); } } }