Skip to content

Commit

Permalink
feat(db): add db:wipe and db:fresh commands
Browse files Browse the repository at this point in the history
  • Loading branch information
jlenon7 committed Apr 24, 2024
1 parent e516313 commit b5a841e
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 7 deletions.
9 changes: 9 additions & 0 deletions configurer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,19 @@ export default class DatabaseConfigurer extends BaseConfigurer {
'make:migration',
'@athenna/database/commands/MakeMigrationCommand'
)
.setTo('commands', 'db:fresh', {
path: '@athenna/database/commands/DbFreshCommand',
loadApp: true,
loadAllCommands: true
})
.setTo('commands', 'db:seed', {
path: '@athenna/database/commands/DbSeedCommand',
loadApp: true
})
.setTo('commands', 'db:wipe', {
path: '@athenna/database/commands/DbWipeCommand',
loadApp: true
})
.setTo('commands', 'migration:run', {
path: '@athenna/database/commands/MigrationRunCommand',
loadApp: true
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/database",
"version": "4.42.0",
"version": "4.43.0",
"description": "The Athenna database handler for SQL/NoSQL.",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand Down Expand Up @@ -50,7 +50,9 @@
"./package": "./package.json",
"./package.json": "./package.json",
"./testing/plugins": "./src/testing/plugins/index.js",
"./commands/DbFreshCommand": "./src/commands/DbFreshCommand.js",
"./commands/DbSeedCommand": "./src/commands/DbSeedCommand.js",
"./commands/DbWipeCommand": "./src/commands/DbWipeCommand.js",
"./commands/MakeMigrationCommand": "./src/commands/MakeMigrationCommand.js",
"./commands/MakeModelCommand": "./src/commands/MakeModelCommand.js",
"./commands/MakeSeederCommand": "./src/commands/MakeSeederCommand.js",
Expand Down Expand Up @@ -203,9 +205,16 @@
"migration:revert": {
"path": "#src/commands/MigrationRevertCommand"
},
"db:fresh": {
"path": "#src/commands/DbFreshCommand",
"loadAllCommands": true
},
"db:seed": {
"path": "#src/commands/DbSeedCommand"
},
"db:wipe": {
"path": "#src/commands/DbWipeCommand"
},
"make:model": {
"path": "#src/commands/MakeModelCommand"
},
Expand Down
32 changes: 32 additions & 0 deletions src/commands/DbFreshCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @athenna/database
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Artisan, BaseCommand, Option } from '@athenna/artisan'

export class DbWipeCommand extends BaseCommand {
@Option({
default: 'default',
signature: '-c, --connection <connection>',
description: 'Set the the database connection.'
})
public connection: string

public static signature(): string {
return 'db:fresh'
}

public static description(): string {
return 'Drop all the tables of your database and run migrations again.'
}

public async handle(): Promise<void> {
await Artisan.call(`db:wipe --connection ${this.connection}`)
await Artisan.call(`migration:run --connection ${this.connection}`)
}
}
63 changes: 63 additions & 0 deletions src/commands/DbWipeCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* @athenna/database
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Exec } from '@athenna/common'
import { Database } from '#src/facades/Database'
import { BaseCommand, Option } from '@athenna/artisan'

