@@ -35,11 +35,12 @@ import { checkBillingEnabled } from "../gcp/cloudbilling";
3535async function setupSchemaIfNecessary (
3636 instanceId : string ,
3737 databaseId : string ,
38+ schemaName : string ,
3839 options : Options ,
3940) : Promise < SchemaSetupStatus . GreenField | SchemaSetupStatus . BrownField > {
4041 try {
4142 await setupIAMUsers ( instanceId , options ) ;
42- const schemaInfo = await getSchemaMetadata ( instanceId , databaseId , DEFAULT_SCHEMA , options ) ;
43+ const schemaInfo = await getSchemaMetadata ( instanceId , databaseId , schemaName , options ) ;
4344 switch ( schemaInfo . setupStatus ) {
4445 case SchemaSetupStatus . BrownField :
4546 case SchemaSetupStatus . GreenField :
@@ -77,12 +78,13 @@ export async function diffSchema(
7778 setSchemaValidationMode ( schema , validationMode ) ;
7879 displayStartSchemaDiff ( validationMode ) ;
7980
80- const { serviceName, instanceName, databaseId, instanceId } = getIdentifiers ( schema ) ;
81+ const { serviceName, instanceName, databaseId, instanceId, schemaName } = getIdentifiers ( schema ) ;
8182 await ensureServiceIsConnectedToCloudSql (
8283 serviceName ,
8384 instanceName ,
8485 databaseId ,
8586 /* linkIfNotConnected=*/ false ,
87+ schemaName ,
8688 ) ;
8789
8890 let incompatible : IncompatibleSqlSchemaError | undefined = undefined ;
@@ -162,12 +164,13 @@ export async function migrateSchema(args: {
162164 displayStartSchemaDiff ( validationMode ) ;
163165
164166 const projectId = needProjectId ( options ) ;
165- const { serviceName, instanceId, instanceName, databaseId } = getIdentifiers ( schema ) ;
167+ const { serviceName, instanceId, instanceName, databaseId, schemaName } = getIdentifiers ( schema ) ;
166168 await ensureServiceIsConnectedToCloudSql (
167169 serviceName ,
168170 instanceName ,
169171 databaseId ,
170172 /* linkIfNotConnected=*/ true ,
173+ schemaName ,
171174 ) ;
172175
173176 // Check if Cloud SQL instance is still being created.
@@ -196,7 +199,7 @@ export async function migrateSchema(args: {
196199 }
197200
198201 // Make sure database is setup.
199- await setupSchemaIfNecessary ( instanceId , databaseId , options ) ;
202+ await setupSchemaIfNecessary ( instanceId , databaseId , schemaName , options ) ;
200203
201204 let diffs : Diff [ ] = [ ] ;
202205 try {
@@ -247,6 +250,7 @@ export async function migrateSchema(args: {
247250 options,
248251 databaseId,
249252 instanceId,
253+ schemaName,
250254 incompatibleSchemaError : incompatible ,
251255 choice : migrationMode ,
252256 } ) ;
@@ -295,6 +299,7 @@ export async function migrateSchema(args: {
295299 options,
296300 databaseId,
297301 instanceId,
302+ schemaName,
298303 incompatibleSchemaError : incompatible ,
299304 choice : migrationMode ,
300305 } ) ;
@@ -349,17 +354,23 @@ export async function grantRoleToUserInSchema(options: Options, schema: Schema)
349354 const role = options . role as string ;
350355 const email = options . email as string ;
351356
352- const { serviceName, instanceId, instanceName, databaseId } = getIdentifiers ( schema ) ;
357+ const { serviceName, instanceId, instanceName, databaseId, schemaName } = getIdentifiers ( schema ) ;
353358
354359 await ensureServiceIsConnectedToCloudSql (
355360 serviceName ,
356361 instanceName ,
357362 databaseId ,
358363 /* linkIfNotConnected=*/ false ,
364+ schemaName ,
359365 ) ;
360366
361367 // Make sure we have the right setup for the requested role grant.
362- const schemaSetupStatus = await setupSchemaIfNecessary ( instanceId , databaseId , options ) ;
368+ const schemaSetupStatus = await setupSchemaIfNecessary (
369+ instanceId ,
370+ databaseId ,
371+ schemaName ,
372+ options ,
373+ ) ;
363374
364375 // Edge case: we can't grant firebase owner unless database is greenfield.
365376 if ( schemaSetupStatus !== SchemaSetupStatus . GreenField && role === "owner" ) {
@@ -369,7 +380,7 @@ export async function grantRoleToUserInSchema(options: Options, schema: Schema)
369380 }
370381
371382 // Grant the role to the user.
372- await grantRoleTo ( options , instanceId , databaseId , role , email ) ;
383+ await grantRoleTo ( options , instanceId , databaseId , role , email , schemaName ) ;
373384}
374385
375386function diffsEqual ( x : Diff [ ] , y : Diff [ ] ) : boolean {
@@ -399,6 +410,7 @@ export function getIdentifiers(schema: Schema): {
399410 instanceName : string ;
400411 instanceId : string ;
401412 databaseId : string ;
413+ schemaName : string ;
402414 serviceName : string ;
403415} {
404416 const postgresDatasource = schema . datasources . find ( ( d ) => d . postgresql ) ;
@@ -415,11 +427,13 @@ export function getIdentifiers(schema: Schema): {
415427 ) ;
416428 }
417429 const instanceId = instanceName . split ( "/" ) . pop ( ) ! ;
430+ const schemaName = postgresDatasource ?. postgresql ?. schema || DEFAULT_SCHEMA ;
418431 const serviceName = serviceNameFromSchema ( schema ) ;
419432 return {
420433 databaseId,
421434 instanceId,
422435 instanceName,
436+ schemaName,
423437 serviceName,
424438 } ;
425439}
@@ -442,9 +456,10 @@ async function handleIncompatibleSchemaError(args: {
442456 options : Options ;
443457 instanceId : string ;
444458 databaseId : string ;
459+ schemaName : string ;
445460 choice : "all" | "safe" | "none" ;
446461} ) : Promise < Diff [ ] > {
447- const { incompatibleSchemaError, options, instanceId, databaseId, choice } = args ;
462+ const { incompatibleSchemaError, options, instanceId, databaseId, schemaName , choice } = args ;
448463 const commandsToExecute = incompatibleSchemaError . diffs . filter ( ( d ) => {
449464 switch ( choice ) {
450465 case "all" :
@@ -467,7 +482,7 @@ async function handleIncompatibleSchemaError(args: {
467482 ${ diffsToString ( commandsToExecuteBySuperUser ) } ` ) ;
468483 }
469484
470- const schemaInfo = await getSchemaMetadata ( instanceId , databaseId , DEFAULT_SCHEMA , options ) ;
485+ const schemaInfo = await getSchemaMetadata ( instanceId , databaseId , schemaName , options ) ;
471486 if ( schemaInfo . setupStatus !== SchemaSetupStatus . GreenField ) {
472487 throw new FirebaseError (
473488 `Brownfield database are protected from SQL changes by Data Connect.\n` +
@@ -482,7 +497,7 @@ async function handleIncompatibleSchemaError(args: {
482497 options ,
483498 instanceId ,
484499 databaseId ,
485- firebaseowner ( databaseId ) ,
500+ firebaseowner ( databaseId , schemaName ) ,
486501 ( await getIAMUser ( options ) ) . user ,
487502 ) )
488503 ) {
@@ -493,7 +508,7 @@ async function handleIncompatibleSchemaError(args: {
493508 }
494509 const account = ( await requireAuth ( options ) ) ! ;
495510 logLabeledBullet ( "dataconnect" , `Granting firebaseowner role to myself ${ account } ...` ) ;
496- await grantRoleTo ( options , instanceId , databaseId , "owner" , account ) ;
511+ await grantRoleTo ( options , instanceId , databaseId , "owner" , account , schemaName ) ;
497512 }
498513
499514 if ( commandsToExecuteBySuperUser . length ) {
@@ -512,7 +527,10 @@ async function handleIncompatibleSchemaError(args: {
512527 options ,
513528 instanceId ,
514529 databaseId ,
515- [ `SET ROLE "${ firebaseowner ( databaseId ) } "` , ...commandsToExecuteByOwner . map ( ( d ) => d . sql ) ] ,
530+ [
531+ `SET ROLE "${ firebaseowner ( databaseId , schemaName ) } "` ,
532+ ...commandsToExecuteByOwner . map ( ( d ) => d . sql ) ,
533+ ] ,
516534 /** silent=*/ false ,
517535 ) ;
518536 return incompatibleSchemaError . diffs ;
@@ -645,6 +663,7 @@ export async function ensureServiceIsConnectedToCloudSql(
645663 instanceName : string ,
646664 databaseId : string ,
647665 linkIfNotConnected : boolean ,
666+ schemaName ?: string ,
648667) : Promise < void > {
649668 let currentSchema = await getSchema ( serviceName ) ;
650669 let postgresql = currentSchema ?. datasources ?. find ( ( d ) => d . postgresql ) ?. postgresql ;
@@ -720,6 +739,7 @@ export async function ensureServiceIsConnectedToCloudSql(
720739 try {
721740 postgresql . schemaValidation = "STRICT" ;
722741 postgresql . database = databaseId ;
742+ postgresql . schema = schemaName ;
723743 postgresql . cloudSql = { instance : instanceName } ;
724744 await upsertSchema ( currentSchema , /** validateOnly=*/ false ) ;
725745 } catch ( err : any ) {
0 commit comments