1
1
from .. import Smoketest
2
2
import sys
3
3
import logging
4
+ import re
5
+
6
+ # 7-bit C1 ANSI sequences
7
+ ansi_escape = re .compile (r'''
8
+ \x1B # ESC
9
+ (?: # 7-bit C1 Fe (except CSI)
10
+ [@-Z\\-_]
11
+ | # or [ for CSI, followed by a control sequence
12
+ \[
13
+ [0-?]* # Parameter bytes
14
+ [ -/]* # Intermediate bytes
15
+ [@-~] # Final byte
16
+ )
17
+ ''' , re .VERBOSE )
18
+
19
+ def strip_ansi_escape_codes (text : str ) -> str :
20
+ return ansi_escape .sub ('' , text )
4
21
5
22
6
23
class AddTableAutoMigration (Smoketest ):
@@ -25,7 +42,11 @@ class AddTableAutoMigration(Smoketest):
25
42
}
26
43
27
44
#[spacetimedb::table(name = point_mass)]
45
+ #[index(name = point_masses_by_mass, btree(columns = position))]
28
46
pub struct PointMass {
47
+ #[primary_key]
48
+ #[auto_inc]
49
+ id: u64,
29
50
mass: f64,
30
51
/// This used to cause an error when check_compatible did not resolve types in a `ModuleDef`.
31
52
position: Vector2,
@@ -37,12 +58,82 @@ class AddTableAutoMigration(Smoketest):
37
58
y: f64,
38
59
}
39
60
61
+ #[spacetimedb::table(name = scheduled_table, scheduled(send_scheduled_message), public)]
62
+ pub struct ScheduledTable {
63
+ #[primary_key]
64
+ #[auto_inc]
65
+ scheduled_id: u64,
66
+ #[scheduled_at]
67
+ scheduled_at: spacetimedb::ScheduleAt,
68
+ text: String,
69
+ }
70
+
71
+ #[spacetimedb::reducer]
72
+ fn send_scheduled_message(_ctx: &ReducerContext, arg: ScheduledTable) {
73
+ let _ = arg.text;
74
+ let _ = arg.scheduled_at;
75
+ let _ = arg.scheduled_id;
76
+ }
77
+
40
78
spacetimedb::filter!("SELECT * FROM person");
41
79
"""
42
80
43
- MODULE_CODE_UPDATED = (
44
- MODULE_CODE
45
- + """
81
+ MODULE_CODE_UPDATED = """
82
+ use spacetimedb::{log, ReducerContext, Table, SpacetimeType};
83
+
84
+ #[spacetimedb::table(name = person)]
85
+ pub struct Person {
86
+ name: String,
87
+ }
88
+
89
+ #[spacetimedb::reducer]
90
+ pub fn add_person(ctx: &ReducerContext, name: String) {
91
+ ctx.db.person().insert(Person { name });
92
+ }
93
+
94
+ #[spacetimedb::reducer]
95
+ pub fn print_persons(ctx: &ReducerContext, prefix: String) {
96
+ for person in ctx.db.person().iter() {
97
+ log::info!("{}: {}", prefix, person.name);
98
+ }
99
+ }
100
+
101
+ #[spacetimedb::table(name = point_mass, public)] // private -> public
102
+ // remove index
103
+ pub struct PointMass {
104
+ // remove primary_key and auto_inc
105
+ id: u64,
106
+ mass: f64,
107
+ /// This used to cause an error when check_compatible did not resolve types in a `ModuleDef`.
108
+ position: Vector2,
109
+ }
110
+
111
+ #[derive(SpacetimeType, Clone, Copy)]
112
+ pub struct Vector2 {
113
+ x: f64,
114
+ y: f64,
115
+ }
116
+
117
+ // TODO: once removing schedules is implemented, remove the schedule here.
118
+ #[spacetimedb::table(name = scheduled_table, scheduled(send_scheduled_message), public)]
119
+ pub struct ScheduledTable {
120
+ #[primary_key]
121
+ #[auto_inc]
122
+ scheduled_id: u64,
123
+ #[scheduled_at]
124
+ scheduled_at: spacetimedb::ScheduleAt,
125
+ text: String,
126
+ }
127
+
128
+ #[spacetimedb::reducer]
129
+ fn send_scheduled_message(_ctx: &ReducerContext, arg: ScheduledTable) {
130
+ let _ = arg.text;
131
+ let _ = arg.scheduled_at;
132
+ let _ = arg.scheduled_id;
133
+ }
134
+
135
+ spacetimedb::filter!("SELECT * FROM person");
136
+
46
137
#[spacetimedb::table(name = book)]
47
138
pub struct Book {
48
139
isbn: String,
@@ -61,8 +152,44 @@ class AddTableAutoMigration(Smoketest):
61
152
}
62
153
63
154
spacetimedb::filter!("SELECT * FROM book");
155
+
156
+ #[spacetimedb::table(name = parabolas)]
157
+ #[index(name = parabolas_by_b_c, btree(columns = [b, c]))]
158
+ pub struct Parabola {
159
+ #[primary_key]
160
+ #[auto_inc]
161
+ id: u64,
162
+ a: f64,
163
+ b: f64,
164
+ c: f64,
165
+ }
64
166
"""
65
- )
167
+
168
+ EXPECTED_MIGRATION_REPORT = """--------------
169
+ Performed automatic migration
170
+ --------------
171
+ - Removed index `point_mass_id_idx_btree` on columns [`id`] of table `point_mass`
172
+ - Removed unique constraint `point_mass_id_key` on columns [`id`] of table `point_mass`
173
+ - Removed auto-increment constraint `point_mass_id_seq` on column `id` of table `point_mass`
174
+ - Created table: `book` (private)
175
+ - Columns:
176
+ - `isbn`: String
177
+ - Created table: `parabolas` (private)
178
+ - Columns:
179
+ - `id`: U64
180
+ - `a`: F64
181
+ - `b`: F64
182
+ - `c`: F64
183
+ - Unique constraints:
184
+ - `parabolas_id_key` on [`id`]
185
+ - Indexes:
186
+ - `parabolas_id_idx_btree` on [`id`]
187
+ - Auto-increment constraints:
188
+ - `parabolas_id_seq` on `id`
189
+ - Created row level security policy:
190
+ `SELECT * FROM book`
191
+ - Changed access for table `point_mass` (private -> public)"""
192
+
66
193
67
194
def assertSql (self , sql , expected ):
68
195
self .maxDiff = None
@@ -98,7 +225,15 @@ def test_add_table_auto_migration(self):
98
225
)
99
226
100
227
self .write_module_code (self .MODULE_CODE_UPDATED )
101
- self .publish_module (self .database_identity , clear = False )
228
+ output = self .publish_module (self .database_identity , clear = False )
229
+ output = strip_ansi_escape_codes (output )
230
+
231
+ print ("got output\n " , output )
232
+
233
+ # Remark: if this test ever fails mysteriously,
234
+ # try double-checking the pretty printing code for trailing spaces before newlines.
235
+ # Also make sure the pretty-printing is deterministic.
236
+ self .assertIn (self .EXPECTED_MIGRATION_REPORT , output )
102
237
103
238
logging .info ("Updated" )
104
239
0 commit comments