-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathlib.cpp
More file actions
260 lines (212 loc) · 8.4 KB
/
Copy pathlib.cpp
File metadata and controls
260 lines (212 loc) · 8.4 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
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
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
250
251
252
253
254
255
256
257
258
259
260
#include "spacetimedb.h"
using namespace SpacetimeDB;
// ============================================================================
// Test Types
// ============================================================================
struct ReturnStruct {
uint32_t a;
std::string b;
};
SPACETIMEDB_STRUCT(ReturnStruct, a, b)
SPACETIMEDB_ENUM(ReturnEnum,
(A, uint32_t),
(B, std::string)
)
// Table for transaction tests
struct MyTable {
ReturnStruct field;
};
SPACETIMEDB_STRUCT(MyTable, field)
SPACETIMEDB_TABLE(MyTable, my_table, Public)
// Table for UUID ordering tests
struct PkUuid {
Uuid u;
uint8_t data;
};
SPACETIMEDB_STRUCT(PkUuid, u, data)
SPACETIMEDB_TABLE(PkUuid, pk_uuid, Public)
// Table for scheduled procedure tests
struct ScheduledProcTable {
uint64_t scheduled_id;
ScheduleAt scheduled_at;
Timestamp reducer_ts;
uint8_t x;
uint8_t y;
};
SPACETIMEDB_STRUCT(ScheduledProcTable, scheduled_id, scheduled_at, reducer_ts, x, y)
SPACETIMEDB_TABLE(ScheduledProcTable, scheduled_proc_table, Private)
FIELD_PrimaryKeyAutoInc(scheduled_proc_table, scheduled_id);
SPACETIMEDB_SCHEDULE(scheduled_proc_table, 1, scheduled_proc) // Column 1 is scheduled_at
// Table for storing procedure results
struct ProcInsertsInto {
Timestamp reducer_ts;
Timestamp procedure_ts;
uint8_t x;
uint8_t y;
};
SPACETIMEDB_STRUCT(ProcInsertsInto, reducer_ts, procedure_ts, x, y)
SPACETIMEDB_TABLE(ProcInsertsInto, proc_inserts_into, Public)
// ============================================================================
// Procedure Tests - Part 1: Return Values
// ============================================================================
// Test returning a primitive type
SPACETIMEDB_PROCEDURE(uint32_t, return_primitive, ProcedureContext ctx, uint32_t lhs, uint32_t rhs) {
return lhs + rhs;
}
// Test returning a struct
SPACETIMEDB_PROCEDURE(ReturnStruct, return_struct, ProcedureContext ctx, uint32_t a, std::string b) {
return ReturnStruct{a, b};
}
// Test returning enum variant A
SPACETIMEDB_PROCEDURE(ReturnEnum, return_enum_a, ProcedureContext ctx, uint32_t a) {
return ReturnEnum{a};
}
// Test returning enum variant B
SPACETIMEDB_PROCEDURE(ReturnEnum, return_enum_b, ProcedureContext ctx, std::string b) {
return ReturnEnum{b};
}
// Test procedure that panics
SPACETIMEDB_PROCEDURE(Unit, will_panic, ProcedureContext ctx) {
LOG_PANIC("This procedure is expected to panic");
return Unit{}; // Never reached
}
// ============================================================================
// Procedure Tests - Part 2: Transactions
// ============================================================================
#ifdef SPACETIMEDB_UNSTABLE_FEATURES
// Helper function to insert a row
void insert_my_table(TxContext& tx) {
tx.db[my_table].insert(MyTable{
ReturnStruct{42, "magic"}
});
}
// Helper function to assert row count
void assert_row_count(ProcedureContext& ctx, uint64_t count) {
ctx.with_tx([count](TxContext& tx) {
uint64_t actual = tx.db[my_table].count();
if (actual != count) {
LOG_PANIC("Expected " + std::to_string(count) + " rows but got " + std::to_string(actual));
}
});
}
// Test transaction that commits
SPACETIMEDB_PROCEDURE(Unit, insert_with_tx_commit, ProcedureContext ctx) {
// Insert a row and commit
ctx.with_tx(insert_my_table);
// Assert that there's a row
assert_row_count(ctx, 1);
return Unit{};
}
// Test transaction that rolls back
SPACETIMEDB_PROCEDURE(Unit, insert_with_tx_rollback, ProcedureContext ctx) {
// Use try_with_tx and return false to rollback
ctx.try_with_tx([](TxContext& tx) -> bool {
insert_my_table(tx);
return false; // Rollback
});
// Assert that there's not a row
assert_row_count(ctx, 0);
return Unit{};
}
#endif // SPACETIMEDB_UNSTABLE_FEATURES
// ============================================================================
// Procedure Tests - Part 4: HTTP Requests
// ============================================================================
#ifdef SPACETIMEDB_UNSTABLE_FEATURES
// Test HTTP GET request to the module's own schema endpoint
SPACETIMEDB_PROCEDURE(std::string, read_my_schema, ProcedureContext ctx, std::string server_url) {
// Get the module identity (database address)
Identity module_identity = ctx.database_identity();
std::string identity_hex = module_identity.to_hex_string();
while (!server_url.empty() && server_url.back() == '/') {
server_url.pop_back();
}
LOG_INFO("read_my_schema using identity: " + identity_hex);
// Make HTTP GET request to the schema endpoint (matches Rust)
std::string url = server_url + "/v1/database/" + identity_hex + "/schema?version=9";
auto result = ctx.http.get(url);
if (!result.is_ok()) {
LOG_INFO("read_my_schema error: " + result.error());
LOG_PANIC(result.error());
return ""; // Never reached
}
auto& response = result.value();
std::string body = response.body.to_string_utf8_lossy();
LOG_INFO("read_my_schema status: " + std::to_string(response.status_code) + ", body length: " + std::to_string(body.length()));
return body;
}
// Test HTTP request with invalid URL (should fail gracefully)
SPACETIMEDB_PROCEDURE(std::string, invalid_request, ProcedureContext ctx) {
auto result = ctx.http.get("http://foo.invalid/");
if (result.is_ok()) {
// Unexpected success - panic like Rust version
auto& response = result.value();
std::string body = response.body.to_string_utf8_lossy();
LOG_INFO("invalid_request unexpected success: " + body);
LOG_PANIC("Got result from requesting `http://foo.invalid`... huh?\n" + body);
return ""; // Never reached
}
std::string error = result.error();
LOG_INFO("invalid_request expected error: " + error);
return error;
}
#endif // SPACETIMEDB_UNSTABLE_FEATURES
// ============================================================================
// UUID Tests
// ============================================================================
// Test UUID v7 generation and ordering
SPACETIMEDB_PROCEDURE(Unit, sorted_uuids_insert, ProcedureContext ctx) {
ctx.with_tx([](TxContext& tx) {
// Generate and insert 1000 UUIDs
for (int i = 0; i < 1000; i++) {
Uuid uuid = tx.new_uuid_v7();
tx.db[pk_uuid].insert(PkUuid{uuid, 0});
}
// Verify UUIDs are sorted
std::optional<Uuid> last_uuid;
for (const auto& row : tx.db[pk_uuid]) {
if (last_uuid.has_value()) {
if (last_uuid.value() >= row.u) {
LOG_PANIC("UUIDs are not sorted correctly");
}
}
last_uuid = row.u;
}
LOG_INFO("Successfully inserted and verified 1000 sorted UUIDs");
});
return Unit{};
}
// ============================================================================
// Scheduled Procedure Tests
// ============================================================================
// Reducer that schedules the scheduled_proc procedure
SPACETIMEDB_REDUCER(schedule_proc, ReducerContext ctx) {
LOG_INFO("schedule_proc called at timestamp: " + std::to_string(ctx.timestamp.micros_since_epoch()));
// Schedule the procedure to run in 1s (1000ms = 1,000,000 microseconds)
ctx.db[scheduled_proc_table].insert(ScheduledProcTable{
0, // scheduled_id (auto-incremented)
ScheduleAt(TimeDuration::from_micros(1000000)), // 1 second from now
ctx.timestamp, // Store the timestamp at which this reducer was called
42, // x
24 // y
});
return Ok();
}
// Procedure that should be called 1s after schedule_proc
SPACETIMEDB_PROCEDURE(Unit, scheduled_proc, ProcedureContext ctx, ScheduledProcTable data) {
Timestamp reducer_ts = data.reducer_ts;
uint8_t x = data.x;
uint8_t y = data.y;
Timestamp procedure_ts = ctx.timestamp;
LOG_INFO("scheduled_proc called - procedure_ts: " + std::to_string(procedure_ts.micros_since_epoch()) +
", reducer_ts: " + std::to_string(reducer_ts.micros_since_epoch()));
ctx.with_tx([reducer_ts, procedure_ts, x, y](TxContext& tx) {
tx.db[proc_inserts_into].insert(ProcInsertsInto{
reducer_ts,
procedure_ts,
x,
y
});
});
return Unit{};
}