Skip to content

Commit 65ff82e

Browse files
committed
Merge branch 'main' into feat/orm-1102-mysql-introspect
2 parents 9808922 + c238eea commit 65ff82e

13 files changed

Lines changed: 199 additions & 55 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

schema-engine/sql-introspection-tests/tests/multi_schema/sql_server.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,151 @@ async fn multiple_schemas_w_cross_schema_fks_w_duplicate_names_are_introspected(
426426
Ok(())
427427
}
428428

429+
#[test_connector(
430+
tags(Mssql),
431+
preview_features("multiSchema"),
432+
namespaces("Appointments", "Trips", "core")
433+
)]
434+
async fn schemas_with_varying_case(api: &mut TestApi) -> TestResult {
435+
for schema in ["Appointments", "Trips", "core"] {
436+
api.raw_cmd(&format!("CREATE SCHEMA {schema}")).await;
437+
}
438+
439+
let setup = formatdoc! {r#"
440+
CREATE TABLE [Appointments].[Associations] (
441+
[AppointmentID] BIGINT NOT NULL,
442+
[AssociatedAppointmentID] BIGINT NOT NULL,
443+
CONSTRAINT [PK_Associations] PRIMARY KEY CLUSTERED ([AppointmentID],[AssociatedAppointmentID])
444+
);
445+
446+
CREATE TABLE [Appointments].[AssociationTypes] (
447+
[ID] SMALLINT NOT NULL IDENTITY(1,1),
448+
CONSTRAINT [PK_AssociationTypes] PRIMARY KEY CLUSTERED ([ID])
449+
);
450+
451+
CREATE TABLE [Appointments].[billCodes] (
452+
[Id] BIGINT NOT NULL IDENTITY(1,1),
453+
CONSTRAINT [PK_AppointmentBillCode] PRIMARY KEY CLUSTERED ([Id])
454+
);
455+
456+
CREATE TABLE [core].[Clusters] (
457+
[ID] INT NOT NULL IDENTITY(1,1),
458+
CONSTRAINT [PK_Clusters] PRIMARY KEY CLUSTERED ([ID])
459+
);
460+
461+
CREATE TABLE [core].[Containers] (
462+
[ID] SMALLINT NOT NULL IDENTITY(1,1),
463+
CONSTRAINT [PK_Containers] PRIMARY KEY CLUSTERED ([ID])
464+
);
465+
466+
CREATE TABLE [Appointments].[Documents] (
467+
[ID] BIGINT NOT NULL IDENTITY(1,1),
468+
CONSTRAINT [PK_AppointmentBOLs] PRIMARY KEY CLUSTERED ([ID])
469+
);
470+
471+
CREATE TABLE [core].[Sites] (
472+
[ID] BIGINT NOT NULL IDENTITY(1,1),
473+
CONSTRAINT [PK_Sites] PRIMARY KEY CLUSTERED ([ID])
474+
);
475+
476+
CREATE TABLE [Appointments].[statuses] (
477+
[ID] SMALLINT NOT NULL IDENTITY(1,1),
478+
CONSTRAINT [PK_AppointmentStatuses] PRIMARY KEY CLUSTERED ([ID])
479+
);
480+
481+
CREATE TABLE [Trips].[Trips] (
482+
[ID] BIGINT NOT NULL IDENTITY(1,1),
483+
CONSTRAINT [PK_Trips] PRIMARY KEY CLUSTERED ([ID])
484+
);
485+
486+
CREATE TABLE [Trips].[TripTypes] (
487+
[ID] INT NOT NULL IDENTITY(1,1),
488+
CONSTRAINT [PK_TripTypes] PRIMARY KEY CLUSTERED ([ID])
489+
);
490+
"#};
491+
492+
api.raw_cmd(&setup).await;
493+
494+
let expected = expect![[r#"
495+
generator client {
496+
provider = "prisma-client-js"
497+
previewFeatures = ["multiSchema"]
498+
}
499+
500+
datasource db {
501+
provider = "sqlserver"
502+
url = "env(TEST_DATABASE_URL)"
503+
schemas = ["Appointments", "Trips", "core"]
504+
}
505+
506+
model Associations {
507+
AppointmentID BigInt
508+
AssociatedAppointmentID BigInt
509+
510+
@@id([AppointmentID, AssociatedAppointmentID], map: "PK_Associations")
511+
@@schema("Appointments")
512+
}
513+
514+
model AssociationTypes {
515+
ID Int @id(map: "PK_AssociationTypes") @default(autoincrement()) @db.SmallInt
516+
517+
@@schema("Appointments")
518+
}
519+
520+
model billCodes {
521+
Id BigInt @id(map: "PK_AppointmentBillCode") @default(autoincrement())
522+
523+
@@schema("Appointments")
524+
}
525+
526+
model Clusters {
527+
ID Int @id(map: "PK_Clusters") @default(autoincrement())
528+
529+
@@schema("core")
530+
}
531+
532+
model Containers {
533+
ID Int @id(map: "PK_Containers") @default(autoincrement()) @db.SmallInt
534+
535+
@@schema("core")
536+
}
537+
538+
model Documents {
539+
ID BigInt @id(map: "PK_AppointmentBOLs") @default(autoincrement())
540+
541+
@@schema("Appointments")
542+
}
543+
544+
model Sites {
545+
ID BigInt @id(map: "PK_Sites") @default(autoincrement())
546+
547+
@@schema("core")
548+
}
549+
550+
model statuses {
551+
ID Int @id(map: "PK_AppointmentStatuses") @default(autoincrement()) @db.SmallInt
552+
553+
@@schema("Appointments")
554+
}
555+
556+
model Trips {
557+
ID BigInt @id(map: "PK_Trips") @default(autoincrement())
558+
559+
@@schema("Trips")
560+
}
561+
562+
model TripTypes {
563+
ID Int @id(map: "PK_TripTypes") @default(autoincrement())
564+
565+
@@schema("Trips")
566+
}
567+
"#]];
568+
569+
api.expect_datamodel(&expected).await;
570+
571+
Ok(())
572+
}
573+
429574
#[test_connector(tags(Mssql), preview_features("multiSchema"), namespaces("first", "second"))]
430575
async fn defaults_are_introspected(api: &mut TestApi) -> TestResult {
431576
let schema_name = "first";

schema-engine/sql-schema-describer/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ either.workspace = true
3030
async-trait.workspace = true
3131
bigdecimal.workspace = true
3232
enumflags2 = { workspace = true, features = ["serde"] }
33-
indexmap.workspace = true
33+
indexmap = { workspace = true, features = ["serde"] }
3434
indoc.workspace = true
35+
itertools.workspace = true
3536
regex.workspace = true
3637
serde.workspace = true
3738
tracing.workspace = true

schema-engine/sql-schema-describer/src/lib.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub use self::{
2424
walkers::*,
2525
};
2626
pub use either::Either;
27+
use indexmap::IndexSet;
2728
pub use prisma_value::PrismaValue;
2829

2930
use enumflags2::{BitFlag, BitFlags};
@@ -45,7 +46,7 @@ pub trait SqlSchemaDescriberBackend: Send + Sync {
4546
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
4647
pub struct SqlSchema {
4748
/// Namespaces (schemas)
48-
namespaces: Vec<String>,
49+
namespaces: IndexSet<String>,
4950
/// The schema's tables.
5051
tables: Vec<Table>,
5152
/// The schema's enums.
@@ -173,10 +174,7 @@ impl SqlSchema {
173174

174175
/// Find a namespace by name.
175176
pub fn get_namespace_id(&self, name: &str) -> Option<NamespaceId> {
176-
self.namespaces
177-
.binary_search_by(|ns_name| ns_name.as_str().cmp(name))
178-
.ok()
179-
.map(|pos| NamespaceId(pos as u32))
177+
self.namespaces.get_index_of(name).map(|pos| NamespaceId(pos as u32))
180178
}
181179

182180
/// The total number of indexes in the schema.
@@ -321,9 +319,8 @@ impl SqlSchema {
321319
}
322320

323321
pub fn push_namespace(&mut self, name: String) -> NamespaceId {
324-
let id = NamespaceId(self.namespaces.len() as u32);
325-
self.namespaces.push(name);
326-
id
322+
let (id, _) = self.namespaces.insert_full(name);
323+
NamespaceId(id as u32)
327324
}
328325

329326
pub fn push_table(&mut self, name: String, namespace_id: NamespaceId, description: Option<String>) -> TableId {

schema-engine/sql-schema-describer/src/walkers/enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl<'a> EnumWalker<'a> {
1515
pub fn namespace(self) -> Option<&'a str> {
1616
self.schema
1717
.namespaces
18-
.get(self.get().namespace_id.0 as usize)
18+
.get_index(self.get().namespace_id.0 as usize)
1919
.map(|s| s.as_str())
2020
}
2121

schema-engine/sql-schema-describer/src/walkers/table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'a> TableWalker<'a> {
7171
pub fn namespace(self) -> Option<&'a str> {
7272
self.schema
7373
.namespaces
74-
.get(self.table().namespace_id.0 as usize)
74+
.get_index(self.table().namespace_id.0 as usize)
7575
.map(|s| s.as_str())
7676
}
7777

schema-engine/sql-schema-describer/src/walkers/user_defined_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<'a> UserDefinedTypeWalker<'a> {
1818
pub fn namespace(self) -> Option<&'a str> {
1919
self.schema
2020
.namespaces
21-
.get(self.get().namespace_id.0 as usize)
21+
.get_index(self.get().namespace_id.0 as usize)
2222
.map(|s| s.as_str())
2323
}
2424

schema-engine/sql-schema-describer/src/walkers/view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl<'a> ViewWalker<'a> {
2020
pub fn namespace(self) -> Option<&'a str> {
2121
self.schema
2222
.namespaces
23-
.get(self.get().namespace_id.0 as usize)
23+
.get_index(self.get().namespace_id.0 as usize)
2424
.map(|s| s.as_str())
2525
}
2626

schema-engine/sql-schema-describer/tests/describers/mssql_describer_tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ fn all_mssql_column_types_must_work(api: TestApi) {
127127
api.raw_cmd(sql);
128128
let expectation = expect![[r#"
129129
SqlSchema {
130-
namespaces: [
130+
namespaces: {
131131
"dbo",
132-
],
132+
},
133133
tables: [
134134
Table {
135135
namespace_id: NamespaceId(
@@ -837,10 +837,10 @@ fn multiple_schemas_with_same_table_names_are_described(api: TestApi) {
837837

838838
let expected_schema = expect![[r#"
839839
SqlSchema {
840-
namespaces: [
840+
namespaces: {
841841
"schema_0",
842842
"schema_1",
843-
],
843+
},
844844
tables: [
845845
Table {
846846
namespace_id: NamespaceId(
@@ -1021,10 +1021,10 @@ fn multiple_schemas_with_same_foreign_key_are_described(api: TestApi) {
10211021

10221022
let expected_schema = expect![[r#"
10231023
SqlSchema {
1024-
namespaces: [
1024+
namespaces: {
10251025
"schema_0",
10261026
"schema_1",
1027-
],
1027+
},
10281028
tables: [
10291029
Table {
10301030
namespace_id: NamespaceId(

schema-engine/sql-schema-describer/tests/describers/mysql_describer_tests.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn all_mysql_column_types_must_work(api: TestApi) {
8989
api.raw_cmd(sql);
9090
let expectation = expect![[r#"
9191
SqlSchema {
92-
namespaces: [],
92+
namespaces: {},
9393
tables: [
9494
Table {
9595
namespace_id: NamespaceId(
@@ -925,7 +925,7 @@ fn all_mariadb_column_types_must_work(api: TestApi) {
925925
api.raw_cmd(sql);
926926
let expectation = expect![[r#"
927927
SqlSchema {
928-
namespaces: [],
928+
namespaces: {},
929929
tables: [
930930
Table {
931931
namespace_id: NamespaceId(
@@ -1754,9 +1754,9 @@ fn all_mysql_8_column_types_must_work(api: TestApi) {
17541754

17551755
let expectation = expect![[r#"
17561756
SqlSchema {
1757-
namespaces: [
1757+
namespaces: {
17581758
"all_mysql_8_column_types_must_work",
1759-
],
1759+
},
17601760
tables: [
17611761
Table {
17621762
namespace_id: NamespaceId(
@@ -2649,9 +2649,9 @@ fn constraints_from_other_databases_should_not_be_introspected(api: TestApi) {
26492649

26502650
let expectation = expect![[r#"
26512651
SqlSchema {
2652-
namespaces: [
2652+
namespaces: {
26532653
"constraints_from_other_databases_should_not_be_introspected",
2654-
],
2654+
},
26552655
tables: [
26562656
Table {
26572657
namespace_id: NamespaceId(
@@ -2845,9 +2845,9 @@ fn introspected_default_strings_should_be_unescaped(api: TestApi) {
28452845
api.raw_cmd(create_table);
28462846
let expectation = expect![[r#"
28472847
SqlSchema {
2848-
namespaces: [
2848+
namespaces: {
28492849
"introspected_default_strings_should_be_unescaped",
2850-
],
2850+
},
28512851
tables: [
28522852
Table {
28532853
namespace_id: NamespaceId(
@@ -2925,9 +2925,9 @@ fn escaped_quotes_in_string_defaults_must_be_unescaped(api: TestApi) {
29252925

29262926
let expectation = expect![[r#"
29272927
SqlSchema {
2928-
namespaces: [
2928+
namespaces: {
29292929
"escaped_quotes_in_string_defaults_must_be_unescaped",
2930-
],
2930+
},
29312931
tables: [
29322932
Table {
29332933
namespace_id: NamespaceId(
@@ -3036,9 +3036,9 @@ fn escaped_backslashes_in_string_literals_must_be_unescaped(api: TestApi) {
30363036

30373037
let expectation = expect![[r#"
30383038
SqlSchema {
3039-
namespaces: [
3039+
namespaces: {
30403040
"escaped_backslashes_in_string_literals_must_be_unescaped",
3041-
],
3041+
},
30423042
tables: [
30433043
Table {
30443044
namespace_id: NamespaceId(
@@ -3127,9 +3127,9 @@ fn function_expression_defaults_are_described_as_dbgenerated(api: TestApi) {
31273127

31283128
let expectation = expect![[r#"
31293129
SqlSchema {
3130-
namespaces: [
3130+
namespaces: {
31313131
"function_expression_defaults_are_described_as_dbgenerated",
3132-
],
3132+
},
31333133
tables: [
31343134
Table {
31353135
namespace_id: NamespaceId(

0 commit comments

Comments
 (0)