-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTable.cs
More file actions
179 lines (142 loc) · 6.81 KB
/
Table.cs
File metadata and controls
179 lines (142 loc) · 6.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
namespace NoSQLite.Test;
[MethodDataSource<Table>(nameof(Arguments))]
public sealed class Table : TestBase
{
public static IEnumerable<Func<JsonSerializerOptions?>> Arguments() =>
[
() => null,
() => JsonSerializerOptions.Default,
#if NET9_0_OR_GREATER
() => new(JsonSerializerOptions.Web) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull },
#else
() => new(JsonSerializerOptions.Default) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull },
#endif
];
public Table(JsonSerializerOptions? jsonOptions) : base(jsonOptions)
{
}
[Test]
public async Task CRUD()
{
var people = new PersonFaker().Generate(10);
var table = Connection.GetTable("crud");
// Insert
foreach (var person in people)
{
table.Add(person);
}
// Count, LongCount, All
await That(table.Count()).IsEqualTo(10);
await That(table.LongCount()).IsEqualTo(10);
await That(table.All<TestPerson>().Length).IsEqualTo(10);
// Exists
var id = 5;
await That(table.Exists<TestPerson, int>(p => p.Id, id)).IsTrue();
await That(table.Exists<TestPerson, int>(p => p.Id, 15)).IsFalse();
// Find
await That(() => table.Find<TestPerson, int>(p => p.Id, 15)).Throws<NoSQLiteException>().WithInnerException().And.IsTypeOf<KeyNotFoundException>();
await That(() => table.TryFind<TestPerson, int>(p => p.Id, 15, out _)).IsFalse();
await That(() => table.TryFind<TestPerson, int>(p => p.Id, id, out _)).IsTrue();
var person5 = await That(table.Find<TestPerson, int>(p => p.Id, id)).IsNotNull();
// Update
person5!.Name = "test";
table.Update(person5, p => p.Id);
// Select
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Name, id)).IsEqualTo("test");
// Insert/Replace/Set
// Check conditions for where the value doesnt exist works only when options are set to not writting null
if (Connection.JsonOptions?.DefaultIgnoreCondition is JsonIgnoreCondition.WhenWritingNull)
{
// should not replace because it doesnt exist
table.Replace<TestPerson, int, string>(p => p.Id, p => p.Nonce, id, "r");
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Nonce, id)).IsEqualTo(null);
// should insert because it doesnt exist
table.Insert<TestPerson, int, string>(p => p.Id, p => p.Nonce, id, "inserted");
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Nonce, id)).IsEqualTo("inserted");
// should replace beacuse it exists
table.Replace<TestPerson, int, string>(p => p.Id, p => p.Nonce, id, "replaced");
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Nonce, id)).IsEqualTo("replaced");
// should set the value even if it deosnt exist
table.Set<TestPerson, int, string>(p => p.Id, p => p.Nonce2, id, "aaaaa");
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Nonce2, id)).IsEqualTo("aaaaa");
}
// Replace
table.Replace<TestPerson, int, bool>(p => p.Id, p => p.Sane, id, false);
await That(table.FindProperty<TestPerson, int, bool>(p => p.Id, p => p.Sane, id)).IsFalse();
// Set (should set regardles of existances or not)
table.Set<TestPerson, int, string>(p => p.Id, p => p.Name, id, "test from set");
await That(table.FindProperty<TestPerson, int, string>(p => p.Id, p => p.Name, id)).IsEqualTo("test from set");
// Delete, (Assert) Exists, Count, LongCount, All
table.Delete<TestPerson, int>(p => p.Id, id);
await That(table.Exists<TestPerson, int>(p => p.Id, id)).IsFalse();
await That(table.Count()).IsEqualTo(9);
await That(table.LongCount()).IsEqualTo(9);
await That(table.All<TestPerson>().Length).IsEqualTo(9);
// Clear, (Assert) Count, LongCount, All
table.Clear();
await That(table.Count()).IsEqualTo(0);
await That(table.LongCount()).IsEqualTo(0);
await That(table.All<TestPerson>().Length).IsEqualTo(0);
}
[Test]
[Arguments("MyIndex")]
[Arguments("123 My Index")]
[Arguments("!@# -- __ -- // --")]
[Arguments(" ")]
[Arguments("")]
public async Task Index(string indexName)
{
var tableName = "index";
var table = Connection.GetTable(tableName);
var propertyPath = Extensions.GetPropertyPath<TestPerson, int>(p => p.Id, Connection.JsonOptions);
await That(table.IndexExists(indexName)).IsFalse();
table.CreateIndex<TestPerson, int>(p => p.Id, indexName);
await That(table.IndexExists(indexName)).IsTrue();
// test plan index
using var planStmt = table.NewStmt($"""
EXPLAIN QUERY PLAN
SELECT *
FROM "{tableName}"
WHERE "documents"->'$.{propertyPath}' = '10';
""");
var result = planStmt.Execute(null, r => r.Text(3));
await That(result).IsEqualTo($"SEARCH {tableName} USING INDEX {tableName}_{indexName} (<expr>=?)");
table.DeleteIndex(indexName);
await That(table.IndexExists(indexName)).IsFalse();
}
[Test]
public async Task Index_Unique()
{
var indexName = "id";
var tableName = "unique";
var table = Connection.GetTable(tableName);
var propertyPath = Extensions.GetPropertyPath<TestPerson, int>(p => p.Id, Connection.JsonOptions);
await That(table.IndexExists(indexName)).IsFalse();
table.CreateIndex<TestPerson, int>(p => p.Id, indexName, unique: true);
await That(table.IndexExists(indexName)).IsTrue();
// test plan index
using var planStmt = table.NewStmt($"""
EXPLAIN QUERY PLAN
SELECT *
FROM "{tableName}"
WHERE "documents"->'$.{propertyPath}' = '10';
""");
var result = planStmt.Execute(null, r => r.Text(3));
await That(result).IsEqualTo($"SEARCH {tableName} USING INDEX {tableName}_{indexName} (<expr>=?)");
// insert two times
var personFaker = new PersonFaker();
var person = personFaker.Generate();
await That(() => table.Add(person)).ThrowsNothing();
// second time throws
await That(() => table.Add(person)).Throws<NoSQLiteException>();
// count remains only one person
await That(table.Count()).IsEqualTo(1);
// delete index
table.DeleteIndex(indexName);
await That(table.IndexExists(indexName)).IsFalse();
// insert doesnt throw
await That(() => table.Add(person)).ThrowsNothing();
// count goes up to two people
await That(table.Count()).IsEqualTo(2);
}
}