|
1 | 1 | using Microsoft.Extensions.DependencyInjection; |
2 | 2 | using SharpCoreDB; |
3 | 3 |
|
4 | | -// This demo showcases the capabilities of SharpCoreDB, a lightweight, encrypted, file-based database |
5 | | -// that supports basic SQL operations like CREATE TABLE, INSERT, and SELECT with WHERE and ORDER BY clauses. |
6 | | -// SharpCoreDB uses JSON files for persistence, implements Write-Ahead Logging (WAL) for durability, |
7 | | -// and provides user authentication with encrypted storage. |
| 4 | +// Serilog setup stub |
| 5 | +// Add Serilog packages to your project: |
| 6 | +// dotnet add package Serilog |
| 7 | +// dotnet add package Serilog.Sinks.Console |
| 8 | +// dotnet add package Serilog.Extensions.Logging |
| 9 | +using Serilog; |
8 | 10 |
|
9 | 11 | class Program |
10 | 12 | { |
11 | 13 | static void Main(string[] args) |
12 | 14 | { |
13 | | - Console.WriteLine("SharpCoreDB Demo - A Lightweight Encrypted Database"); |
14 | | - Console.WriteLine("==============================================="); |
| 15 | + // Configure Serilog |
| 16 | + Log.Logger = new LoggerConfiguration() |
| 17 | + .MinimumLevel.Information() |
| 18 | + .WriteTo.Console() |
| 19 | + .CreateLogger(); |
15 | 20 |
|
16 | | - // Clean up any previous demo data |
17 | | - string dbPath = Path.Combine(Path.GetTempPath(), "SharpCoreDBDemo2"); |
18 | | - if (Directory.Exists(dbPath)) |
19 | | - { |
20 | | - Directory.Delete(dbPath, true); |
21 | | - } |
22 | | - |
23 | | - // Step 1: Set up Dependency Injection |
24 | | - // SharpCoreDB uses dependency injection for its services. We use the AddSharpCoreDB extension |
25 | | - // to register all required services, making the database self-contained. |
26 | | - var services = new ServiceCollection(); |
27 | | - services.AddSharpCoreDB(); |
28 | | - var serviceProvider = services.BuildServiceProvider(); |
29 | | - |
30 | | - // Step 2: Get the Database from DI |
31 | | - // The database is now resolved from the service provider, with all dependencies configured internally. |
32 | | - var factory = serviceProvider.GetRequiredService<DatabaseFactory>(); |
33 | | - string masterPassword = "demoMasterPassword123"; |
34 | | - |
35 | | - Console.WriteLine($"\nInitializing database at: {dbPath}"); |
36 | | - Console.WriteLine($"Master password: {masterPassword}"); |
37 | | - var db = factory.Create(dbPath, masterPassword); |
38 | | - |
39 | | - // Step 3: Create Tables |
40 | | - Console.WriteLine("--- Creating Tables ---"); |
41 | | - db.ExecuteSQL("CREATE TABLE users (id INTEGER, name TEXT)"); |
42 | | - string createTestTable = "CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT, active BOOLEAN, created DATETIME, score REAL, bigNum LONG, price DECIMAL, ulid ULID AUTO, guid GUID AUTO)"; |
43 | | - Console.WriteLine($"Executing: {createTestTable}"); |
44 | | - db.ExecuteSQL(createTestTable); |
45 | | - |
46 | | - // Step 4: Insert Data |
47 | | - Console.WriteLine("\n--- Inserting Data ---"); |
48 | | - db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 1 }, { "1", "Alice" } }); |
49 | | - db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 2 }, { "1", "Bob" } }); |
50 | | - db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "Charlie" } }); |
51 | | - var newUlid = Ulid.NewUlid().Value; |
52 | | - Console.WriteLine($"Generated ULID: {newUlid}"); |
53 | | - var parsedUlid = Ulid.Parse(newUlid); |
54 | | - Console.WriteLine($"Parsed timestamp: {parsedUlid.ToDateTime()}"); |
55 | | - db.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", |
56 | | - new Dictionary<string, object?> { |
57 | | - { "0", 1 }, |
58 | | - { "1", "Test1" }, |
59 | | - { "2", true }, |
60 | | - { "3", new DateTime(2023, 1, 1) }, |
61 | | - { "4", 10.5 }, |
62 | | - { "5", 123456789012345L }, |
63 | | - { "6", 99.99m }, |
64 | | - { "7", newUlid }, |
65 | | - { "8", Guid.NewGuid().ToString() } |
66 | | - }); |
67 | | - db.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", new Dictionary<string, object?> { { "0", 2 }, { "1", "Test2" }, { "2", null }, { "3", null }, { "4", null }, { "5", null }, { "6", null }, { "7", null }, { "8", null } }); |
68 | | - db.ExecuteSQL("INSERT INTO test (id, name) VALUES (?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "AutoTest" } }); |
69 | | - Console.WriteLine("Inserted data"); |
70 | | - |
71 | | - // Step 5: Query Data |
72 | | - Console.WriteLine("\n--- Querying Data ---"); |
73 | | - |
74 | | - // Select all test |
75 | | - Console.WriteLine("Selecting all test:"); |
76 | | - db.ExecuteSQL("SELECT * FROM test"); |
77 | | - |
78 | | - // Select test where active = 'true' |
79 | | - Console.WriteLine("\nSelecting test where active = 'true':"); |
80 | | - db.ExecuteSQL("SELECT * FROM test WHERE active = 'true'"); |
81 | | - |
82 | | - // Test UPDATE |
83 | | - Console.WriteLine("\nTesting UPDATE:"); |
84 | | - db.ExecuteSQL("UPDATE test SET name = ? WHERE id = ?", new Dictionary<string, object?> { { "0", "UpdatedTest" }, { "1", 1 } }); |
85 | | - db.ExecuteSQL("SELECT * FROM test WHERE id = ?", new Dictionary<string, object?> { { "0", 1 } }); |
86 | | - |
87 | | - // Test DELETE |
88 | | - Console.WriteLine("\nTesting DELETE:"); |
89 | | - db.ExecuteSQL("DELETE FROM test WHERE id = ?", new Dictionary<string, object?> { { "0", 2 } }); |
90 | | - db.ExecuteSQL("SELECT * FROM test"); |
91 | | - |
92 | | - // Test JOIN |
93 | | - Console.WriteLine("\nTesting JOIN:"); |
94 | | - db.ExecuteSQL("SELECT test.id, users.name FROM test JOIN users ON test.id = users.id"); |
95 | | - |
96 | | - // Test LEFT JOIN |
97 | | - Console.WriteLine("\nTesting LEFT JOIN:"); |
98 | | - db.ExecuteSQL("SELECT test.id, users.name FROM test LEFT JOIN users ON test.id = users.id"); |
99 | | - |
100 | | - // Step 6: Readonly Connection Test |
101 | | - Console.WriteLine("\n--- Readonly Connection Test ---"); |
102 | | - var dbReadonly = factory.Create(dbPath, masterPassword, true); // Readonly |
103 | | - Console.WriteLine("Readonly database created"); |
104 | | - |
105 | | - // Try to insert in readonly (should fail) |
106 | 21 | try |
107 | 22 | { |
108 | | - dbReadonly.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "Readonly Test" }, { "2", false }, { "3", new DateTime(2023, 1, 2) }, { "4", 20.0 } }); |
| 23 | + Console.WriteLine("SharpCoreDB Demo - A Lightweight Encrypted Database"); |
| 24 | + Console.WriteLine("==============================================="); |
| 25 | + |
| 26 | + // Clean up any previous demo data |
| 27 | + string dbPath = Path.Combine(Path.GetTempPath(), "SharpCoreDBDemo2"); |
| 28 | + if (Directory.Exists(dbPath)) |
| 29 | + { |
| 30 | + Directory.Delete(dbPath, true); |
| 31 | + } |
| 32 | + |
| 33 | + // Step 1: Set up Dependency Injection |
| 34 | + // SharpCoreDB uses dependency injection for its services. We use the AddSharpCoreDB extension |
| 35 | + // to register all required services, making the database self-contained. |
| 36 | + var services = new ServiceCollection(); |
| 37 | + services.AddSharpCoreDB(); |
| 38 | + // Add Serilog as the logging provider |
| 39 | + services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog()); |
| 40 | + var serviceProvider = services.BuildServiceProvider(); |
| 41 | + |
| 42 | + // Step 2: Get the Database from DI |
| 43 | + // The database is now resolved from the service provider, with all dependencies configured internally. |
| 44 | + var factory = serviceProvider.GetRequiredService<DatabaseFactory>(); |
| 45 | + string masterPassword = "demoMasterPassword123"; |
| 46 | + |
| 47 | + Console.WriteLine($"\nInitializing database at: {dbPath}"); |
| 48 | + Console.WriteLine($"Master password: {masterPassword}"); |
| 49 | + var db = factory.Create(dbPath, masterPassword); |
| 50 | + |
| 51 | + // Step 3: Create Tables |
| 52 | + Console.WriteLine("--- Creating Tables ---"); |
| 53 | + db.ExecuteSQL("CREATE TABLE users (id INTEGER, name TEXT)"); |
| 54 | + string createTestTable = "CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT, active BOOLEAN, created DATETIME, score REAL, bigNum LONG, price DECIMAL, ulid ULID AUTO, guid GUID AUTO)"; |
| 55 | + Console.WriteLine($"Executing: {createTestTable}"); |
| 56 | + db.ExecuteSQL(createTestTable); |
| 57 | + |
| 58 | + // Step 4: Insert Data |
| 59 | + Console.WriteLine("\n--- Inserting Data ---"); |
| 60 | + db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 1 }, { "1", "Alice" } }); |
| 61 | + db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 2 }, { "1", "Bob" } }); |
| 62 | + db.ExecuteSQL("INSERT INTO users VALUES (?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "Charlie" } }); |
| 63 | + var newUlid = Ulid.NewUlid().Value; |
| 64 | + Console.WriteLine($"Generated ULID: {newUlid}"); |
| 65 | + var parsedUlid = Ulid.Parse(newUlid); |
| 66 | + Console.WriteLine($"Parsed timestamp: {parsedUlid.ToDateTime()}"); |
| 67 | + db.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", |
| 68 | + new Dictionary<string, object?> { |
| 69 | + { "0", 1 }, |
| 70 | + { "1", "Test1" }, |
| 71 | + { "2", true }, |
| 72 | + { "3", new DateTime(2023, 1, 1) }, |
| 73 | + { "4", 10.5 }, |
| 74 | + { "5", 123456789012345L }, |
| 75 | + { "6", 99.99m }, |
| 76 | + { "7", newUlid }, |
| 77 | + { "8", Guid.NewGuid().ToString() } |
| 78 | + }); |
| 79 | + db.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", new Dictionary<string, object?> { { "0", 2 }, { "1", "Test2" }, { "2", null }, { "3", null }, { "4", null }, { "5", null }, { "6", null }, { "7", null }, { "8", null } }); |
| 80 | + db.ExecuteSQL("INSERT INTO test (id, name) VALUES (?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "AutoTest" } }); |
| 81 | + Console.WriteLine("Inserted data"); |
| 82 | + |
| 83 | + // Step 5: Query Data |
| 84 | + Console.WriteLine("\n--- Querying Data ---"); |
| 85 | + |
| 86 | + // Select all test |
| 87 | + Console.WriteLine("Selecting all test:"); |
| 88 | + db.ExecuteSQL("SELECT * FROM test"); |
| 89 | + |
| 90 | + // Select test where active = 'true' |
| 91 | + Console.WriteLine("\nSelecting test where active = 'true':"); |
| 92 | + db.ExecuteSQL("SELECT * FROM test WHERE active = 'true'"); |
| 93 | + |
| 94 | + // Test UPDATE |
| 95 | + Console.WriteLine("\nTesting UPDATE:"); |
| 96 | + db.ExecuteSQL("UPDATE test SET name = ? WHERE id = ?", new Dictionary<string, object?> { { "0", "UpdatedTest" }, { "1", 1 } }); |
| 97 | + db.ExecuteSQL("SELECT * FROM test WHERE id = ?", new Dictionary<string, object?> { { "0", 1 } }); |
| 98 | + |
| 99 | + // Test DELETE |
| 100 | + Console.WriteLine("\nTesting DELETE:"); |
| 101 | + db.ExecuteSQL("DELETE FROM test WHERE id = ?", new Dictionary<string, object?> { { "0", 2 } }); |
| 102 | + db.ExecuteSQL("SELECT * FROM test"); |
| 103 | + |
| 104 | + // Test JOIN |
| 105 | + Console.WriteLine("\nTesting JOIN:"); |
| 106 | + db.ExecuteSQL("SELECT test.id, users.name FROM test JOIN users ON test.id = users.id"); |
| 107 | + |
| 108 | + // Test LEFT JOIN |
| 109 | + Console.WriteLine("\nTesting LEFT JOIN:"); |
| 110 | + db.ExecuteSQL("SELECT test.id, users.name FROM test LEFT JOIN users ON test.id = users.id"); |
| 111 | + |
| 112 | + // Step 6: Readonly Connection Test |
| 113 | + Console.WriteLine("\n--- Readonly Connection Test ---"); |
| 114 | + var dbReadonly = factory.Create(dbPath, masterPassword, true); // Readonly |
| 115 | + Console.WriteLine("Readonly database created"); |
| 116 | + |
| 117 | + // Try to insert in readonly (should fail) |
| 118 | + try |
| 119 | + { |
| 120 | + dbReadonly.ExecuteSQL("INSERT INTO test VALUES (?, ?, ?, ?, ?)", new Dictionary<string, object?> { { "0", 3 }, { "1", "Readonly Test" }, { "2", false }, { "3", new DateTime(2023, 1, 2) }, { "4", 20.0 } }); |
| 121 | + } |
| 122 | + catch (Exception ex) |
| 123 | + { |
| 124 | + Console.WriteLine($"Insert in readonly failed: {ex.Message}"); |
| 125 | + } |
| 126 | + |
| 127 | + // Query in readonly (allows dirty reads) |
| 128 | + Console.WriteLine("Querying in readonly:"); |
| 129 | + dbReadonly.ExecuteSQL("SELECT * FROM test"); |
| 130 | + |
| 131 | + Console.WriteLine("\nDemo completed successfully!"); |
109 | 132 | } |
110 | 133 | catch (Exception ex) |
111 | 134 | { |
112 | | - Console.WriteLine($"Insert in readonly failed: {ex.Message}"); |
| 135 | + Console.WriteLine($"An error occurred: {ex.Message}"); |
| 136 | + } |
| 137 | + finally |
| 138 | + { |
| 139 | + // Ensure to flush and stop the logger |
| 140 | + Log.CloseAndFlush(); |
113 | 141 | } |
114 | | - |
115 | | - // Query in readonly (allows dirty reads) |
116 | | - Console.WriteLine("Querying in readonly:"); |
117 | | - dbReadonly.ExecuteSQL("SELECT * FROM test"); |
118 | | - |
119 | | - Console.WriteLine("\nDemo completed successfully!"); |
120 | 142 | } |
121 | 143 | } |
122 | 144 |
|
0 commit comments