export class DbWipeCommand extends BaseCommand {
@Option({
default: 'default',
signature: '-c, --connection <connection>',
description: 'Set the the database connection.'
})
public connection: string

public static signature(): string {
return 'db:wipe'
}

public static description(): string {
return 'Drop all the tables of your database.'
}

public async handle(): Promise<void> {
this.logger.simple('({bold,green} [ WIPING DATABASE ])\n')

const DB = Database.connection(this.connection)
const task = this.logger.task()

if (this.getConfig('driver') === 'mongo') {
const tables = await DB.getTables()

await Exec.concurrently(tables, table => DB.dropTable(table))
} else {
const migrationsTable = this.getConfig(
'migrations.tableName',
'migrations'
)

await DB.revertMigrations()
await DB.dropTable(migrationsTable)
}

const dbName = await DB.getCurrentDatabase()

await task.run().finally(() => DB.close())

this.logger.success(`Database ({yellow} "${dbName}") successfully wiped.`)
}

private getConfig(name: string, defaultValue?: any) {
return Config.get(
`database.connections.${this.connection}.${name}`,
defaultValue
)
}
}
8 changes: 8 additions & 0 deletions src/commands/MigrationRevertCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ export class MigrationRevertCommand extends BaseCommand {
public async handle(): Promise<void> {
this.logger.simple('({bold,green} [ REVERTING MIGRATIONS ])\n')

if (Config.is(`database.connections.${this.connection}.driver`, 'mongo')) {
this.logger.warn(
`Connection ({yellow} "${this.connection}") is using ({yellow} "mongo") driver and migrations revert will be skipped.`
)

return
}

const DB = Database.connection(this.connection)
const dbName = await DB.getCurrentDatabase()

Expand Down
8 changes: 8 additions & 0 deletions src/commands/MigrationRunCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ export class MigrationRunCommand extends BaseCommand {
public async handle(): Promise<void> {
this.logger.simple('({bold,green} [ RUNNING MIGRATIONS ])\n')

if (Config.is(`database.connections.${this.connection}.driver`, 'mongo')) {
this.logger.warn(
`Connection ({yellow} "${this.connection}") is using ({yellow} "mongo") driver and migrations run will be skipped.`
)

return
}

const DB = Database.connection(this.connection)
const dbName = await DB.getCurrentDatabase()

Expand Down
3 changes: 1 addition & 2 deletions src/models/builders/ModelQueryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,14 @@ export class ModelQueryBuilder<
this.primaryKeyProperty = this.schema.getMainPrimaryKeyProperty() as any

const deletedAtColumn = this.schema.getDeletedAtColumn()
const properties = this.schema.getAllColumnProperties()

if (deletedAtColumn) {
this.isSoftDelete = true
this.DELETED_AT_NAME = deletedAtColumn.name
this.DELETED_AT_PROP = deletedAtColumn.property
}

this.selectColumns = properties
this.selectColumns = this.schema.getAllColumnNames()
this.setPrimaryKey(this.primaryKeyName)
}

Expand Down
7 changes: 7 additions & 0 deletions src/models/schemas/ModelSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ export class ModelSchema<M extends BaseModel = any> {
return this.columns.map(column => column.property)
}

/**
* Get all column names as an array of string.
*/
public getAllColumnNames(): string[] {
return this.columns.map(column => column.name)
}

/**
* Get all columns where unique option is true.
*/
Expand Down
6 changes: 4 additions & 2 deletions tests/fixtures/config/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export default {

connections: {
fake: {
driver: 'fake',
validations: true
driver: 'fake'
},
fakeMongo: {
driver: 'mongo'
},
mysql: {
driver: 'mysql'
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/commands/DbFreshCommandTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @athenna/database
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Path } from '@athenna/common'
import { Test, type Context } from '@athenna/test'
import { BaseCommandTest } from '#tests/helpers/BaseCommandTest'

export default class DbFreshCommandTest extends BaseCommandTest {
@Test()
public async shouldBeAbleToRunDbFreshCommand({ command }: Context) {
const output = await command.run('db:fresh --connection=fake', {
path: Path.fixtures('consoles/db-console.ts')
})

output.assertSucceeded()
output.assertLogged('[ WIPING DATABASE ]')
output.assertLogged('[ RUNNING MIGRATIONS ]')
}
}
25 changes: 25 additions & 0 deletions tests/unit/commands/DbWipeCommandTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @athenna/database
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Path } from '@athenna/common'
import { Test, type Context } from '@athenna/test'
import { BaseCommandTest } from '#tests/helpers/BaseCommandTest'

export default class DbWipeCommandTest extends BaseCommandTest {
@Test()
public async shouldBeAbleToWipeTheEntireDatabase({ command }: Context) {
const output = await command.run('db:wipe --connection=fake', {
path: Path.fixtures('consoles/db-console.ts')
})

output.assertSucceeded()
output.assertLogged('[ WIPING DATABASE ]')
output.assertLogged('Database "fake" successfully wiped.')
}
}
11 changes: 11 additions & 0 deletions tests/unit/commands/MigrationRevertCommandTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,15 @@ export default class MigrationRevertCommandTest extends BaseCommandTest {
output.assertLogged('[ REVERTING MIGRATIONS ]')
output.assertLogged('[ success ] Successfully reverted migrations on "fake" database.')
}

@Test()
public async shouldSkipRevertingMigrationsIfDriverIsMongo({ command }: Context) {
const output = await command.run('migration:revert --connection=fakeMongo', {
path: Path.fixtures('consoles/db-console.ts')
})

output.assertSucceeded()
output.assertLogged('[ REVERTING MIGRATIONS ]')
output.assertLogged('Connection "fakeMongo" is using "mongo" driver and migrations revert will be skipped.')
}
}
11 changes: 11 additions & 0 deletions tests/unit/commands/MigrationRunCommandTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,15 @@ export default class MigrationRunCommandTest extends BaseCommandTest {
output.assertLogged('[ RUNNING MIGRATIONS ]')
output.assertLogged('[ success ] Successfully ran migrations on "fake" database.')
}

@Test()
public async shouldSkipRunningMigrationsIfDriverIsMongo({ command }: Context) {
const output = await command.run('migration:run --connection=fakeMongo', {
path: Path.fixtures('consoles/db-console.ts')
})

output.assertSucceeded()
output.assertLogged('[ RUNNING MIGRATIONS ]')
output.assertLogged('Connection "fakeMongo" is using "mongo" driver and migrations run will be skipped.')
}
}

0 comments on commit b5a841e

Please sign in to comment.