Skip to content
Snippets Groups Projects
Commit 89ff1fb2 authored by Louis's avatar Louis :fire:
Browse files

Set up database migrations

parent c86188a6
No related branches found
No related tags found
No related merge requests found
Showing
with 644 additions and 2 deletions
module.exports = {
up: (migration, Types) => {
return migration.createTable('', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('')
},
}
\ No newline at end of file
const timestamps = require('./properties/timestamps')
module.exports = (sequelize, DataTypes) => {
const Model = sequelize.define('', Object.assign(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
validate: {
isUUID: 4,
},
},
meta: {
type: DataTypes.JSONB,
},
},
timestamps(DataTypes),
), {
paranoid: true,
tableName: '',
})
Model.getPolyIdentifier = () => ''
Model.getRelationIdentifier = () => ''
Model.prototype.toJSON = function userToJSON() {
return {
id: this.id,
meta: this.meta,
created_at: this.created_at,
updated_at: this.updated_at,
}
}
Model.associate = function defineModelAssociations(models) {
}
Model.relations = []
return Model
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.sequelize.transaction(async t => {
await migration.sequelize.query('CREATE EXTENSION IF NOT EXISTS postgis;', { transaction: t })
await migration.sequelize.query('CREATE EXTENSION IF NOT EXISTS pg_trgm;', { transaction: t })
await migration.sequelize.query('CREATE EXTENSION IF NOT EXISTS timescaledb;', { transaction: t })
})
},
down: (migration, Types) => {
return migration.sequelize.transaction(async t => {
await migration.sequelize.query('DROP EXTENSION IF EXISTS postgis;', { transaction: t })
await migration.sequelize.query('DROP EXTENSION IF EXISTS pg_trgm;', { transaction: t })
await migration.sequelize.query('DROP EXTENSION IF EXISTS timescaledb;', { transaction: t })
})
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.createTable('users', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
name: {
type: Types.TEXT,
allowNull: true,
},
email: {
type: Types.TEXT,
allowNull: false,
},
password: {
type: Types.TEXT,
allowNull: false,
},
reset_token: {
type: Types.TEXT,
allowNull: true,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('users')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.sequelize.transaction(async t => {
await migration.createTable('metrics', {
id: {
type: Types.UUID,
defaultValue: Types.UUIDV4,
allowNull: false,
},
value: {
type: Types.TEXT,
allowNull: false,
},
type: {
type: Types.TEXT,
allowNull: false,
},
location: {
type: Types.GEOGRAPHY('POINT', 4326),
allowNull: false,
},
author_id: {
type: Types.UUID,
allowNull: true,
references: {
model: 'users',
key: 'id',
},
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
recorded_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
}, { transaction: t })
await migration.sequelize.query('CREATE INDEX metrics_id_idx ON metrics(id)', { transaction: t })
await migration.sequelize.query('SELECT create_hypertable(\'metrics\', \'recorded_at\')', { transaction: t })
})
},
down: (migration, Types) => {
return migration.sequelize.dropTable('metrics')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.createTable('oauth_clients', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
secret: {
type: Types.TEXT,
allowNull: true,
},
owner_id: {
type: Types.UUID,
allowNull: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
references: {
model: 'users',
key: 'id',
},
},
redirect_uris: {
type: Types.ARRAY(Types.TEXT),
allowNull: false,
defaultValue: [],
},
grant_types: {
type: Types.ARRAY(Types.TEXT),
allowNull: false,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('oauth_clients')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.createTable('oauth_access_tokens', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
client_id: {
type: Types.UUID,
allowNull: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
references: {
model: 'oauth_clients',
key: 'id',
},
},
user_id: {
type: Types.UUID,
allowNull: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
references: {
model: 'users',
key: 'id',
},
},
token: {
type: Types.TEXT,
allowNull: false,
unique: true,
},
scope: {
type: Types.TEXT,
allowNull: true,
},
expires_at: {
type: Types.DATE,
allowNull: true,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('oauth_access_tokens')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.createTable('oauth_refresh_tokens', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
client_id: {
type: Types.UUID,
allowNull: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
references: {
model: 'oauth_clients',
key: 'id',
},
},
user_id: {
type: Types.UUID,
allowNull: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
references: {
model: 'users',
key: 'id',
},
},
token: {
type: Types.TEXT,
allowNull: false,
unique: true,
},
scope: {
type: Types.TEXT,
allowNull: true,
},
expires_at: {
type: Types.DATE,
allowNull: true,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('oauth_refresh_tokens')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.createTable('files', {
id: {
type: Types.UUID,
primaryKey: true,
defaultValue: Types.UUIDV4,
allowNull: false,
},
provider: {
type: Types.TEXT,
allowNull: false,
},
file_root: {
type: Types.TEXT,
allowNull: false,
},
file_name: {
type: Types.TEXT,
allowNull: false,
},
comment: {
type: Types.TEXT,
allowNull: false,
defaultValue: '',
},
tags: {
type: Types.ARRAY(Types.TEXT),
allowNull: false,
defaultValue: [],
},
labels: {
type: Types.ARRAY(Types.TEXT),
allowNull: false,
defaultValue: [],
},
featured: {
type: Types.BOOLEAN,
allowNull: false,
defaultValue: false,
},
requires_approval: {
type: Types.BOOLEAN,
allowNull: false,
defaultValue: false,
},
approved: {
type: Types.BOOLEAN,
allowNull: false,
defaultValue: true,
},
meta: {
type: Types.JSONB,
defaultValue: {},
allowNull: false,
},
created_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
updated_at: {
type: Types.DATE,
defaultValue: Types.fn('now'),
allowNull: false,
},
deleted_at: {
type: Types.DATE,
defaultValue: null,
allowNull: true,
},
})
},
down: (migration, Types) => {
return migration.dropTable('files')
},
}
\ No newline at end of file
module.exports = {
up: (migration, Types) => {
return migration.sequelize.transaction(async t => {
await migration.sequelize.query(`
CREATE TABLE IF NOT EXISTS files_search_index (
file_id UUID UNIQUE PRIMARY KEY NOT NULL REFERENCES files(id) ON DELETE CASCADE ON UPDATE CASCADE,
search_index TSVECTOR NOT NULL
);`, { transaction: t })
await migration.sequelize.query(`CREATE INDEX IF NOT EXISTS files_search_index_idx ON files_search_index USING GIN(search_index);`, { transaction: t })
await migration.sequelize.query(`
CREATE OR REPLACE FUNCTION update_files_search_index() RETURNS TRIGGER AS $FUNC$
DECLARE
indexed_text TEXT := to_tsvector(concat(NEW.comment, array_to_string(NEW.tags, ' ', ''), array_to_string(NEW.labels, ' ', '')));
BEGIN
INSERT INTO files_search_index(file_id, search_index)
VALUES (NEW.id, to_tsvector(concat(NEW.comment, indexed_text)))
ON CONFLICT (file_id) DO UPDATE SET search_index = indexed_text;
END;
$FUNC$ LANGUAGE plpgsql;`, { transaction: t })
await migration.sequelize.query(`
CREATE TRIGGER update_files_search_index_trigger AFTER INSERT OR UPDATE ON files
FOR EACH ROW EXECUTE FUNCTION update_files_search_index();`, { transaction: t })
})
},
down: (migration, Types) => {
return migration.sequelize.transaction(async t => {
await migration.sequelize.query(`DROP TRIGGER IF EXISTS update_files_search_index_trigger ON files`, { transaction: t })
await migration.sequelize.query(`DROP FUNCTION IF EXISTS update_files_search_index()`, { transaction: t })
await migration.sequelize.query(`DROP INDEX IF EXISTS files_search_index_idx`, { transaction: t })
await migration.sequelize.query(`DROP TABLE IF EXISTS files_search_index`, { transaction: t })
})
}
}
\ No newline at end of file
......@@ -889,6 +889,11 @@
}
}
},
"basic-auth": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-0.0.1.tgz",
"integrity": "sha1-Md22WEP2w1xv6nvrRqmHy4zhiSQ="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
......@@ -1033,6 +1038,11 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
......@@ -4460,6 +4470,15 @@
}
}
},
"koa-oauth-server": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/koa-oauth-server/-/koa-oauth-server-1.0.1.tgz",
"integrity": "sha1-KGWsQ12pxbJGRP0jxejo9mllAAQ=",
"requires": {
"oauth2-server": "^2.3.0",
"thenify": "^3.0.0"
}
},
"koa-router": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/koa-router/-/koa-router-7.4.0.tgz",
......@@ -4948,6 +4967,14 @@
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"oauth2-server": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/oauth2-server/-/oauth2-server-2.4.1.tgz",
"integrity": "sha1-2m3QVMAh7JwpQ59dGijeY9ArcWw=",
"requires": {
"basic-auth": "~0.0.1"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
......@@ -5159,6 +5186,11 @@
"semver": "^5.1.0"
}
},
"packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
......@@ -5258,6 +5290,62 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
"pg": {
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/pg/-/pg-7.12.1.tgz",
"integrity": "sha512-l1UuyfEvoswYfcUe6k+JaxiN+5vkOgYcVSbSuw3FvdLqDbaoa2RJo1zfJKfPsSYPFVERd4GHvX3s2PjG1asSDA==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "0.1.3",
"pg-pool": "^2.0.4",
"pg-types": "^2.1.0",
"pgpass": "1.x",
"semver": "4.3.2"
},
"dependencies": {
"semver": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
"integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c="
}
}
},
"pg-connection-string": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz",
"integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc="
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-pool": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.7.tgz",
"integrity": "sha512-UiJyO5B9zZpu32GSlP0tXy8J2NsJ9EFGFfz5v6PSbdz/1hBLX1rNiiy5+mAm5iJJYwfCv4A0EBcQLGWwjbpzZw=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz",
"integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=",
"requires": {
"split": "^1.0.0"
}
},
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
......@@ -5294,6 +5382,29 @@
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
"dev": true
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
},
"postgres-date": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz",
"integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
......@@ -6162,6 +6273,14 @@
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
"dev": true
},
"split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"requires": {
"through": "2"
}
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
......@@ -6462,8 +6581,7 @@
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"timed-out": {
"version": "4.0.1",
......@@ -7069,6 +7187,11 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
......
......@@ -20,11 +20,13 @@
"koa-bodyparser": "^4.2.1",
"koa-cors": "0.0.16",
"koa-logger": "^3.2.1",
"koa-oauth-server": "^1.0.1",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"moment-range": "^4.0.2",
"pg": "^7.12.1",
"scrypt-kdf": "^2.0.1",
"sequelize": "^5.21.2",
"uuid": "^3.3.2"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment