215 lines
4.4 KiB
JavaScript
215 lines
4.4 KiB
JavaScript
import fs from 'fs';
|
|
|
|
export async function up(knex) {
|
|
const nanoidFn = await fs.promises.readFile('./migrations/nanoid.sql', 'utf8'); // from https://github.com/viascom/nanoid-postgres
|
|
|
|
await knex.raw(nanoidFn);
|
|
|
|
await knex.raw(`
|
|
CREATE FUNCTION shack_id(length smallint DEFAULT 8) RETURNS TEXT AS $$
|
|
SELECT nanoid(length, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
|
$$ LANGUAGE SQL STABLE;
|
|
`);
|
|
|
|
await knex.schema.createTable('users', (table) => {
|
|
table.increments('id');
|
|
|
|
table.text('username', 32)
|
|
.notNullable()
|
|
.unique();
|
|
|
|
table.text('email', 32)
|
|
.notNullable()
|
|
.unique();
|
|
|
|
table.text('password')
|
|
.notNullable();
|
|
|
|
table.text('name', 32);
|
|
table.text('bio', 1000);
|
|
|
|
table.specificType('ip', 'inet');
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
|
|
await knex.schema.createTable('shelves', (table) => {
|
|
table.increments('id');
|
|
|
|
table.text('slug')
|
|
.unique()
|
|
.index()
|
|
.notNullable();
|
|
|
|
table.integer('founder_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
|
|
await knex.schema.createTable('shelves_settings', (table) => {
|
|
table.increments('id');
|
|
|
|
table.integer('shelf_id')
|
|
.primary()
|
|
.references('id')
|
|
.inTable('shelves');
|
|
|
|
table.text('name');
|
|
table.text('title');
|
|
table.text('description');
|
|
|
|
table.enum('view_access', ['public', 'registered', 'private'])
|
|
.notNullable()
|
|
.defaultTo('public');
|
|
|
|
table.enum('post_access', ['registered', 'private'])
|
|
.notNullable()
|
|
.defaultTo('public');
|
|
|
|
table.boolean('is_nsfw');
|
|
});
|
|
|
|
await knex.schema.createTable('shelves_subscriptions', (table) => {
|
|
table.increments('id');
|
|
|
|
table.integer('shelf_id')
|
|
.references('id')
|
|
.inTable('shelves');
|
|
|
|
table.integer('user_id')
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.unique(['shelf_id', 'user_id']);
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
|
|
await knex.schema.createTable('posts', (table) => {
|
|
table.text('id', 8)
|
|
.primary()
|
|
.defaultTo(knex.raw('shack_id()'));
|
|
|
|
table.text('title')
|
|
.notNullable();
|
|
|
|
table.text('body');
|
|
table.text('link');
|
|
|
|
table.integer('shelf_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('shelves');
|
|
|
|
table.integer('user_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
|
|
await knex.raw('ALTER TABLE posts ADD CONSTRAINT post_content CHECK (body IS NOT NULL OR link IS NOT NULL)');
|
|
|
|
await knex.schema.createTable('posts_votes', (table) => {
|
|
table.increments('id');
|
|
|
|
table.tinyint('value')
|
|
.notNullable()
|
|
.defaultTo(1);
|
|
|
|
table.integer('user_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.string('post_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('posts');
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
|
|
table.unique(['user_id', 'post_id']);
|
|
});
|
|
|
|
await knex.schema.createTable('comments', (table) => {
|
|
table.text('id', 8)
|
|
.primary()
|
|
.defaultTo(knex.raw('shack_id()'));
|
|
|
|
table.text('post_id', 8)
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('posts');
|
|
|
|
table.text('parent_id')
|
|
.references('id')
|
|
.inTable('comments');
|
|
|
|
table.integer('user_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.text('body');
|
|
|
|
table.boolean('deleted')
|
|
.notNullable()
|
|
.defaultTo(false);
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
|
|
await knex.schema.createTable('comments_votes', (table) => {
|
|
table.increments('id');
|
|
|
|
table.tinyint('value')
|
|
.notNullable()
|
|
.defaultTo(1);
|
|
|
|
table.integer('user_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('users');
|
|
|
|
table.string('comment_id')
|
|
.notNullable()
|
|
.references('id')
|
|
.inTable('comments');
|
|
|
|
table.datetime('created_at')
|
|
.notNullable()
|
|
.defaultTo(knex.fn.now());
|
|
});
|
|
}
|
|
|
|
export async function down(knex) {
|
|
await knex.schema.dropTableIfExists('comments_votes');
|
|
await knex.schema.dropTableIfExists('comments');
|
|
await knex.schema.dropTableIfExists('posts_votes');
|
|
await knex.schema.dropTableIfExists('posts');
|
|
await knex.schema.dropTableIfExists('shelves_settings');
|
|
await knex.schema.dropTableIfExists('shelves');
|
|
await knex.schema.dropTableIfExists('users');
|
|
|
|
await knex.raw(`
|
|
DROP FUNCTION IF EXISTS shack_id;
|
|
`);
|
|
}
|