@discord-factory/storage-next
v2.3.0
Published
When you create a discord bot, you often have to persist data in order not to lose them after a restart or a problem with your bot. In order to answer this need, [Discord Factory](https://github.com/DiscordFactory) provides a new generation module allowi
Downloads
42
Readme
📦 Storage-next
When you create a discord bot, you often have to persist data in order not to lose them after a restart or a problem with your bot. In order to answer this need, Discord Factory provides a new generation module allowing you to easily interact with your favorite database thanks to the ORM Knex.
Getting started
First, you need to import the module with the following command :
npm install @discord-factory/storage-next@lasted
# or
yarn add @discord-factory/storage-next@lasted
How to use
The @discord-factory/storage-next
module provides you with 2 commands allowing you to instantly create a template and a migration :
Make model
npm run factory make:model MyModel
# or
yarn factory make:model MyModel
Make migration
npm run factory make:migration MyMigration
# or
yarn factory make:migration MyMigration
How does the module work ?
In the first time, please add the module into the /start/Kernel.ts
import StorageNext from '@discord-factory/storage-next'
export default class Kernel {
public registerAddons () {
return [StorageNext]
}
}
As a developer, you need to separate your application into several levels. When using a database, you will need to define a model and migration to interoperate with your database.
A problem that comes up quite often is "how to automatically create a database with predefined tables". This problem is solved by migrations.
A migration
is a file that interacts with the database in order to create, alter or delete tables or columns within it.
A migration can be managed through the following command and will have a minimal structure as shown below :
npm run factory make:migration Folder/SubFolder/Foo
# or
yarn factory make:migration Folder/SubFolder/Foo
import { Migration, BaseMigration, Schema, Table } from '@discord-factory/storage-next'
@Migration()
export default class Foo_1631887311895 extends BaseMigration {
/**
* The `tableName` variable represents the name of your database table,
* it must be unique and by convention,
* must be in lower case.
*/
public tableName = 'foo'
/**
* The `up` function is responsible
* for sending the table named by the `tableName` variable to the database
*/
public async up (schema: Schema): Promise<any> {
/**
* The variable `table` represents your table in the database.
* You can add columns to it by choosing the type and/or options of the columns.
*/
return schema.createTable(this.tableName, (table: Table) => {
table.string('id').primary()
})
}
/**
* The `up` function is responsible for deleting the table
* named by the `tableName` variable within the database.
*/
public async down (schema: Schema): Promise<any> {
return schema.dropTableIfExists(this.tableName)
}
}
In order to insert the tables defined in your migrations, you will need to run the command below in a terminal at the root of your application.
npm run factory migration:run
# or
yarn factory migration:run
You can delete them from your database with the following command
npm run factory migration:rollback
# or
yarn factory migration:rollback
The model
is a file that allows you to interact with the table defined in it.
You must define in it all the properties that will represent the columns in your table, database.
A model can be managed through the following command and will have a minimal structure as shown below :
A migration can be managed through the following command and will have a minimal structure as shown below :
npm run factory make:model Folder/SubFolder/Foo
# or
yarn factory make:model Folder/SubFolder/Foo
import { Model, BaseModel, Uuid } from '@discord-factory/storage-next'
@Model('foo')
export default class Foo extends BaseModel {
/**
* The `myString` property of type string indicates that a column named `myString` exists
* in the table named foo (defined in the model decorator) and is of type varchar.
*/
public myString: string
public myNumber: number
public myBoolean boolean
}
The properties defined in your model should represent your columns in your database table.
As SQLite does not support auto-incrementing, it is recommended that you insert it "by default" in each of your queries to create a new database resource.
In order to solve this problem, the @discord-factory/storage-next
module provides you with two hooks, one allowing data alteration during an insertion and the other during an update of a resource.
import { Model, BaseModel, Uuid } from '@discord-factory/storage-next'
@Model('foo')
export default class Foo extends BaseModel {
public id: string
public firstname: string
// Called when Foo is used to craete ressource
public static beforeInsert (model: Foo) {
model.id = Uuid.generateV4()
}
// Called when Foo is used to update one ressource
public static beforeSave (model: Foo) {
model.firstname = `${model.firstname} Doe`
}
}
Basic examples
Considering the following migration and model
import { Migration, BaseMigration, Schema, Table } from '@discord-factory/storage-next'
@Migration()
export default class User_1631887311895 extends BaseMigration {
public tableName = 'user'
public async up (schema: Schema): Promise<any> {
return schema.createTable(this.tableName, (table: Table) => {
table.string('id').primary()
table.string('firstname')
table.string('lastname')
})
}
public async down (schema: Schema): Promise<any> {
return schema.dropTableIfExists(this.tableName)
}
}
import { Model, BaseModel, Uuid } from '@discord-factory/storage-next'
@Model('user')
export default class User extends BaseModel {
public id: string
public firstname: string
public static beforeInsert (model: Foo) {
model.id = Uuid.generateV4()
}
}
Get one resource
const user = await User.find('0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd') as User
console.log(user)
console.log({
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd',
firstname: 'John',
lastname: 'Doe'
})
Get one resource by column
const user = await User.findBy('id', '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd') as User
const user = await User.findBy({ id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd' }) as User
console.log(user)
console.log({
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd',
firstname: 'John',
lastname: 'Doe'
})
Get all resources from table
const user = await User.all() as User[]
console.log(user)
console.log([
{
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd',
firstname: 'John',
lastname: 'Doe'
}
])
Create one resource
const data = {
firstname: 'John',
lastname: 'Doe',
}
const user = await User.create(data) as User 👈 // You should to define type if you want auto-complétion
console.log(user)
console.log({
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd',
firstname: 'John',
lastname: 'Doe'
})
Create many resource
const data = [
{ firstname: 'John', lastname: 'Doe' },
{ firstname: 'Sarah', lastname: 'Doe' }
]
const users = await User.createMany(data) as User[] 👈 // You should to define type if you want auto-complétion
console.log(users)
console.log([
{
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd',
firstname: 'John',
lastname: 'Doe'
},
{
id: '0ab2a318-d1b0-4c1e-a7d1-31b42b2153fe',
firstname: 'Sarah',
lastname: 'Doe'
}
])
Update one resource
const data = {
firstname: 'John',
lastname: 'Doe',
}
const user = await User.find('0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd')
await user.update(data)
Delete one resource
const user = await User.find('0ab2a318-d1b0-4c1e-a7d1-31b42b2153cd')
await User.delete()
License
MIT License © 2021 Baptiste Parmantier