-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add schema class to create/modify tables under migrations
Schema class itself can execute it's own instructions when provided a query or transaction client. The migrator will collect these classes and will execute them in sequence. In short the job of migrator will be to acquire the locks and then execute schemas in order
- Loading branch information
1 parent
3c3b8ca
commit ba751e6
Showing
15 changed files
with
803 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare module '@ioc:Adonis/Lucid/Migrator' { | ||
import { SchemaConstructorContract } from '@ioc:Adonis/Lucid/Schema' | ||
|
||
export type MigrationNode = { | ||
absPath: string, | ||
name: string, | ||
source: SchemaConstructorContract, | ||
} | ||
|
||
export interface MigratorContract { | ||
migrate (): Promise<void> | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare module '@ioc:Adonis/Lucid/Schema' { | ||
import { QueryClientContract, ExcutableQueryBuilderContract } from '@ioc:Adonis/Lucid/Database' | ||
import { RawContract } from '@ioc:Adonis/Lucid/DatabaseQueryBuilder' | ||
import { SchemaBuilder } from 'knex' | ||
|
||
export type DeferCallback = (client: QueryClientContract) => void | Promise<void> | ||
|
||
export interface SchemaConstructorContract { | ||
new (db: QueryClientContract, file: string, dryRun: boolean): SchemaContract | ||
} | ||
|
||
export interface SchemaContract { | ||
dryRun: boolean | ||
db: QueryClientContract | ||
schema: SchemaBuilder | ||
file: string | ||
disableTransactions: boolean | ||
|
||
now (precision?: number): RawContract & ExcutableQueryBuilderContract<any> | ||
defer: (cb: DeferCallback) => void | ||
up (): Promise<void> | void | ||
down (): Promise<void> | void | ||
execUp (): Promise<string [] | boolean> | ||
execDown (): Promise<string [] | boolean> | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class MssqlDialect implements DialectContract { | ||
public readonly name = 'mssql' | ||
public supportsAdvisoryLocks = false | ||
|
||
public async getAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Support for advisory locks is not implemented for mssql. Create a PR to add the feature`) | ||
} | ||
|
||
public async releaseAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Support for advisory locks is not implemented for mssql. Create a PR to add the feature`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract, QueryClientContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class MysqlDialect implements DialectContract { | ||
public readonly name = 'mysql' | ||
public supportsAdvisoryLocks = true | ||
|
||
constructor (private _client: QueryClientContract) { | ||
} | ||
|
||
/** | ||
* Attempts to add advisory lock to the database and | ||
* returns it's status. | ||
*/ | ||
public async getAdvisoryLock (key: string, timeout: number = 0): Promise<boolean> { | ||
const response = await this._client.raw(`SELECT GET_LOCK('${key}', ${timeout}) as lock_status;`) | ||
return response[0] && response[0][0] && response[0][0].lock_status === 1 | ||
} | ||
|
||
/** | ||
* Releases the advisory lock | ||
*/ | ||
public async releaseAdvisoryLock (key: string): Promise<boolean> { | ||
const response = await this._client.raw(`SELECT RELEASE_LOCK('${key}') as lock_status;`) | ||
return response[0] && response[0][0] && response[0][0].lock_status === 1 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class OracleDialect implements DialectContract { | ||
public readonly name = 'oracledb' | ||
public supportsAdvisoryLocks = false | ||
|
||
public async getAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Support for advisory locks is not implemented for oracledb. Create a PR to add the feature`) | ||
} | ||
|
||
public async releaseAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Support for advisory locks is not implemented for oracledb. Create a PR to add the feature`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract, QueryClientContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class PgDialect implements DialectContract { | ||
public readonly name = 'postgres' | ||
public supportsAdvisoryLocks = true | ||
|
||
constructor (private _client: QueryClientContract) { | ||
} | ||
|
||
/** | ||
* Attempts to add advisory lock to the database and | ||
* returns it's status. | ||
*/ | ||
public async getAdvisoryLock (key: string): Promise<boolean> { | ||
const response = await this._client.raw(`SELECT PG_TRY_ADVISORY_LOCK('${key}') as lock_status;`) | ||
return response.rows[0] && response.rows[0].lock_status === true | ||
} | ||
|
||
/** | ||
* Releases the advisory lock | ||
*/ | ||
public async releaseAdvisoryLock (key: string): Promise<boolean> { | ||
const response = await this._client.raw(`SELECT PG_ADVISORY_UNLOCK('${key}') as lock_status;`) | ||
return response.rows[0] && response.rows[0].lock_status === true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class RedshiftDialect implements DialectContract { | ||
public readonly name = 'redshift' | ||
public supportsAdvisoryLocks = false | ||
|
||
/** | ||
* Redshift doesn't support advisory locks. Learn more: | ||
* https://tableplus.com/blog/2018/10/redshift-vs-postgres-database-comparison.html | ||
*/ | ||
public async getAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Redshift doesn't support advisory locks`) | ||
} | ||
|
||
/** | ||
* Redshift doesn't support advisory locks. Learn more: | ||
* https://tableplus.com/blog/2018/10/redshift-vs-postgres-database-comparison.html | ||
*/ | ||
public async releaseAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Redshift doesn't support advisory locks`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { DialectContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
export class SqliteDialect implements DialectContract { | ||
public readonly name = 'sqlite3' | ||
public supportsAdvisoryLocks = false | ||
|
||
/** | ||
* Attempts to add advisory lock to the database and | ||
* returns it's status. | ||
*/ | ||
public async getAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Sqlite doesn't support advisory locks`) | ||
} | ||
|
||
/** | ||
* Releases the advisory lock | ||
*/ | ||
public async releaseAdvisoryLock (): Promise<boolean> { | ||
throw new Error(`Sqlite doesn't support advisory locks`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
import { PgDialect } from './Pg' | ||
import { MysqlDialect } from './Mysql' | ||
import { MssqlDialect } from './Mssql' | ||
import { SqliteDialect } from './Sqlite' | ||
import { OracleDialect } from './Oracle' | ||
import { RedshiftDialect } from './Redshift' | ||
|
||
export const dialects = { | ||
'mssql': MssqlDialect, | ||
'mysql': MysqlDialect, | ||
'mysql2': MysqlDialect, | ||
'oracledb': OracleDialect, | ||
'postgres': PgDialect, | ||
'redshift': RedshiftDialect, | ||
'sqlite3': SqliteDialect, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/// <reference path="../../adonis-typings/index.ts" /> | ||
|
||
import { readdir } from 'fs' | ||
import { join, isAbsolute, extname } from 'path' | ||
import { MigrationNode } from '@ioc:Adonis/Lucid/Migrator' | ||
import { ApplicationContract } from '@ioc:Adonis/Core/Application' | ||
import { ConnectionConfigContract } from '@ioc:Adonis/Lucid/Database' | ||
|
||
/** | ||
* Migration source exposes the API to read the migration files | ||
* from disk for a given connection. | ||
*/ | ||
export class MigrationSource { | ||
constructor ( | ||
private _config: ConnectionConfigContract, | ||
private _app: ApplicationContract, | ||
) {} | ||
|
||
/** | ||
* Returns an array of files inside a given directory. Relative | ||
* paths are resolved from the project root | ||
*/ | ||
private _getDirectoryFiles (directoryPath: string): Promise<MigrationNode[]> { | ||
return new Promise((resolve, reject) => { | ||
const path = isAbsolute(directoryPath) ? directoryPath : join(this._app.appRoot, directoryPath) | ||
readdir(path, (error, files) => { | ||
if (error) { | ||
reject(error) | ||
return | ||
} | ||
|
||
return resolve(files.sort().map((file) => { | ||
return { | ||
absPath: join(path, file), | ||
name: file.replace(RegExp(`${extname(file)}$`), ''), | ||
source: require(join(path, file)), | ||
} | ||
})) | ||
}) | ||
}) | ||
} | ||
|
||
/** | ||
* Returns an array of migrations paths for a given connection. If paths | ||
* are not defined, then `database/migrations` fallback is used | ||
*/ | ||
private _getMigrationsPath (): string[] { | ||
return (this._config.migrations && this._config.migrations.paths) || ['database/migrations'] | ||
} | ||
|
||
/** | ||
* Returns an array of files for all defined directories | ||
*/ | ||
public async getMigrations () { | ||
const migrationPaths = this._getMigrationsPath().sort() | ||
const directories = await Promise.all(migrationPaths.map((directoryPath) => { | ||
return this._getDirectoryFiles(directoryPath) | ||
})) | ||
|
||
return directories.reduce((result, directory) => { | ||
result = result.concat(directory) | ||
return result | ||
}, []) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
* @adonisjs/lucid | ||
* | ||
* (c) Harminder Virk <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
export class Migrator { | ||
} |
Oops, something went wrong.