Skip to content

Commit

Permalink
fix: Provision same named schema to ensure same named mutation (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
morgsmccauley authored Jul 27, 2023
1 parent 466e787 commit d61a707
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ exports[`HasuraClient adds a datasource 1`] = `
},
},
},
"customization": {
"root_fields": {
"prefix": "morgs_near_",
},
"type_names": {
"prefix": "morgs_near_",
},
},
"name": "morgs_near",
},
"type": "pg_add_source",
Expand Down
8 changes: 0 additions & 8 deletions indexer-js-queue-handler/hasura-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,6 @@ export default class HasuraClient {
},
},
},
customization: {
root_fields: {
prefix: `${userName}_`,
},
type_names: {
prefix: `${userName}_`,
},
},
});
}
}
9 changes: 4 additions & 5 deletions indexer-js-queue-handler/provisioner.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default class Provisioner {

const databaseName = sanitizedAccountId;
const userName = sanitizedAccountId;
const schemaName = sanitizedFunctionName;
const schemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;

try {
if (!await this.hasuraClient.doesSourceExist(databaseName)) {
Expand All @@ -153,10 +153,9 @@ export default class Provisioner {
}

// Untrack tables from old schema to prevent conflicts with new DB
const oldSchemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;
if (await this.hasuraClient.doesSchemaExist(HasuraClient.DEFAULT_DATABASE, oldSchemaName)) {
const tableNames = await this.getTableNames(oldSchemaName, HasuraClient.DEFAULT_DATABASE);
await this.hasuraClient.untrackTables(HasuraClient.DEFAULT_DATABASE, oldSchemaName, tableNames);
if (await this.hasuraClient.doesSchemaExist(HasuraClient.DEFAULT_DATABASE, schemaName)) {
const tableNames = await this.getTableNames(schemaName, HasuraClient.DEFAULT_DATABASE);
await this.hasuraClient.untrackTables(HasuraClient.DEFAULT_DATABASE, schemaName, tableNames);
}

await this.createSchema(databaseName, schemaName);
Expand Down
26 changes: 13 additions & 13 deletions indexer-js-queue-handler/provisioner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('Provisioner', () => {
const databaseSchema = 'CREATE TABLE blocks (height numeric)';
const error = new Error('some error');
const defaultDatabase = 'default';
const oldSchemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;
const schemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;

const password = 'password';
const crypto = {
Expand Down Expand Up @@ -91,12 +91,12 @@ describe('Provisioner', () => {
['REVOKE CONNECT ON DATABASE morgs_near FROM PUBLIC'],
]);
expect(hasuraClient.addDatasource).toBeCalledWith(sanitizedAccountId, password, sanitizedAccountId);
expect(hasuraClient.createSchema).toBeCalledWith(sanitizedAccountId, sanitizedFunctionName);
expect(hasuraClient.runMigrations).toBeCalledWith(sanitizedAccountId, sanitizedFunctionName, databaseSchema);
expect(hasuraClient.getTableNames).toBeCalledWith(sanitizedFunctionName, sanitizedAccountId);
expect(hasuraClient.trackTables).toBeCalledWith(sanitizedFunctionName, tableNames, sanitizedAccountId);
expect(hasuraClient.createSchema).toBeCalledWith(sanitizedAccountId, schemaName);
expect(hasuraClient.runMigrations).toBeCalledWith(sanitizedAccountId, schemaName, databaseSchema);
expect(hasuraClient.getTableNames).toBeCalledWith(schemaName, sanitizedAccountId);
expect(hasuraClient.trackTables).toBeCalledWith(schemaName, tableNames, sanitizedAccountId);
expect(hasuraClient.addPermissionsToTables).toBeCalledWith(
sanitizedFunctionName,
schemaName,
sanitizedAccountId,
tableNames,
sanitizedAccountId,
Expand All @@ -116,8 +116,8 @@ describe('Provisioner', () => {

await provisioner.provisionUserApi(accountId, functionName, databaseSchema);

expect(hasuraClient.getTableNames).toBeCalledWith(oldSchemaName, defaultDatabase)
expect(hasuraClient.untrackTables).toBeCalledWith(defaultDatabase, oldSchemaName, tableNames);
expect(hasuraClient.getTableNames).toBeCalledWith(schemaName, defaultDatabase)
expect(hasuraClient.untrackTables).toBeCalledWith(defaultDatabase, schemaName, tableNames);
});

it('skips provisioning the datasource if it already exists', async () => {
Expand All @@ -130,12 +130,12 @@ describe('Provisioner', () => {
expect(pgClient.query).not.toBeCalled();
expect(hasuraClient.addDatasource).not.toBeCalled();

expect(hasuraClient.createSchema).toBeCalledWith(sanitizedAccountId, sanitizedFunctionName);
expect(hasuraClient.runMigrations).toBeCalledWith(sanitizedAccountId, sanitizedFunctionName, databaseSchema);
expect(hasuraClient.getTableNames).toBeCalledWith(sanitizedFunctionName, sanitizedAccountId);
expect(hasuraClient.trackTables).toBeCalledWith(sanitizedFunctionName, tableNames, sanitizedAccountId);
expect(hasuraClient.createSchema).toBeCalledWith(sanitizedAccountId, schemaName);
expect(hasuraClient.runMigrations).toBeCalledWith(sanitizedAccountId, schemaName, databaseSchema);
expect(hasuraClient.getTableNames).toBeCalledWith(schemaName, sanitizedAccountId);
expect(hasuraClient.trackTables).toBeCalledWith(schemaName, tableNames, sanitizedAccountId);
expect(hasuraClient.addPermissionsToTables).toBeCalledWith(
sanitizedFunctionName,
schemaName,
sanitizedAccountId,
tableNames,
sanitizedAccountId,
Expand Down
25 changes: 9 additions & 16 deletions indexer-js-queue-handler/scripts/migrate-schema-to-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ const sanitizedFunctionName = provisioner.replaceSpecialChars(functionName);

const databaseName = sanitizedAccountId;
const userName = sanitizedAccountId;
const schemaName = sanitizedFunctionName;

const existingSchemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;
const schemaName = `${sanitizedAccountId}_${sanitizedFunctionName}`;

const password = provisioner.generatePassword()
if (!await provisioner.hasuraClient.doesSourceExist(databaseName)) {
Expand All @@ -65,30 +63,25 @@ if (!await provisioner.hasuraClient.doesSourceExist(databaseName)) {
await provisioner.addDatasource(userName, password, databaseName);
}

const tableNames = await provisioner.getTableNames(existingSchemaName, HasuraClient.DEFAULT_DATABASE);
const tableNames = await provisioner.getTableNames(schemaName, HasuraClient.DEFAULT_DATABASE);

console.log('Untracking existing tables')
await provisioner.hasuraClient.untrackTables(HasuraClient.DEFAULT_DATABASE, existingSchemaName, tableNames);
await provisioner.hasuraClient.untrackTables(HasuraClient.DEFAULT_DATABASE, schemaName, tableNames);

console.log(`Restoring existing schema ${existingSchemaName} in new DB ${databaseName}`);
await provisioner.createSchema(databaseName, existingSchemaName);
await provisioner.runMigrations(databaseName, existingSchemaName, databaseSchema);
console.log(`Restoring existing schema ${schemaName} in new DB ${databaseName}`);
await provisioner.createSchema(databaseName, schemaName);
await provisioner.runMigrations(databaseName, schemaName, databaseSchema);

console.log('Dumping existing data');
execSync(
`pg_dump ${`postgres://${process.env.PG_ADMIN_USER}:${process.env.PG_ADMIN_PASSWORD}@${process.env.PG_HOST}:${process.env.PG_PORT}/${process.env.PG_ADMIN_DATABASE}`} --data-only --schema=${existingSchemaName} --file="${existingSchemaName}.sql"`
`pg_dump ${`postgres://${process.env.PG_ADMIN_USER}:${process.env.PG_ADMIN_PASSWORD}@${process.env.PG_HOST}:${process.env.PG_PORT}/${process.env.PG_ADMIN_DATABASE}`} --data-only --schema=${schemaName} --file="${schemaName}.sql"`
);

console.log(`Restoring data to schema ${existingSchemaName} in DB ${databaseName}`);
console.log(`Restoring data to schema ${schemaName} in DB ${databaseName}`);
execSync(
`psql ${`postgres://${userName}:${password}@${process.env.PG_HOST}:${process.env.PG_PORT}/${databaseName}`} < "${existingSchemaName}.sql"`
`psql ${`postgres://${userName}:${password}@${process.env.PG_HOST}:${process.env.PG_PORT}/${databaseName}`} < "${schemaName}.sql"`
);

console.log(`Renaming schema ${existingSchemaName} to ${schemaName}`);
execSync(
`psql ${`postgres://${userName}:${password}@${process.env.PG_HOST}:${process.env.PG_PORT}/${databaseName}`} --command="ALTER SCHEMA \"${existingSchemaName}\" RENAME TO \"${schemaName}\";"`
)

console.log('Tracking tables');
await provisioner.trackTables(schemaName, tableNames, databaseName);

Expand Down

0 comments on commit d61a707

Please sign in to comment.