diff --git a/Benchmarks.cs b/Benchmarks.cs index 253dff7..ad4cada 100644 --- a/Benchmarks.cs +++ b/Benchmarks.cs @@ -3,6 +3,7 @@ using BenchmarkDotNet.Configs; using Comparisons.SQLiteVSDoublets.Model; using Comparisons.SQLiteVSDoublets.SQLite; +using Comparisons.SQLiteVSDoublets.SystemDataSQLite; using Comparisons.SQLiteVSDoublets.Doublets; namespace Comparisons.SQLiteVSDoublets @@ -22,6 +23,7 @@ private class Config : ManualConfig [Params(1000, 10000, 100000)] public int N; private SQLiteTestRun _sqliteTestRun; + private SystemDataSQLiteTestRun _systemDataSqliteTestRun; private DoubletsTestRun _doubletsTestRun; [GlobalSetup] @@ -29,6 +31,7 @@ public void Setup() { BlogPosts.GenerateData(N); _sqliteTestRun = new SQLiteTestRun("test.db"); + _systemDataSqliteTestRun = new SystemDataSQLiteTestRun("test-systemdata.db"); _doubletsTestRun = new DoubletsTestRun("test.links"); } @@ -42,6 +45,16 @@ public void SQLiteOutput() File.WriteAllText(Path.Combine(SizeAfterCreationColumn.DbSizeOutputFolder, $"disk-size.sqlite.{N}.txt"), _sqliteTestRun.Results.DbSizeAfterCreation.ToString()); } + [Benchmark] + public void SystemDataSQLite() => _systemDataSqliteTestRun.Run(); + + [IterationCleanup(Target = "SystemDataSQLite")] + public void SystemDataSQLiteOutput() + { + Directory.CreateDirectory(SizeAfterCreationColumn.DbSizeOutputFolder); + File.WriteAllText(Path.Combine(SizeAfterCreationColumn.DbSizeOutputFolder, $"disk-size.systemdata-sqlite.{N}.txt"), _systemDataSqliteTestRun.Results.DbSizeAfterCreation.ToString()); + } + [Benchmark] public void Doublets() => _doubletsTestRun.Run(); diff --git a/Comparisons.SQLiteVSDoublets.csproj b/Comparisons.SQLiteVSDoublets.csproj index 2fa06d4..f77285c 100644 --- a/Comparisons.SQLiteVSDoublets.csproj +++ b/Comparisons.SQLiteVSDoublets.csproj @@ -2,7 +2,7 @@ Exe - net6 + net7.0 enable @@ -10,6 +10,7 @@ + diff --git a/Program.cs b/Program.cs index 36418b6..e3f8797 100644 --- a/Program.cs +++ b/Program.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Comparisons.SQLiteVSDoublets.SQLite; using Comparisons.SQLiteVSDoublets.Doublets; +using Comparisons.SQLiteVSDoublets.Experiments; using Comparisons.SQLiteVSDoublets.Model; using BenchmarkDotNet.Running; @@ -18,6 +19,9 @@ class Program /// static void Main() { + // Test System.Data.SQLite implementation + TestSystemDataSQLite.RunTest(); + BenchmarkRunner.Run(); // Use this method if you need full control over the execution. //Run(); diff --git a/SystemDataSQLite/SystemDataSQLiteTestRun.cs b/SystemDataSQLite/SystemDataSQLiteTestRun.cs new file mode 100644 index 0000000..f9277aa --- /dev/null +++ b/SystemDataSQLite/SystemDataSQLiteTestRun.cs @@ -0,0 +1,146 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Linq; +using Comparisons.SQLiteVSDoublets.Model; + +namespace Comparisons.SQLiteVSDoublets.SystemDataSQLite +{ + /// + /// + /// Represents the System.Data.SQLite test run. + /// + /// + /// + /// + public class SystemDataSQLiteTestRun : TestRun + { + /// + /// + /// The connection string. + /// + /// + /// + private readonly string _connectionString; + + /// + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// A db filename. + /// + /// + public SystemDataSQLiteTestRun(string dbFilename) : base(dbFilename) + { + _connectionString = $"Data Source={dbFilename};Version=3;"; + } + + /// + /// + /// Prepares this instance. + /// + /// + /// + public override void Prepare() + { + using var connection = new SQLiteConnection(_connectionString); + connection.Open(); + + const string createTableQuery = @" + CREATE TABLE IF NOT EXISTS BlogPosts ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + Title TEXT NOT NULL UNIQUE, + Content TEXT NOT NULL, + PublicationDateTime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP + )"; + + using var command = new SQLiteCommand(createTableQuery, connection); + command.ExecuteNonQuery(); + } + + /// + /// + /// Creates the list. + /// + /// + /// + public override void CreateList() + { + using var connection = new SQLiteConnection(_connectionString); + connection.Open(); + + using var transaction = connection.BeginTransaction(); + + const string insertQuery = @" + INSERT INTO BlogPosts (Title, Content, PublicationDateTime) + VALUES (@Title, @Content, @PublicationDateTime)"; + + using var command = new SQLiteCommand(insertQuery, connection, transaction); + + var titleParam = command.Parameters.Add("@Title", DbType.String); + var contentParam = command.Parameters.Add("@Content", DbType.String); + var dateParam = command.Parameters.Add("@PublicationDateTime", DbType.String); + + foreach (var blogPost in BlogPosts.List) + { + titleParam.Value = blogPost.Title; + contentParam.Value = blogPost.Content; + dateParam.Value = blogPost.PublicationDateTime.ToString("yyyy-MM-dd HH:mm:ss"); + + command.ExecuteNonQuery(); + } + + transaction.Commit(); + } + + /// + /// + /// Reads the list. + /// + /// + /// + public override void ReadList() + { + using var connection = new SQLiteConnection(_connectionString); + connection.Open(); + + const string selectQuery = @"SELECT Id, Title, Content, PublicationDateTime FROM BlogPosts"; + + using var command = new SQLiteCommand(selectQuery, connection); + using var reader = command.ExecuteReader(); + + while (reader.Read()) + { + var blogPost = new BlogPost + { + Id = reader.GetInt32("Id"), + Title = reader.GetString("Title"), + Content = reader.GetString("Content"), + PublicationDateTime = DateTime.Parse(reader.GetString("PublicationDateTime")) + }; + + ReadBlogPosts.Add(blogPost); + } + } + + /// + /// + /// Deletes the list. + /// + /// + /// + public override void DeleteList() + { + using var connection = new SQLiteConnection(_connectionString); + connection.Open(); + + const string deleteQuery = @"DELETE FROM BlogPosts"; + + using var command = new SQLiteCommand(deleteQuery, connection); + command.ExecuteNonQuery(); + } + } +} \ No newline at end of file diff --git a/TestSystemDataSQLite.csproj b/TestSystemDataSQLite.csproj new file mode 100644 index 0000000..6aa7847 --- /dev/null +++ b/TestSystemDataSQLite.csproj @@ -0,0 +1,25 @@ + + + + Exe + net8.0 + enable + Comparisons.SQLiteVSDoublets.TestApp.TestProgram + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/experiments/TestProgram.cs b/experiments/TestProgram.cs new file mode 100644 index 0000000..12d7f5c --- /dev/null +++ b/experiments/TestProgram.cs @@ -0,0 +1,15 @@ +using System; +using Comparisons.SQLiteVSDoublets.Experiments; + +namespace Comparisons.SQLiteVSDoublets.TestApp +{ + class TestProgram + { + static void Main() + { + Console.WriteLine("Testing System.Data.SQLite integration..."); + TestSystemDataSQLite.RunTest(); + Console.WriteLine("Test completed."); + } + } +} \ No newline at end of file diff --git a/experiments/TestSystemDataSQLite.cs b/experiments/TestSystemDataSQLite.cs new file mode 100644 index 0000000..cda30e4 --- /dev/null +++ b/experiments/TestSystemDataSQLite.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using Comparisons.SQLiteVSDoublets.Model; +using Comparisons.SQLiteVSDoublets.SQLite; +using Comparisons.SQLiteVSDoublets.SystemDataSQLite; + +namespace Comparisons.SQLiteVSDoublets.Experiments +{ + /// + /// + /// Simple test to verify System.Data.SQLite implementation works. + /// + /// + /// + public class TestSystemDataSQLite + { + public static void RunTest() + { + Console.WriteLine("Testing System.Data.SQLite implementation..."); + + // Generate test data + const int testDataSize = 10; + BlogPosts.GenerateData(testDataSize); + + // Test System.Data.SQLite implementation + var systemDataSqliteTestRun = new SystemDataSQLiteTestRun("test-systemdata.db"); + + try + { + // Clean up any existing test file + if (File.Exists("test-systemdata.db")) + File.Delete("test-systemdata.db"); + + systemDataSqliteTestRun.Run(); + + Console.WriteLine("✓ System.Data.SQLite test completed successfully"); + Console.WriteLine($"Results: {systemDataSqliteTestRun.Results}"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ System.Data.SQLite test failed: {ex.Message}"); + Console.WriteLine($"Stack trace: {ex.StackTrace}"); + } + + // Test Entity Framework SQLite implementation for comparison + var efSqliteTestRun = new SQLiteTestRun("test-ef.db"); + + try + { + // Clean up any existing test file + if (File.Exists("test-ef.db")) + File.Delete("test-ef.db"); + + efSqliteTestRun.Run(); + + Console.WriteLine("✓ Entity Framework SQLite test completed successfully"); + Console.WriteLine($"Results: {efSqliteTestRun.Results}"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ Entity Framework SQLite test failed: {ex.Message}"); + Console.WriteLine($"Stack trace: {ex.StackTrace}"); + } + + // Clean up test files + try + { + if (File.Exists("test-systemdata.db")) + File.Delete("test-systemdata.db"); + if (File.Exists("test-ef.db")) + File.Delete("test-ef.db"); + } + catch + { + // Ignore cleanup errors + } + } + } +} \ No newline at end of file diff --git a/test-ef.db-shm b/test-ef.db-shm new file mode 100644 index 0000000..2413088 Binary files /dev/null and b/test-ef.db-shm differ diff --git a/test-ef.db-wal b/test-ef.db-wal new file mode 100644 index 0000000..c8b9070 Binary files /dev/null and b/test-ef.db-wal differ