@@ -1112,3 +1112,384 @@ async fn test_issue_303() -> Result<()> {
1112
1112
1113
1113
Ok ( ( ) )
1114
1114
}
1115
+
1116
+ #[ tokio:: test]
1117
+ async fn test_issue_328 ( ) -> Result < ( ) > {
1118
+ let factory = ServerFactory :: default ( ) ;
1119
+ let mut fs = MemoryFileSystem :: default ( ) ;
1120
+ let test_db = get_new_test_db ( ) . await ;
1121
+
1122
+ let setup = r#"
1123
+ create table public.users (
1124
+ id serial primary key,
1125
+ name varchar(255) not null
1126
+ );
1127
+ "# ;
1128
+
1129
+ test_db
1130
+ . execute ( setup)
1131
+ . await
1132
+ . expect ( "Failed to setup test database" ) ;
1133
+
1134
+ let mut conf = PartialConfiguration :: init ( ) ;
1135
+ conf. merge_with ( PartialConfiguration {
1136
+ db : Some ( PartialDatabaseConfiguration {
1137
+ database : Some (
1138
+ test_db
1139
+ . connect_options ( )
1140
+ . get_database ( )
1141
+ . unwrap ( )
1142
+ . to_string ( ) ,
1143
+ ) ,
1144
+ ..Default :: default ( )
1145
+ } ) ,
1146
+ ..Default :: default ( )
1147
+ } ) ;
1148
+ fs. insert (
1149
+ url ! ( "postgrestools.jsonc" ) . to_file_path ( ) . unwrap ( ) ,
1150
+ serde_json:: to_string_pretty ( & conf) . unwrap ( ) ,
1151
+ ) ;
1152
+
1153
+ let ( service, client) = factory
1154
+ . create_with_fs ( None , DynRef :: Owned ( Box :: new ( fs) ) )
1155
+ . into_inner ( ) ;
1156
+
1157
+ let ( stream, sink) = client. split ( ) ;
1158
+ let mut server = Server :: new ( service) ;
1159
+
1160
+ let ( sender, mut receiver) = channel ( CHANNEL_BUFFER_SIZE ) ;
1161
+ let reader = tokio:: spawn ( client_handler ( stream, sink, sender) ) ;
1162
+
1163
+ server. initialize ( ) . await ?;
1164
+ server. initialized ( ) . await ?;
1165
+
1166
+ server. load_configuration ( ) . await ?;
1167
+
1168
+ server
1169
+ . open_document ( "-- Create the company table\n CREATE TABLE company (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n name VARCHAR(255) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL\n );\n \n -- Create the business table\n CREATE TABLE business (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n name VARCHAR(255) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL,\n company_id UUID REFERENCES company(id) NOT NULL,\n INDEX (company_id)\n );" )
1170
+ . await ?;
1171
+
1172
+ let notification = tokio:: time:: timeout ( Duration :: from_secs ( 5 ) , async {
1173
+ loop {
1174
+ match receiver. next ( ) . await {
1175
+ Some ( ServerNotification :: PublishDiagnostics ( msg) ) => {
1176
+ if msg
1177
+ . diagnostics
1178
+ . iter ( )
1179
+ . any ( |d| d. message . contains ( "column \" unknown\" does not exist" ) )
1180
+ {
1181
+ return true ;
1182
+ }
1183
+ }
1184
+ _ => continue ,
1185
+ }
1186
+ }
1187
+ } )
1188
+ . await
1189
+ . is_ok ( ) ;
1190
+
1191
+ assert ! ( notification, "expected diagnostics for unknown column" ) ;
1192
+
1193
+ server. shutdown ( ) . await ?;
1194
+ reader. abort ( ) ;
1195
+
1196
+ Ok ( ( ) )
1197
+ }
1198
+
1199
+ #[ tokio:: test]
1200
+ async fn test_issue_327 ( ) -> Result < ( ) > {
1201
+ let factory = ServerFactory :: default ( ) ;
1202
+ let mut fs = MemoryFileSystem :: default ( ) ;
1203
+ let test_db = get_new_test_db ( ) . await ;
1204
+
1205
+ let setup = r#"
1206
+ create table public.users (
1207
+ id serial primary key,
1208
+ name varchar(255) not null
1209
+ );
1210
+ "# ;
1211
+
1212
+ test_db
1213
+ . execute ( setup)
1214
+ . await
1215
+ . expect ( "Failed to setup test database" ) ;
1216
+
1217
+ let mut conf = PartialConfiguration :: init ( ) ;
1218
+ conf. merge_with ( PartialConfiguration {
1219
+ db : Some ( PartialDatabaseConfiguration {
1220
+ database : Some (
1221
+ test_db
1222
+ . connect_options ( )
1223
+ . get_database ( )
1224
+ . unwrap ( )
1225
+ . to_string ( ) ,
1226
+ ) ,
1227
+ ..Default :: default ( )
1228
+ } ) ,
1229
+ ..Default :: default ( )
1230
+ } ) ;
1231
+ fs. insert (
1232
+ url ! ( "postgrestools.jsonc" ) . to_file_path ( ) . unwrap ( ) ,
1233
+ serde_json:: to_string_pretty ( & conf) . unwrap ( ) ,
1234
+ ) ;
1235
+
1236
+ let ( service, client) = factory
1237
+ . create_with_fs ( None , DynRef :: Owned ( Box :: new ( fs) ) )
1238
+ . into_inner ( ) ;
1239
+
1240
+ let ( stream, sink) = client. split ( ) ;
1241
+ let mut server = Server :: new ( service) ;
1242
+
1243
+ let ( sender, _) = channel ( CHANNEL_BUFFER_SIZE ) ;
1244
+ let reader = tokio:: spawn ( client_handler ( stream, sink, sender) ) ;
1245
+
1246
+ server. initialize ( ) . await ?;
1247
+ server. initialized ( ) . await ?;
1248
+
1249
+ server. load_configuration ( ) . await ?;
1250
+
1251
+ // Initial document content - a complex SQL file with multiple statements
1252
+ let initial_content = r#"/* https://supabase.com/docs/guides/database/postgres/custom-claims-and-role-based-access-control-rbac#create-a-table-to-track-user-roles-and-permissions */
1253
+ -----------------------------
1254
+ /* User Permission Levels */
1255
+ ---------------------------
1256
+ CREATE TYPE public.user_permission_level
1257
+ AS ENUM('admin', 'manager', 'member');
1258
+
1259
+
1260
+ CREATE SCHEMA private;
1261
+
1262
+ sadjhkyjcxv sd 23
1263
+
1264
+
1265
+ CREATE TABLE private.user_permission_levels (
1266
+ user_id UUID PRIMARY KEY,
1267
+ permission_level user_permission_level NOT NULL,
1268
+
1269
+ CONSTRAINT "user_permission_levels_user_id_fkey"
1270
+ FOREIGN KEY (user_id)
1271
+ REFERENCES auth.users (id)
1272
+ ON UPDATE CASCADE
1273
+ ON DELETE CASCADE
1274
+ );
1275
+
1276
+
1277
+ COMMENT ON TABLE private.user_permission_levels
1278
+ IS 'Permission levels for each user.';
1279
+
1280
+
1281
+ /*
1282
+ ALTER TABLE private.user_permission_levels ENABLE ROW LEVEL SECURITY; */
1283
+ /*
1284
+ GRANT ALL ON TABLE private.user_permission_levels TO supabase_auth_admin; */
1285
+ /* CREATE POLICY "Allow auth admin to read user permission levels" ON private.user_permission_levels FOR
1286
+ SELECT
1287
+ TO supabase_auth_admin USING (TRUE); */
1288
+ /* */
1289
+ -------------------------------
1290
+ /* Custom Access Token Hook */
1291
+ /* Executed while building JWT for user access token */
1292
+ /* Must be enabled in Supabase Dashboard (for managed) or in config.toml (for local dev) */
1293
+ ------------------------------------------------------------------------------------------"# ;
1294
+
1295
+ server
1296
+ . open_named_document ( initial_content, url ! ( "document.sql" ) )
1297
+ . await ?;
1298
+
1299
+ server
1300
+ . change_document (
1301
+ 21 ,
1302
+ vec ! [ TextDocumentContentChangeEvent {
1303
+ range: Some ( Range {
1304
+ start: Position {
1305
+ line: 9 ,
1306
+ character: 0 ,
1307
+ } ,
1308
+ end: Position {
1309
+ line: 10 ,
1310
+ character: 17 ,
1311
+ } ,
1312
+ } ) ,
1313
+ range_length: Some ( 19 ) ,
1314
+ text: "" . to_string( ) ,
1315
+ } ] ,
1316
+ )
1317
+ . await ?;
1318
+
1319
+ server
1320
+ . change_document (
1321
+ 22 ,
1322
+ vec ! [ TextDocumentContentChangeEvent {
1323
+ range: Some ( Range {
1324
+ start: Position {
1325
+ line: 8 ,
1326
+ character: 22 ,
1327
+ } ,
1328
+ end: Position {
1329
+ line: 9 ,
1330
+ character: 0 ,
1331
+ } ,
1332
+ } ) ,
1333
+ range_length: Some ( 2 ) ,
1334
+ text: "" . to_string( ) ,
1335
+ } ] ,
1336
+ )
1337
+ . await ?;
1338
+
1339
+ server
1340
+ . change_document (
1341
+ 50 ,
1342
+ vec ! [ TextDocumentContentChangeEvent {
1343
+ range: Some ( Range {
1344
+ start: Position {
1345
+ line: 0 ,
1346
+ character: 0 ,
1347
+ } ,
1348
+ end: Position {
1349
+ line: 0 ,
1350
+ character: 0 ,
1351
+ } ,
1352
+ } ) ,
1353
+ range_length: Some ( 0 ) ,
1354
+ text: "-" . to_string( ) ,
1355
+ } ] ,
1356
+ )
1357
+ . await ?;
1358
+
1359
+ server
1360
+ . change_document (
1361
+ 51 ,
1362
+ vec ! [ TextDocumentContentChangeEvent {
1363
+ range: Some ( Range {
1364
+ start: Position {
1365
+ line: 0 ,
1366
+ character: 1 ,
1367
+ } ,
1368
+ end: Position {
1369
+ line: 0 ,
1370
+ character: 1 ,
1371
+ } ,
1372
+ } ) ,
1373
+ range_length: Some ( 0 ) ,
1374
+ text: "-" . to_string( ) ,
1375
+ } ] ,
1376
+ )
1377
+ . await ?;
1378
+
1379
+ server
1380
+ . change_document (
1381
+ 52 ,
1382
+ vec ! [ TextDocumentContentChangeEvent {
1383
+ range: Some ( Range {
1384
+ start: Position {
1385
+ line: 0 ,
1386
+ character: 2 ,
1387
+ } ,
1388
+ end: Position {
1389
+ line: 0 ,
1390
+ character: 2 ,
1391
+ } ,
1392
+ } ) ,
1393
+ range_length: Some ( 0 ) ,
1394
+ text: " " . to_string( ) ,
1395
+ } ] ,
1396
+ )
1397
+ . await ?;
1398
+
1399
+ server
1400
+ . change_document (
1401
+ 57 ,
1402
+ vec ! [
1403
+ TextDocumentContentChangeEvent {
1404
+ range: Some ( Range {
1405
+ start: Position {
1406
+ line: 33 ,
1407
+ character: 0 ,
1408
+ } ,
1409
+ end: Position {
1410
+ line: 33 ,
1411
+ character: 0 ,
1412
+ } ,
1413
+ } ) ,
1414
+ range_length: Some ( 0 ) ,
1415
+ text: "-" . to_string( ) ,
1416
+ } ,
1417
+ TextDocumentContentChangeEvent {
1418
+ range: Some ( Range {
1419
+ start: Position {
1420
+ line: 32 ,
1421
+ character: 0 ,
1422
+ } ,
1423
+ end: Position {
1424
+ line: 32 ,
1425
+ character: 0 ,
1426
+ } ,
1427
+ } ) ,
1428
+ range_length: Some ( 0 ) ,
1429
+ text: "-" . to_string( ) ,
1430
+ } ,
1431
+ TextDocumentContentChangeEvent {
1432
+ range: Some ( Range {
1433
+ start: Position {
1434
+ line: 31 ,
1435
+ character: 0 ,
1436
+ } ,
1437
+ end: Position {
1438
+ line: 31 ,
1439
+ character: 0 ,
1440
+ } ,
1441
+ } ) ,
1442
+ range_length: Some ( 0 ) ,
1443
+ text: "-" . to_string( ) ,
1444
+ } ,
1445
+ TextDocumentContentChangeEvent {
1446
+ range: Some ( Range {
1447
+ start: Position {
1448
+ line: 30 ,
1449
+ character: 0 ,
1450
+ } ,
1451
+ end: Position {
1452
+ line: 30 ,
1453
+ character: 0 ,
1454
+ } ,
1455
+ } ) ,
1456
+ range_length: Some ( 0 ) ,
1457
+ text: "-" . to_string( ) ,
1458
+ } ,
1459
+ TextDocumentContentChangeEvent {
1460
+ range: Some ( Range {
1461
+ start: Position {
1462
+ line: 29 ,
1463
+ character: 0 ,
1464
+ } ,
1465
+ end: Position {
1466
+ line: 29 ,
1467
+ character: 0 ,
1468
+ } ,
1469
+ } ) ,
1470
+ range_length: Some ( 0 ) ,
1471
+ text: "-" . to_string( ) ,
1472
+ } ,
1473
+ TextDocumentContentChangeEvent {
1474
+ range: Some ( Range {
1475
+ start: Position {
1476
+ line: 28 ,
1477
+ character: 0 ,
1478
+ } ,
1479
+ end: Position {
1480
+ line: 28 ,
1481
+ character: 0 ,
1482
+ } ,
1483
+ } ) ,
1484
+ range_length: Some ( 0 ) ,
1485
+ text: "-" . to_string( ) ,
1486
+ } ,
1487
+ ] ,
1488
+ )
1489
+ . await ?;
1490
+
1491
+ server. shutdown ( ) . await ?;
1492
+ reader. abort ( ) ;
1493
+
1494
+ Ok ( ( ) )
1495
+ }
0 commit comments