getlackey/lackey-cms

View on GitHub
modules/core/server/models/knex.js

Summary

Maintainability
F
4 days
Test Coverage
/* eslint no-underscore-dangle:0 */
/* jslint node:true, esnext:true */
/* global LACKEY_PATH */
'use strict';

/*
    Copyright 2016 Enigma Marketing Services Limited

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

const Schema = require('./schema'),
    SCli = require(LACKEY_PATH).cli,
    __MODULE_NAME = 'lackey-cms/modules/core/server/models/knex';

SCli.debug(__MODULE_NAME, 'Knex required');

module.exports = Schema
    .whenReady
    .then((knex) => {

        SCli.debug(__MODULE_NAME, 'Knex initted');

        return Schema
            //
            // TABLE Users
            //
            .table(knex, 'users', table => {
                table.increments();
                table.string('name');
                table.string('title');
                table.string('slug');
                table.string('hashedPassword');
                table.string('salt');
                table.bigInteger('avatar');
                table.string('bio');
                table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
            })
            .then(() => {
                return Schema.addColumn(knex, 'users', 'route', table => {
                    table.string('route');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'users', 'deleted', table => {
                    table.boolean('deleted');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'users', 'lastActive', table => {
                    table.timestamp('lastActive');
                });
            })
            //
            // TABLE identities
            // .userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'identities', table => {
                    table.increments();
                    table.string('provider');
                    table.string('accountId');
                    table.string('accessToken');
                    table.string('refreshToken');
                    table.json('providerData');
                    table.boolean('confirmed');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique(['provider', 'accountId']);
                });
            })
            //
            // TABLE sessions
            //
            //
            .then(() => {
                return Schema.table(knex, 'sessions', table => {
                    table.string('sid');
                    table.json('sess').notNullable();
                    table.unique(['sid']);
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'userId', table => {
                    table.bigInteger('userId');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'device', table => {
                    table.string('device');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'ipAddress', table => {
                    table.string('ipAddress');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'userAgent', table => {
                    table.string('userAgent');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'browser', table => {
                    table.string('browser');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'os', table => {
                    table.string('os');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'sessions', 'updated', table => {
                    table.timestamp('updated').notNullable().defaultTo(knex.raw('now()'));
                });
            })

        //
        // TABLE roles
        //
        .then(() => {
                return Schema.table(knex, 'roles', table => {
                    table.increments();
                    table.string('name');
                    table.string('label');
                    table.json('acl');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique('name');

                });
            })
            //
            // TABLE acl
            // .userId -> users.id
            // .roleId -> roles.id
            //
            .then(() => {
                return Schema.table(knex, 'acl', table => {
                    table.increments();
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('roleId')
                        .unsigned()
                        .references('id')
                        .inTable('roles')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            //
            // TABLE tokens
            // .userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'tokens', table => {
                    table.increments();
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.string('token');
                    table.string('type');
                    table.timestamp('expire');
                    table.boolean('used');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            //
            // TABLE activityLog
            // .userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'activityLog', table => {
                    table.increments();
                    table.string('method');
                    table.string('url');
                    table.json('headers');
                    table.json('body');
                    table.integer('status');
                    table.integer('duration');
                    table.json('response');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            //
            // TABLE template
            // userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'template', table => {
                    table.increments();
                    table.string('name');
                    table.string('path');
                    table.string('type');
                    table.string('thumb');
                    table.boolean('selectable');
                    table.json('props');
                    table.json('populate');
                    table.json('javascripts');
                    table.json('stylesheets');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique('path');
                });

            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'expose', table => {
                    table.json('expose');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'prefix', table => {
                    table.string('prefix');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'variants', table => {
                    table.json('variants');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'require', table => {
                    table.json('require');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'allowTaxonomies', table => {
                    table.json('allowTaxonomies');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'template', 'editable', table => {
                    table.boolean('editable').defaultTo(true);
                });
            })
            //
            // TABLE content
            // .userId -> users.id
            // .templateId -> template.id
            //
            .then(() => {
                return Schema.table(knex, 'content', table => {
                    table.increments();
                    table.string('name');
                    table.string('type');
                    table.json('layout');
                    table.json('props');
                    table.string('route');
                    table.string('state');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('templateId')
                        .unsigned()
                        .references('id')
                        .inTable('template')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique(['route', 'type']);
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'content', 'authorId', table => {
                    table.bigInteger('authorId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'content', 'publishAt', table => {
                    table.date('publishAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            .then(() => {
                return knex.schema
                    .hasColumn('content', 'plaintext')
                    .then(exists => {
                        //if (!exists) {
                        return require(__dirname + '/content/upgrade')(knex)
                            .then(() => {
                                if (!exists) {
                                    return Schema.addColumn(knex, 'content', 'plaintext', table => {
                                        table.text('plaintext');
                                    });
                                }
                            });
                        //}
                    });
            })
            //
            // TABLE redirect
            // userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'redirect', table => {
                    table.increments();
                    table.string('route');
                    table.string('target');
                    table.string('type');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique('route');
                });
            })
            //
            // TABLE media
            // userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'media', table => {
                    table.increments();
                    table.string('mime');
                    table.string('name');
                    table.string('source');
                    table.json('attributes');
                    table.json('alternatives');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            //
            // TABLE taxonomyType
            // userId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'taxonomyType', table => {
                    table.increments();
                    table.string('name');
                    table.string('label');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                    table.unique('name');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'taxonomyType', 'restrictive', table => {
                    table.boolean('restrictive');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'taxonomyType', 'description', table => {
                    table.string('description');
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'taxonomyType', 'allowCreation', table => {
                    table.boolean('allowCreation');
                });
            })
            //
            // TABLE taxonomy
            // userId -> users.id
            // taxonomyTypeId -> taxonomyType.id
            //
            .then(() => {
                return Schema.table(knex, 'taxonomy', table => {
                    table.increments();
                    table.string('name');
                    table.string('label');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyTypeId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomyType')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            //
            // TABLE userToTaxonomy
            // taxonomyUserId -> taxonomy.id
            // userId -> users.id
            // taxonomyUserId -> users.id
            //
            .then(() => {
                return Schema.table(knex, 'userToTaxonomy', table => {
                    table.increments();
                    table.bigInteger('taxonomyUserId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomy')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });

            })
            //
            // TABLE roleToTaxonomy
            // taxonomyUserId -> taxonomy.id
            // userId -> users.id
            // roleId -> roles.id
            //
            .then(() => {
                return Schema.table(knex, 'roleToTaxonomy', table => {
                    table.increments();
                    table.bigInteger('roleId')
                        .unsigned()
                        .references('id')
                        .inTable('roles')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomy')
                        .onDelete('CASCADE');
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });

            })
            //
            // TABLE templateToTaxonomy
            // taxonomyUserId -> taxonomy.id
            // userId -> users.id
            // templateId -> templates.id
            //
            .then(() => {
                return Schema.table(knex, 'templateToTaxonomy', table => {
                    table.increments();
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomy')
                        .onDelete('CASCADE');
                    table.bigInteger('templateId')
                        .unsigned()
                        .references('id')
                        .inTable('template')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });

            })

            //
            // TABLE contentToTaxonomy
            // taxonomyUserId -> taxonomy.id
            // userId -> users.id
            // contentId -> content.id
            //
            .then(() => {
                return Schema.table(knex, 'contentToTaxonomy', table => {
                    table.increments();
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomy')
                        .onDelete('CASCADE');
                    table.bigInteger('contentId')
                        .unsigned()
                        .references('id')
                        .inTable('content')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });

            })
            .then(() => {
                return Schema.loadSQL(knex, __dirname + '/content/psql/ContentACL.sql');
            })
            //
            // TABLE mediaToTaxonomy
            // taxonomyId -> taxonomy.id
            // userId -> users.id
            // mediaId -> media.id
            //
            .then(() => {
                return Schema.table(knex, 'mediaToTaxonomy', table => {
                    table.increments();
                    table.bigInteger('userId')
                        .unsigned()
                        .references('id')
                        .inTable('users')
                        .onDelete('CASCADE');
                    table.bigInteger('taxonomyId')
                        .unsigned()
                        .references('id')
                        .inTable('taxonomy')
                        .onDelete('CASCADE');
                    table.bigInteger('mediaId')
                        .unsigned()
                        .references('id')
                        .inTable('media')
                        .onDelete('CASCADE');
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                    table.timestamp('updatedAt').notNullable().defaultTo(knex.raw('now()'));
                });

            })
            .then(() => {
                return Schema.loadSQL(knex, __dirname + '/media/psql/MediaACL.sql');
            })
            //
            // TABLE Translations
            //
            //
            .then(() => {
                return Schema.table(knex, 'translations', table => {
                    table.increments();
                    table.string('reference');
                    table.string('originalValue');
                    table.string('language');
                    table.string('value');
                });
            })
            //
            // TABLE Translations
            //
            //
            .then(() => {
                return Schema.table(knex, 'analytics', table => {
                    table.increments();
                    table.string('metric').notNullable();
                    table.integer('value').defaultTo(1).notNullable();
                    table.date('date').notNullable();
                    table.unique(['metric', 'date']);
                });
            })
            .then(() => {
                return Schema.table(knex, 'previews', table => {
                    table.increments();
                    table.bigInteger('contentId').notNullable();
                    table.string('shareString').defaultTo(1).notNullable();
                    table.timestamp('createdAt').notNullable().defaultTo(knex.raw('now()'));
                });
            })
            .then(() => {
                return Schema.addColumn(knex, 'analytics', 'map', table => {
                    table.json('map');
                });
            })
            .then(() => {
                return knex.schema.raw('UPDATE taxonomy SET name = lower(name)');
            })
            .then(() => {
                SCli.debug(__MODULE_NAME, 'Schema applied');
            });
    });