Remove old migration files

This commit is contained in:
Denis Arh
2020-08-24 15:38:42 +02:00
parent 3f30105d67
commit a7f8cd58cd
82 changed files with 0 additions and 1468 deletions
-117
View File
@@ -1,117 +0,0 @@
package db
import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/goware/statik/fs"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"go.uber.org/zap"
"github.com/cortezaproject/corteza-server/compose/db/mysql"
)
func statements(contents []byte, err error) ([]string, error) {
if err != nil {
return []string{}, err
}
return regexp.MustCompilePOSIX(";$").Split(string(contents), -1), nil
}
func Migrate(db *factory.DB, log *zap.Logger) error {
log = log.Named("database.migrations")
statikFS, err := fs.New(mysql.Asset)
if err != nil {
return errors.Wrap(err, "error creating statik filesystem")
}
var files []string
fn := func(filename string, info os.FileInfo, err error) error {
_ = err
matched, err := filepath.Match("/*.up.sql", filename)
if matched {
files = append(files, filename)
}
return err
}
if err := fs.Walk(statikFS, "/", fn); err != nil {
return errors.Wrap(err, "error when listing files for migrations")
}
sort.Strings(files)
if len(files) == 0 {
return errors.New("no files encoded for migration, need at least one SQL file")
}
migrate := func(filename string, useLog bool) error {
status := migration{
Project: "crm",
Filename: filename,
}
if useLog {
if err := db.Get(&status, "select * from migrations where project=? and filename=?", status.Project, status.Filename); err != nil {
return err
}
if status.Status == "ok" {
return nil
}
}
up := func() error {
stmts, err := statements(fs.ReadFile(statikFS, filename))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading migration %s", filename))
}
log.Debug("Running migration", zap.String("filename", filename))
for idx, query := range stmts {
if strings.TrimSpace(query) != "" && idx >= status.StatementIndex {
status.StatementIndex = idx
if _, err := db.Exec(query); err != nil {
log.Debug("migration error ", zap.String("filename", filename), zap.Error(err))
return err
}
}
}
status.Status = "ok"
return nil
}
err := db.Transaction(up)
if err != nil {
status.Status = err.Error()
}
if useLog {
if err := db.Replace("migrations", status); err != nil {
return errors.Wrap(err, "migration update failed")
}
}
return err
}
if err := migrate("/migrations.sql", false); err != nil {
return err
}
db.Exec("LOCK TABLE migrations WRITE;")
defer db.Exec("UNLOCK TABLES")
for _, filename := range files {
if err := migrate(filename, true); err != nil {
return err
}
}
return nil
}
File diff suppressed because one or more lines are too long
@@ -1,60 +0,0 @@
CREATE TABLE `crm_content` (
`id` bigint(20) unsigned NOT NULL,
`module_id` bigint(20) unsigned NOT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`,`module_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crm_content_column` (
`content_id` bigint(20) NOT NULL,
`column_name` varchar(255) NOT NULL,
`column_value` text NOT NULL,
PRIMARY KEY (`content_id`,`column_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crm_field` (
`field_type` varchar(16) NOT NULL COMMENT 'Short field type (string, boolean,...)',
`field_name` varchar(255) NOT NULL COMMENT 'Description of field contents',
`field_template` varchar(255) NOT NULL COMMENT 'HTML template file for field',
PRIMARY KEY (`field_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crm_module` (
`id` bigint(20) unsigned NOT NULL,
`name` varchar(64) NOT NULL COMMENT 'The name of the module',
`json` json NOT NULL COMMENT 'List of field definitions for the module',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crm_module_form` (
`module_id` bigint(20) unsigned NOT NULL,
`place` tinyint(3) unsigned NOT NULL,
`kind` varchar(64) NOT NULL COMMENT 'The type of the form input field',
`name` varchar(64) NOT NULL COMMENT 'The name of the field in the form',
`label` varchar(255) NOT NULL COMMENT 'The label of the form input',
`help_text` text NOT NULL COMMENT 'Help text',
`default_value` text NOT NULL COMMENT 'Default value',
`max_length` int(10) unsigned NOT NULL COMMENT 'Maximum input length',
`is_private` tinyint(1) NOT NULL COMMENT 'Contains personal/sensitive data?',
PRIMARY KEY (`module_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crm_page` (
`id` bigint(20) unsigned NOT NULL COMMENT 'Page ID',
`self_id` bigint(20) unsigned NOT NULL COMMENT 'Parent Page ID',
`module_id` bigint(20) unsigned NOT NULL COMMENT 'Module ID (optional)',
`title` varchar(255) NOT NULL COMMENT 'Title (required)',
`description` text NOT NULL COMMENT 'Description',
`blocks` json NOT NULL COMMENT 'JSON array of blocks for the page',
`visible` tinyint(4) NOT NULL COMMENT 'Is page visible in navigation?',
`weight` int(11) NOT NULL COMMENT 'Order for navigation',
PRIMARY KEY (`id`) USING BTREE,
KEY `module_id` (`module_id`),
KEY `self_id` (`self_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,7 +0,0 @@
INSERT INTO `crm_field` VALUES ('bool','Boolean value (yes / no)','');
INSERT INTO `crm_field` VALUES ('email','E-mail input','');
INSERT INTO `crm_field` VALUES ('enum','Single option picker','');
INSERT INTO `crm_field` VALUES ('hidden','Hidden value','');
INSERT INTO `crm_field` VALUES ('stamp','Date/time input','');
INSERT INTO `crm_field` VALUES ('text','Text input','');
INSERT INTO `crm_field` VALUES ('textarea','Text input (multi-line)','');
@@ -1 +0,0 @@
ALTER TABLE `crm_content` ADD `user_id` BIGINT UNSIGNED NOT NULL AFTER `module_id`, ADD INDEX (`user_id`);
@@ -1 +0,0 @@
INSERT INTO `crm_field` (`field_type`, `field_name`, `field_template`) VALUES ('related', 'Related content', ''), ('related_multi', 'Related content (multiple)', '');
@@ -1,6 +0,0 @@
CREATE TABLE `crm_content_links` (
`content_id` bigint(20) unsigned NOT NULL,
`column_name` varchar(255) NOT NULL,
`rel_content_id` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`content_id`,`column_name`,`rel_content_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
ALTER TABLE `crm_module_form` ADD `is_required` TINYINT(1) NOT NULL AFTER `is_private`, ADD `is_visible` TINYINT(1) NOT NULL AFTER `is_required`;
@@ -1 +0,0 @@
ALTER TABLE `crm_module_form` DROP PRIMARY KEY, ADD PRIMARY KEY(`module_id`, `place`);
@@ -1 +0,0 @@
ALTER TABLE `crm_content` ADD `json` json DEFAULT NULL COMMENT 'Content in JSON format.' AFTER `user_id`;
@@ -1 +0,0 @@
ALTER TABLE `crm_module_form` ADD `json` JSON NOT NULL COMMENT 'Options in JSON format.' AFTER `kind`;
@@ -1,9 +0,0 @@
ALTER TABLE `crm_content` RENAME TO `crm_record`;
ALTER TABLE `crm_record` MODIFY COLUMN `json` json DEFAULT NULL COMMENT 'Records in JSON format.';
ALTER TABLE `crm_content_column` RENAME TO `crm_record_column`;
ALTER TABLE `crm_record_column` CHANGE COLUMN `content_id` `record_id` bigint(20);
ALTER TABLE `crm_content_links` RENAME TO `crm_record_links`;
ALTER TABLE `crm_record_links` CHANGE COLUMN `content_id` `record_id` bigint(20) unsigned;
ALTER TABLE `crm_record_links` CHANGE COLUMN `rel_content_id` `rel_record_id` bigint(20) unsigned;
@@ -1,12 +0,0 @@
CREATE TABLE `crm_chart` (
`id` BIGINT(20) UNSIGNED NOT NULL,
`name` VARCHAR(64) NOT NULL COMMENT 'The name of the chart',
`config` JSON NOT NULL COMMENT 'Chart & reporting configuration',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT NULL,
`deleted_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
DROP TABLE `crm_field`;
@@ -1,15 +0,0 @@
CREATE TABLE `crm_trigger` (
`id` BIGINT(20) UNSIGNED NOT NULL,
`name` VARCHAR(64) NOT NULL COMMENT 'The name of the trigger',
`enabled` BOOLEAN NOT NULL COMMENT 'Trigger enabled?',
`actions` TEXT NOT NULL COMMENT 'All actions that trigger it',
`source` TEXT NOT NULL COMMENT 'Trigger source',
`rel_module` BIGINT(20) UNSIGNED NULL COMMENT 'Primary module',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT NULL,
`deleted_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
ALTER TABLE `crm_record` DROP COLUMN `json`;
@@ -1,25 +0,0 @@
-- No more links, we'll handle this through ref field on crm_record_value tbl
DROP TABLE IF EXISTS `crm_record_links`;
-- Not columns, values
ALTER TABLE `crm_record_column` RENAME TO `crm_record_value`;
-- Simplify names
ALTER TABLE `crm_record_value` CHANGE COLUMN `column_name` `name` VARCHAR(64);
ALTER TABLE `crm_record_value` CHANGE COLUMN `column_value` `value` TEXT;
-- Add reference
ALTER TABLE `crm_record_value` ADD COLUMN `ref` BIGINT UNSIGNED DEFAULT 0 NOT NULL;
ALTER TABLE `crm_record_value` ADD COLUMN `deleted_at` datetime DEFAULT NULL;
ALTER TABLE `crm_record_value` ADD COLUMN `place` INT UNSIGNED DEFAULT 0 NOT NULL;
ALTER TABLE `crm_record_value` DROP PRIMARY KEY, ADD PRIMARY KEY(`record_id`, `name`, `place`);
CREATE INDEX crm_record_value_ref ON crm_record_value (ref);
-- We want this as a real field
ALTER TABLE `crm_module_form` ADD COLUMN `is_multi` TINYINT(1) NOT NULL;
-- This will be handled through meta(json) fieldd
ALTER TABLE `crm_module_form` DROP COLUMN `help_text`;
ALTER TABLE `crm_module_form` DROP COLUMN `max_length`;
ALTER TABLE `crm_module_form` DROP COLUMN `default_Value`;
@@ -1,7 +0,0 @@
ALTER TABLE `crm_record` CHANGE COLUMN `user_id` `owned_by` BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE `crm_record` ADD COLUMN `created_by` BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE `crm_record` ADD COLUMN `updated_by` BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE `crm_record` ADD COLUMN `deleted_by` BIGINT UNSIGNED NOT NULL DEFAULT 0;
UPDATE crm_record SET created_by = owned_by;
UPDATE crm_record SET updated_by = owned_by WHERE updated_at IS NOT NULL;
UPDATE crm_record SET deleted_by = owned_by WHERE deleted_at IS NOT NULL;
@@ -1,24 +0,0 @@
CREATE TABLE crm_attachment (
id BIGINT UNSIGNED NOT NULL,
rel_owner BIGINT UNSIGNED NOT NULL,
kind VARCHAR(32) NOT NULL,
url VARCHAR(512),
preview_url VARCHAR(512),
size INT UNSIGNED,
mimetype VARCHAR(255),
name TEXT,
meta JSON,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- page attachments will be referenced via page-block meta data
-- module/record attachment will be referenced via crm_record_value
@@ -1,30 +0,0 @@
DROP TABLE IF EXISTS crm_field;
DROP TABLE IF EXISTS crm_fields;
DROP TABLE IF EXISTS crm_content;
DROP TABLE IF EXISTS crm_content_links;
DROP TABLE IF EXISTS crm_content_column;
DROP TABLE IF EXISTS crm_module_content;
ALTER TABLE crm_attachment
RENAME TO compose_attachment;
ALTER TABLE crm_chart
RENAME TO compose_chart;
ALTER TABLE crm_module
RENAME TO compose_module;
ALTER TABLE crm_module_form
RENAME TO compose_module_form;
ALTER TABLE crm_page
RENAME TO compose_page;
ALTER TABLE crm_record
RENAME TO compose_record;
ALTER TABLE crm_record_value
RENAME TO compose_record_value;
ALTER TABLE crm_trigger
RENAME TO compose_trigger;
@@ -1,14 +0,0 @@
CREATE TABLE `compose_namespace` (
`id` BIGINT(20) UNSIGNED NOT NULL,
`name` VARCHAR(64) NOT NULL COMMENT 'Name',
`slug` VARCHAR(64) NOT NULL COMMENT 'URL slug',
`enabled` BOOLEAN NOT NULL COMMENT 'Is namespace enabled?',
`meta` JSON NOT NULL COMMENT 'Meta data',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT NULL,
`deleted_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,61 +0,0 @@
ALTER TABLE `compose_attachment`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
ALTER TABLE `compose_chart`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
ALTER TABLE `compose_module`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
ALTER TABLE `compose_page`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
ALTER TABLE `compose_record`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
ALTER TABLE `compose_trigger`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
UPDATE `compose_attachment` SET `rel_namespace` = 88714882739863655;
UPDATE `compose_chart` SET `rel_namespace` = 88714882739863655;
UPDATE `compose_module` SET `rel_namespace` = 88714882739863655;
UPDATE `compose_page` SET `rel_namespace` = 88714882739863655;
UPDATE `compose_record` SET `rel_namespace` = 88714882739863655;
UPDATE `compose_trigger` SET `rel_namespace` = 88714882739863655;
ALTER TABLE `compose_attachment`
ADD CONSTRAINT `compose_attachment_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
ALTER TABLE `compose_chart`
ADD CONSTRAINT `compose_chart_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
ALTER TABLE `compose_module`
ADD CONSTRAINT `compose_module_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
ALTER TABLE `compose_page`
ADD CONSTRAINT `compose_page_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
ALTER TABLE `compose_record`
ADD CONSTRAINT `compose_record_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
ALTER TABLE `compose_trigger`
ADD CONSTRAINT `compose_trigger_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
@@ -1,6 +0,0 @@
ALTER TABLE `compose_page`
ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN `updated_at` DATETIME DEFAULT NULL,
ADD COLUMN `deleted_at` DATETIME DEFAULT NULL;
ALTER TABLE `compose_page` CHANGE COLUMN `module_id` `rel_module` BIGINT UNSIGNED NOT NULL DEFAULT 0;
@@ -1,31 +0,0 @@
ALTER TABLE compose_module_form
RENAME TO compose_module_field;
-- Remove orphaned and invalid fields
DELETE FROM `compose_module_field` WHERE `module_id` NOT IN (SELECT `id` FROM `compose_module`) OR `name` = '';
-- Order and consistency.
ALTER TABLE `compose_module_field`
ADD COLUMN `id` BIGINT UNSIGNED NOT NULL FIRST,
ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN `updated_at` DATETIME DEFAULT NULL,
ADD COLUMN `deleted_at` DATETIME DEFAULT NULL,
RENAME COLUMN `module_id` TO `rel_module`,
RENAME COLUMN `json` TO `options`;
-- Generate IDs for the new field, use module, offset by one (just to start with a different ID)
-- and use place (0 based, +1 for every field, expecting to be unique per module because of the existing pkey)
UPDATE `compose_module_field` SET id = rel_module + 1 + place;
-- Drop old primary key (module_id, place)
ALTER TABLE `compose_module_field` DROP PRIMARY KEY, ADD PRIMARY KEY(`id`);
-- Foreign key
ALTER TABLE `compose_module_field`
ADD CONSTRAINT `compose_module`
FOREIGN KEY (`rel_module`)
REFERENCES `compose_module` (`id`);
-- And unique indexes for module+place/name combos.
CREATE UNIQUE INDEX uid_compose_module_field_place ON compose_module_field (`rel_module`, `place`);
CREATE UNIQUE INDEX uid_compose_module_field_name ON compose_module_field (`rel_module`, `name`);
@@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS compose_permission_rules (
rel_role BIGINT UNSIGNED NOT NULL,
resource VARCHAR(128) NOT NULL,
operation VARCHAR(128) NOT NULL,
access TINYINT(1) NOT NULL,
PRIMARY KEY (rel_role, resource, operation)
) ENGINE=InnoDB;
@@ -1,74 +0,0 @@
DROP TABLE IF EXISTS compose_automation_trigger;
DROP TABLE IF EXISTS compose_automation_script;
CREATE TABLE IF NOT EXISTS compose_automation_script (
`id` BIGINT(20) UNSIGNED NOT NULL,
`name` VARCHAR(64) NOT NULL DEFAULT 'unnamed' COMMENT 'The name of the script',
`source` TEXT NOT NULL COMMENT 'Source code for the script',
`source_ref` VARCHAR(200) NOT NULL COMMENT 'Where is the script located (if remote)',
`async` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Do we run this script asynchronously?',
`rel_runner` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Who is running the script? 0 for invoker',
`run_in_ua` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Run this script inside user-agent environment',
`timeout` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Any explicit timeout set for this script (milliseconds)?',
`critical` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Is it critical that this script is executed successfully',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Is this script enabled?',
`created_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS compose_automation_trigger (
`id` BIGINT(20) UNSIGNED NOT NULL,
`rel_script` BIGINT(20) UNSIGNED NOT NULL COMMENT 'Script that is triggered',
`resource` VARCHAR(128) NOT NULL COMMENT 'Resource triggering the event',
`event` VARCHAR(128) NOT NULL COMMENT 'Event triggered',
`event_condition`
TEXT NOT NULL COMMENT 'Trigger condition',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Trigger enabled?',
`weight` INT NOT NULL DEFAULT 0,
`created_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`deleted_at` DATETIME NULL DEFAULT NULL,
CONSTRAINT `fk_script` FOREIGN KEY (`rel_script`) REFERENCES `compose_automation_script` (`id`),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# Migrate old triggers into scripts
INSERT INTO compose_automation_script (id, name, source, source_ref, run_in_ua, critical, enabled, created_at, updated_at, deleted_at)
SELECT id, name, source, '', true, false, enabled, created_at, updated_at, deleted_at from compose_trigger;
# Migrate old triggers into new triggers
INSERT INTO compose_automation_trigger (id, event, resource, event_condition, rel_script, enabled, created_at, updated_at, deleted_at)
SELECT id+seq, events.event, 'compose:record', rel_module, id, enabled, created_at, updated_at, deleted_at from compose_trigger AS t INNER JOIN
( SELECT 0 as seq, '' AS event
UNION SELECT 1 as seq, 'manual' AS event
UNION SELECT 2 as seq, 'beforeCreate' AS event
UNION SELECT 3 as seq, 'afterCreate' AS event
UNION SELECT 4 as seq, 'beforeUpdate' AS event
UNION SELECT 5 as seq, 'afterUpdate' AS event
UNION SELECT 6 as seq, 'beforeDelete' AS event
UNION SELECT 7 as seq, 'afterDelete' AS event) AS events ON ((event = '' AND t.actions = '')
OR (event <> '' AND t.actions LIKE concat('%',event,'%') ));
# Normalize and cleanup
UPDATE compose_automation_trigger SET event = 'manual' WHERE event = '';
DELETE FROM compose_automation_trigger WHERE event_condition IN ('', '0') AND event <> 'manual';
DROP TABLE IF EXISTS compose_trigger;
@@ -1,10 +0,0 @@
ALTER TABLE `compose_automation_script`
ADD `rel_namespace` BIGINT UNSIGNED NOT NULL AFTER `id`,
ADD INDEX (`rel_namespace`);
UPDATE `compose_automation_script` SET `rel_namespace` = (SELECT MIN(id) FROM compose_namespace);
ALTER TABLE `compose_automation_script`
ADD CONSTRAINT `compose_automation_script_namespace`
FOREIGN KEY (`rel_namespace`)
REFERENCES `compose_namespace` (`id`);
@@ -1,3 +0,0 @@
ALTER TABLE `compose_module_field`
ADD `default_value` JSON DEFAULT NULL COMMENT 'Default value as a record value set.'
AFTER `options`;
@@ -1,3 +0,0 @@
ALTER TABLE `compose_module` ADD `handle` VARCHAR(200) NOT NULL AFTER `id`;
ALTER TABLE `compose_page` ADD `handle` VARCHAR(200) NOT NULL AFTER `id`;
ALTER TABLE `compose_chart` ADD `handle` VARCHAR(200) NOT NULL AFTER `id`;
@@ -1,10 +0,0 @@
CREATE TABLE IF NOT EXISTS `compose_settings` (
rel_owner BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Value owner, 0 for global settings',
name VARCHAR(200) NOT NULL COMMENT 'Unique set of setting keys',
value JSON COMMENT 'Setting value',
updated_at DATETIME NOT NULL DEFAULT NOW() COMMENT 'When was the value updated',
updated_by BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Who created/updated the value',
PRIMARY KEY (name, rel_owner)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
ALTER TABLE `compose_record_value` MODIFY `value` LONGTEXT;
-8
View File
@@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS `migrations` (
`project` varchar(16) NOT NULL COMMENT 'sam, crm, ...',
`filename` varchar(255) NOT NULL COMMENT 'yyyymmddHHMMSS.sql',
`statement_index` int(11) NOT NULL COMMENT 'Statement number from SQL file',
`status` text NOT NULL COMMENT 'ok or full error message',
PRIMARY KEY (`project`,`filename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-2
View File
@@ -1,2 +0,0 @@
#!/bin/bash
touch $(date +%Y%m%d%H%M%S).up.sql
-8
View File
@@ -1,8 +0,0 @@
package db
type migration struct {
Project string `db:"project"`
Filename string `db:"filename"`
StatementIndex int `db:"statement_index"`
Status string `db:"status"`
}
-117
View File
@@ -1,117 +0,0 @@
package db
import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/goware/statik/fs"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"go.uber.org/zap"
"github.com/cortezaproject/corteza-server/messaging/db/mysql"
)
func statements(contents []byte, err error) ([]string, error) {
if err != nil {
return []string{}, err
}
return regexp.MustCompilePOSIX(";$").Split(string(contents), -1), nil
}
func Migrate(db *factory.DB, log *zap.Logger) error {
log = log.Named("database.migrations")
statikFS, err := fs.New(mysql.Asset)
if err != nil {
return errors.Wrap(err, "error creating statik filesystem")
}
var files []string
fn := func(filename string, info os.FileInfo, err error) error {
_ = err
matched, err := filepath.Match("/*.up.sql", filename)
if matched {
files = append(files, filename)
}
return err
}
if err := fs.Walk(statikFS, "/", fn); err != nil {
return errors.Wrap(err, "error when listing files for migrations")
}
sort.Strings(files)
if len(files) == 0 {
return errors.New("no files encoded for migration, need at least one SQL file")
}
migrate := func(filename string, useLog bool) error {
status := migration{
Project: "sam",
Filename: filename,
}
if useLog {
if err := db.Get(&status, "select * from migrations where project=? and filename=?", status.Project, status.Filename); err != nil {
return err
}
if status.Status == "ok" {
return nil
}
}
up := func() error {
stmts, err := statements(fs.ReadFile(statikFS, filename))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading migration %s", filename))
}
log.Debug("Running migration", zap.String("filename", filename))
for idx, query := range stmts {
if strings.TrimSpace(query) != "" && idx >= status.StatementIndex {
status.StatementIndex = idx
if _, err := db.Exec(query); err != nil {
log.Debug("migration error ", zap.String("filename", filename), zap.Error(err))
return err
}
}
}
status.Status = "ok"
return nil
}
err := db.Transaction(up)
if err != nil {
status.Status = err.Error()
}
if useLog {
if err := db.Replace("migrations", status); err != nil {
return errors.Wrap(err, "migration update failed")
}
}
return err
}
if err := migrate("/migrations.sql", false); err != nil {
return err
}
db.Exec("LOCK TABLE migrations WRITE;")
defer db.Exec("UNLOCK TABLES")
for _, filename := range files {
if err := migrate(filename, true); err != nil {
return err
}
}
return nil
}
File diff suppressed because one or more lines are too long
@@ -1,128 +0,0 @@
-- Keeps all known channels
CREATE TABLE channels (
id BIGINT UNSIGNED NOT NULL,
name TEXT NOT NULL, -- display name of the channel
topic TEXT NOT NULL,
meta JSON NOT NULL,
type ENUM ('private', 'public', 'group') NOT NULL DEFAULT 'public',
rel_organisation BIGINT UNSIGNED NOT NULL REFERENCES organisation(id),
rel_creator BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
archived_at DATETIME NULL,
deleted_at DATETIME NULL, -- channel soft delete
rel_last_message BIGINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- handles channel membership
CREATE TABLE channel_members (
rel_channel BIGINT UNSIGNED NOT NULL REFERENCES channels(id),
rel_user BIGINT UNSIGNED NOT NULL,
type ENUM ('owner', 'member', 'invitee') NOT NULL DEFAULT 'member',
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
PRIMARY KEY (rel_channel, rel_user)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE channel_views (
rel_channel BIGINT UNSIGNED NOT NULL REFERENCES channels(id),
rel_user BIGINT UNSIGNED NOT NULL,
-- timestamp of last view, should be enough to find out which messaghr
viewed_at DATETIME NOT NULL DEFAULT NOW(),
-- new messages count since last view
new_since INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (rel_user, rel_channel)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE channel_pins (
rel_channel BIGINT UNSIGNED NOT NULL REFERENCES channels(id),
rel_message BIGINT UNSIGNED NOT NULL REFERENCES messages(id),
rel_user BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY (rel_channel, rel_message)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE messages (
id BIGINT UNSIGNED NOT NULL,
type TEXT,
message TEXT NOT NULL,
meta JSON,
rel_user BIGINT UNSIGNED NOT NULL,
rel_channel BIGINT UNSIGNED NOT NULL REFERENCES channels(id),
reply_to BIGINT UNSIGNED NULL REFERENCES messages(id),
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE reactions (
id BIGINT UNSIGNED NOT NULL,
rel_user BIGINT UNSIGNED NOT NULL,
rel_message BIGINT UNSIGNED NOT NULL REFERENCES messages(id),
rel_channel BIGINT UNSIGNED NOT NULL REFERENCES channels(id),
reaction TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE attachments (
id BIGINT UNSIGNED NOT NULL,
rel_user BIGINT UNSIGNED NOT NULL,
url VARCHAR(512),
preview_url VARCHAR(512),
size INT UNSIGNED,
mimetype VARCHAR(255),
name TEXT,
meta JSON,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE message_attachment (
rel_message BIGINT UNSIGNED NOT NULL REFERENCES messages(id),
rel_attachment BIGINT UNSIGNED NOT NULL REFERENCES attachment(id),
PRIMARY KEY (rel_message)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE event_queue (
id BIGINT UNSIGNED NOT NULL,
origin BIGINT UNSIGNED NOT NULL,
subscriber TEXT,
payload JSON,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE event_queue_synced (
origin BIGINT UNSIGNED NOT NULL,
rel_last BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (origin)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,3 +0,0 @@
update channels set type = 'group' where type = 'direct';
alter table channels CHANGE type type enum('private', 'public', 'group');
alter table channel_members CHANGE type type enum('owner', 'member', 'invitee');
@@ -1,20 +0,0 @@
ALTER TABLE channel_views DROP viewed_at;
ALTER TABLE channel_views ADD rel_last_message_id BIGINT UNSIGNED;
ALTER TABLE channel_views CHANGE new_since new_messages_count INT UNSIGNED;
-- Table structure after these changes:
-- +---------------------+---------------------+------+-----+---------+-------+
-- | Field | Type | Null | Key | Default | Extra |
-- +---------------------+---------------------+------+-----+---------+-------+
-- | rel_channel | bigint(20) unsigned | NO | PRI | NULL | |
-- | rel_user | bigint(20) unsigned | NO | PRI | NULL | |
-- | rel_last_message_id | bigint(20) unsigned | YES | | NULL | |
-- | new_messages_count | int(10) unsigned | NO | | 0 | |
-- +---------------------+---------------------+------+-----+---------+-------+
-- Prefill with data
INSERT INTO channel_views (rel_channel, rel_user, rel_last_message_id)
SELECT cm.rel_channel, cm.rel_user, max(m.ID)
FROM channel_members AS cm INNER JOIN messages AS m ON (m.rel_channel = cm.rel_channel)
GROUP BY cm.rel_channel, cm.rel_user;
@@ -1,2 +0,0 @@
ALTER TABLE messages CHANGE reply_to reply_to BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE messages ADD replies INT UNSIGNED NOT NULL DEFAULT 0;
@@ -1,14 +0,0 @@
DROP TABLE channel_pins;
DROP TABLE reactions;
CREATE TABLE message_flags (
id BIGINT UNSIGNED NOT NULL,
rel_channel BIGINT UNSIGNED NOT NULL,
rel_message BIGINT UNSIGNED NOT NULL,
rel_user BIGINT UNSIGNED NOT NULL,
flag TEXT,
created_at DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,13 +0,0 @@
CREATE TABLE mentions (
id BIGINT UNSIGNED NOT NULL,
rel_channel BIGINT UNSIGNED NOT NULL,
rel_message BIGINT UNSIGNED NOT NULL,
rel_user BIGINT UNSIGNED NOT NULL,
rel_mentioned_by BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX lookup_mentions ON mentions (rel_mentioned_by)
@@ -1,8 +0,0 @@
ALTER TABLE channel_views RENAME TO unreads;
ALTER TABLE unreads ADD rel_reply_to BIGINT UNSIGNED NOT NULL AFTER rel_channel;
ALTER TABLE unreads CHANGE rel_channel rel_channel BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE unreads CHANGE rel_user rel_user BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE unreads CHANGE rel_last_message_id rel_last_message BIGINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE unreads CHANGE new_messages_count count INT UNSIGNED NOT NULL DEFAULT 0;
@@ -1,2 +0,0 @@
DROP TABLE event_queue;
DROP TABLE event_queue_synced;
@@ -1 +0,0 @@
alter table messages convert to character set utf8mb4 collate utf8mb4_unicode_ci;
@@ -1 +0,0 @@
ALTER TABLE channel_members ADD flag ENUM ('pinned', 'hidden', 'ignored', '') NOT NULL DEFAULT '' AFTER `type`;
@@ -1,16 +0,0 @@
-- misc tables
ALTER TABLE attachments RENAME TO messaging_attachment;
ALTER TABLE mentions RENAME TO messaging_mention;
ALTER TABLE unreads RENAME TO messaging_unread;
-- channel tables
ALTER TABLE channels RENAME TO messaging_channel;
ALTER TABLE channel_members RENAME TO messaging_channel_member;
-- message tables
ALTER TABLE messages RENAME TO messaging_message;
ALTER TABLE message_attachment RENAME TO messaging_message_attachment;
ALTER TABLE message_flags RENAME TO messaging_message_flag;
@@ -1,23 +0,0 @@
CREATE TABLE `messaging_webhook` (
`id` bigint(20) unsigned NOT NULL,
`kind` varchar(8) NOT NULL COMMENT 'Kind: incoming, outgoing',
`token` varchar(255) NOT NULL COMMENT 'Authentication token',
`rel_owner` bigint(20) unsigned NOT NULL COMMENT 'Webhook owner User ID',
`rel_user` bigint(20) unsigned NOT NULL COMMENT 'Webhook message User ID',
`rel_channel` bigint(20) unsigned NOT NULL COMMENT 'Channel ID',
`outgoing_trigger` varchar(32) NOT NULL COMMENT 'Outgoing command trigger',
`outgoing_url` varchar(255) NOT NULL COMMENT 'URL for POST request',
`created_at` datetime NOT NULL,
`updated_at` datetime NULL,
`deleted_at` datetime NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- get webhook by command trigger
ALTER TABLE `messaging_webhook` ADD UNIQUE(`outgoing_trigger`);
-- list webhooks by owner (list your own webhooks)
ALTER TABLE `messaging_webhook` ADD INDEX(`rel_owner`);
-- list webhooks on a channel
ALTER TABLE `messaging_webhook` ADD INDEX(`rel_channel`);
@@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS messaging_permission_rules (
rel_role BIGINT UNSIGNED NOT NULL,
resource VARCHAR(128) NOT NULL,
operation VARCHAR(128) NOT NULL,
access TINYINT(1) NOT NULL,
PRIMARY KEY (rel_role, resource, operation)
) ENGINE=InnoDB;
@@ -1,41 +0,0 @@
UPDATE `messaging_unread` SET rel_reply_to = 0 WHERE rel_reply_to IS NULL;
ALTER TABLE `messaging_unread` CHANGE COLUMN `rel_reply_to` `rel_reply_to` BIGINT UNSIGNED NOT NULL;
ALTER TABLE `messaging_unread` DROP PRIMARY KEY, ADD PRIMARY KEY(`rel_channel`, `rel_reply_to`, `rel_user`);
-- Add entries for all (unexisting) unreads (channels & threads)
INSERT IGNORE INTO messaging_unread
(rel_channel, rel_reply_to, rel_user)
SELECT DISTINCT cm.rel_channel, msg.id, cm.rel_user
FROM messaging_channel_member AS cm
INNER JOIN messaging_message AS msg ON (cm.rel_channel = msg.rel_channel AND replies > 0)
WHERE NOT EXISTS (SELECT 1 FROM messaging_unread AS u WHERE u.rel_reply_to = msg.id AND u.rel_user = cm.rel_user)
AND msg.rel_user > 0
UNION
SELECT DISTINCT cm.rel_channel, 0, cm.rel_user
FROM messaging_channel_member AS cm
WHERE NOT EXISTS (SELECT 1 FROM messaging_unread AS u WHERE u.rel_channel = cm.rel_channel AND u.rel_user = cm.rel_user)
AND cm.rel_user > 0
;
-- Update counters for channel messages
INSERT IGNORE INTO messaging_unread
(rel_channel, rel_reply_to, rel_user, count, rel_last_message)
SELECT u.rel_channel, 0, u.rel_user, COUNT(m.id), u.rel_last_message
FROM messaging_unread AS u
INNER JOIN messaging_message AS m ON (u.rel_channel = m.rel_channel AND m.id > u.rel_last_message)
WHERE u.rel_reply_to = 0
AND m.reply_to = 0
GROUP BY u.rel_channel, u.rel_user;
-- Update counters for thread messages
INSERT IGNORE INTO messaging_unread
(rel_channel, rel_reply_to, rel_user, count, rel_last_message)
SELECT u.rel_channel, rpl.reply_to, u.rel_user, COUNT(rpl.id), u.rel_last_message
FROM messaging_unread AS u
INNER JOIN messaging_message AS rpl ON (u.rel_channel = rpl.rel_channel AND rpl.reply_to = u.rel_reply_to AND rpl.id > u.rel_last_message)
WHERE rpl.replies > 0 AND u.rel_reply_to > 0
GROUP BY u.rel_channel, rpl.reply_to, u.rel_user;
@@ -1 +0,0 @@
ALTER TABLE `messaging_channel` ADD `membership_policy` ENUM ('featured', 'forced', '') NOT NULL DEFAULT '' AFTER `type`;
@@ -1,10 +0,0 @@
CREATE TABLE IF NOT EXISTS `messaging_settings` (
rel_owner BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Value owner, 0 for global settings',
name VARCHAR(200) NOT NULL COMMENT 'Unique set of setting keys',
value JSON COMMENT 'Setting value',
updated_at DATETIME NOT NULL DEFAULT NOW() COMMENT 'When was the value updated',
updated_by BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Who created/updated the value',
PRIMARY KEY (name, rel_owner)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
DROP TABLE `messaging_webhook`;
-8
View File
@@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS `migrations` (
`project` varchar(16) NOT NULL COMMENT 'sam, crm, ...',
`filename` varchar(255) NOT NULL COMMENT 'yyyymmddHHMMSS.sql',
`statement_index` int(11) NOT NULL COMMENT 'Statement number from SQL file',
`status` TEXT NOT NULL COMMENT 'ok or full error message',
PRIMARY KEY (`project`,`filename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-2
View File
@@ -1,2 +0,0 @@
#!/bin/bash
touch $(date +%Y%m%d%H%M%S).up.sql
-8
View File
@@ -1,8 +0,0 @@
package db
type migration struct {
Project string `db:"project"`
Filename string `db:"filename"`
StatementIndex int `db:"statement_index"`
Status string `db:"status"`
}
-117
View File
@@ -1,117 +0,0 @@
package db
import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/goware/statik/fs"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"go.uber.org/zap"
"github.com/cortezaproject/corteza-server/system/db/mysql"
)
func statements(contents []byte, err error) ([]string, error) {
if err != nil {
return []string{}, err
}
return regexp.MustCompilePOSIX(";$").Split(string(contents), -1), nil
}
func Migrate(db *factory.DB, log *zap.Logger) error {
log = log.Named("database.migrations")
statikFS, err := fs.New(mysql.Asset)
if err != nil {
return errors.Wrap(err, "error creating statik filesystem")
}
var files []string
fn := func(filename string, info os.FileInfo, err error) error {
_ = err
matched, err := filepath.Match("/*.up.sql", filename)
if matched {
files = append(files, filename)
}
return err
}
if err := fs.Walk(statikFS, "/", fn); err != nil {
return errors.Wrap(err, "error when listing files for migrations")
}
sort.Strings(files)
if len(files) == 0 {
return errors.New("no files encoded for migration, need at least one SQL file")
}
migrate := func(filename string, useLog bool) error {
status := migration{
Project: "system",
Filename: filename,
}
if useLog {
if err := db.Get(&status, "select * from migrations where project=? and filename=?", status.Project, status.Filename); err != nil {
return err
}
if status.Status == "ok" {
return nil
}
}
up := func() error {
stmts, err := statements(fs.ReadFile(statikFS, filename))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading migration %s", filename))
}
log.Debug("Running migration", zap.String("filename", filename))
for idx, query := range stmts {
if strings.TrimSpace(query) != "" && idx >= status.StatementIndex {
status.StatementIndex = idx
if _, err := db.Exec(query); err != nil {
log.Debug("migration error ", zap.String("filename", filename), zap.Error(err))
return err
}
}
}
status.Status = "ok"
return nil
}
err := db.Transaction(up)
if err != nil {
status.Status = err.Error()
}
if useLog {
if err := db.Replace("migrations", status); err != nil {
return errors.Wrap(err, "migration update failed")
}
}
return err
}
if err := migrate("/migrations.sql", false); err != nil {
return err
}
db.Exec("LOCK TABLE migrations WRITE;")
defer db.Exec("UNLOCK TABLES")
for _, filename := range files {
if err := migrate(filename, true); err != nil {
return err
}
}
return nil
}
File diff suppressed because one or more lines are too long
@@ -1,66 +0,0 @@
-- all known organisations (crust instances) and our relation towards them
CREATE TABLE organisations (
id BIGINT UNSIGNED NOT NULL,
fqn TEXT NOT NULL, -- fully qualified name of the organisation
name TEXT NOT NULL, -- display name of the organisation
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
archived_at DATETIME NULL,
deleted_at DATETIME NULL, -- organisation soft delete
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE settings (
name VARCHAR(200) NOT NULL COMMENT 'Unique set of setting keys',
value TEXT COMMENT 'Setting value',
PRIMARY KEY (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Keeps all known users, home and external organisation
-- changes are stored in audit log
CREATE TABLE users (
id BIGINT UNSIGNED NOT NULL,
email TEXT NOT NULL,
username TEXT NOT NULL,
password TEXT NOT NULL,
name TEXT NOT NULL,
handle TEXT NOT NULL,
meta JSON NOT NULL,
satosa_id CHAR(36) NULL,
rel_organisation BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
suspended_at DATETIME NULL,
deleted_at DATETIME NULL, -- user soft delete
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE UNIQUE INDEX uid_satosa ON users (satosa_id);
-- Keeps all known teams
CREATE TABLE teams (
id BIGINT UNSIGNED NOT NULL,
name TEXT NOT NULL, -- display name of the team
handle TEXT NOT NULL, -- team handle string
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
archived_at DATETIME NULL,
deleted_at DATETIME NULL, -- team soft delete
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Keeps team memberships
CREATE TABLE team_members (
rel_team BIGINT UNSIGNED NOT NULL REFERENCES organisation(id),
rel_user BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (rel_team, rel_user)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,4 +0,0 @@
ALTER TABLE teams RENAME TO sys_team;
ALTER TABLE organisations RENAME TO sys_organisation;
ALTER TABLE team_members RENAME TO sys_team_member;
ALTER TABLE users RENAME TO sys_user;
@@ -1,5 +0,0 @@
# add field to manage user type (bot support)
ALTER TABLE `sys_user` ADD `kind` VARCHAR(8) NOT NULL DEFAULT '' AFTER `handle`;
# add field to manage "ownership" (get all bots created by user)
ALTER TABLE `sys_user` ADD `rel_user_id` BIGINT UNSIGNED NOT NULL AFTER `rel_organisation`, ADD INDEX (`rel_user_id`);
@@ -1 +0,0 @@
ALTER TABLE `sys_user` DROP INDEX `uid_satosa`, ADD INDEX `uid_satosa` (`satosa_id`) USING BTREE;
@@ -1,19 +0,0 @@
-- Keeps all known users, home and external organisation
-- changes are stored in audit log
CREATE TABLE sys_credentials (
id BIGINT UNSIGNED NOT NULL,
rel_owner BIGINT UNSIGNED NOT NULL REFERENCES sys_users(id),
label TEXT NOT NULL COMMENT 'something we can differentiate credentials by',
kind VARCHAR(128) NOT NULL COMMENT 'hash, facebook, gplus, github, linkedin ...',
credentials TEXT NOT NULL COMMENT 'crypted/hashed passwords, secrets, social profile ID',
meta JSON NOT NULL,
expires_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL, -- user soft delete
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX idx_owner ON sys_credentials (rel_owner);
@@ -1 +0,0 @@
ALTER TABLE `sys_user` MODIFY `password` TEXT NULL;
@@ -1,8 +0,0 @@
CREATE TABLE `sys_rules` (
`rel_team` BIGINT UNSIGNED NOT NULL,
`resource` VARCHAR(128) NOT NULL,
`operation` VARCHAR(128) NOT NULL,
`value` TINYINT(1) NOT NULL,
PRIMARY KEY (`rel_team`, `resource`, `operation`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,5 +0,0 @@
ALTER TABLE sys_team RENAME TO sys_role;
ALTER TABLE sys_team_member RENAME TO sys_role_member;
ALTER TABLE `sys_role_member` CHANGE COLUMN `rel_team` `rel_role` BIGINT UNSIGNED NOT NULL;
ALTER TABLE `sys_rules` CHANGE COLUMN `rel_team` `rel_role` BIGINT UNSIGNED NOT NULL;
@@ -1,4 +0,0 @@
REPLACE INTO `sys_role` (`id`, `name`, `handle`) VALUES
(1, 'Everyone', 'everyone'),
(2, 'Administrators', 'admins');
@@ -1,33 +0,0 @@
CREATE TABLE sys_application (
id BIGINT UNSIGNED NOT NULL,
rel_owner BIGINT UNSIGNED NOT NULL REFERENCES sys_users(id),
name TEXT NOT NULL COMMENT 'something we can differentiate application by',
enabled BOOL NOT NULL,
unify JSON NULL COMMENT 'unify specific settings',
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL, -- user soft delete
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
REPLACE INTO `sys_application` (`id`, `name`, `enabled`, `rel_owner`, `unify`) VALUES
( 1, 'Crust Messaging', true, 0,
'{"logo": "/applications/crust.jpg", "icon": "/applications/crust_favicon.png", "url": "/messaging/", "listed": true}'
),
( 2, 'Crust CRM', true, 0,
'{"logo": "/applications/crust.jpg", "icon": "/applications/crust_favicon.png", "url": "/crm/", "listed": true}'
),
( 3, 'Crust Admin Area', true, 0,
'{"logo": "/applications/crust.jpg", "icon": "/applications/crust_favicon.png", "url": "/admin/", "listed": true}'
),
( 4, 'Corteza Jitsi Bridge', true, 0,
'{"logo": "/applications/jitsi.png", "icon": "/applications/jitsi_icon.png", "url": "/bridge/jitsi/", "listed": true}'
),
( 5, 'Google Maps', true, 0,
'{"logo": "/applications/google_maps.png", "icon": "/applications/google_maps_icon.png", "url": "/bridge/google-maps/", "listed": true}'
);
@@ -1,12 +0,0 @@
DROP TABLE IF EXISTS `settings`;
CREATE TABLE IF NOT EXISTS `sys_settings` (
rel_owner BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Value owner, 0 for global settings',
name VARCHAR(200) NOT NULL COMMENT 'Unique set of setting keys',
value JSON COMMENT 'Setting value',
updated_at DATETIME NOT NULL DEFAULT NOW() COMMENT 'When was the value updated',
updated_by BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Who created/updated the value',
PRIMARY KEY (name, rel_owner)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,3 +0,0 @@
ALTER TABLE `sys_user` DROP `password`;
ALTER TABLE `sys_user` DROP `satosa_id`;
ALTER TABLE `sys_credentials` ADD `last_used_at` DATETIME NULL;
@@ -1 +0,0 @@
ALTER TABLE `sys_user` ADD `email_confirmed` BOOLEAN NOT NULL DEFAULT FALSE;
@@ -1,4 +0,0 @@
UPDATE `sys_application`
SET `name` = 'Crust Compose',
`unify` = '{"logo": "/applications/default_logo.jpg", "icon": "/applications/default_icon.png", "url": "/compose/", "listed": true}'
WHERE id = 2;
@@ -1,40 +0,0 @@
CREATE TABLE IF NOT EXISTS sys_permission_rules (
rel_role BIGINT UNSIGNED NOT NULL,
resource VARCHAR(128) NOT NULL,
operation VARCHAR(128) NOT NULL,
access TINYINT(1) NOT NULL,
PRIMARY KEY (rel_role, resource, operation)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS messaging_permission_rules (
rel_role BIGINT UNSIGNED NOT NULL,
resource VARCHAR(128) NOT NULL,
operation VARCHAR(128) NOT NULL,
access TINYINT(1) NOT NULL,
PRIMARY KEY (rel_role, resource, operation)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS compose_permission_rules (
rel_role BIGINT UNSIGNED NOT NULL,
resource VARCHAR(128) NOT NULL,
operation VARCHAR(128) NOT NULL,
access TINYINT(1) NOT NULL,
PRIMARY KEY (rel_role, resource, operation)
) ENGINE=InnoDB;
REPLACE sys_permission_rules
(rel_role, resource, operation, access)
SELECT rel_role, resource, operation, `value` - 1 FROM sys_rules WHERE resource LIKE 'system%';
REPLACE compose_permission_rules
(rel_role, resource, operation, access)
SELECT rel_role, resource, operation, `value` - 1 FROM sys_rules WHERE resource LIKE 'compose%';
REPLACE messaging_permission_rules
(rel_role, resource, operation, access)
SELECT rel_role, resource, operation, `value` - 1 FROM sys_rules WHERE resource LIKE 'messaging%';
DROP TABLE sys_rules;
@@ -1,5 +0,0 @@
/* migrates existing credentials */
UPDATE sys_credentials SET kind = 'google' WHERE kind = 'gplus';
/* migrates existing settings. */
UPDATE sys_settings SET name = REPLACE(name, '.gplus.', '.google.') WHERE name LIKE 'auth.external.providers.gplus.%';
@@ -1,48 +0,0 @@
CREATE TABLE IF NOT EXISTS sys_automation_script (
`id` BIGINT(20) UNSIGNED NOT NULL,
`rel_namespace` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'For compatibility only, not used',
`name` VARCHAR(64) NOT NULL DEFAULT 'unnamed' COMMENT 'The name of the script',
`source` TEXT NOT NULL COMMENT 'Source code for the script',
`source_ref` VARCHAR(200) NOT NULL COMMENT 'Where is the script located (if remote)',
`async` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Do we run this script asynchronously?',
`rel_runner` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Who is running the script? 0 for invoker',
`run_in_ua` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Run this script inside user-agent environment',
`timeout` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Any explicit timeout set for this script (milliseconds)?',
`critical` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Is it critical that this script is executed successfully',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Is this script enabled?',
`created_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS sys_automation_trigger (
`id` BIGINT(20) UNSIGNED NOT NULL,
`rel_script` BIGINT(20) UNSIGNED NOT NULL COMMENT 'Script that is triggered',
`resource` VARCHAR(128) NOT NULL COMMENT 'Resource triggering the event',
`event` VARCHAR(128) NOT NULL COMMENT 'Event triggered',
`event_condition`
TEXT NOT NULL COMMENT 'Trigger condition',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT 'Trigger enabled?',
`weight` INT NOT NULL DEFAULT 0,
`created_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`deleted_at` DATETIME NULL DEFAULT NULL,
CONSTRAINT `fk_sys_automation_script` FOREIGN KEY (`rel_script`) REFERENCES `sys_automation_script` (`id`),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,25 +0,0 @@
CREATE TABLE IF NOT EXISTS sys_reminder (
`id` BIGINT(20) UNSIGNED NOT NULL,
`resource` VARCHAR(128) NOT NULL COMMENT 'Resource, that this reminder is bound to',
`payload` JSON NOT NULL COMMENT 'Payload for this reminder',
`snooze_count` INT NOT NULL DEFAULT 0 COMMENT 'Number of times this reminder was snoozed',
`assigned_to` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Assignee for this reminder',
`assigned_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'User that assigned this reminder',
`assigned_at` DATETIME NOT NULL COMMENT 'When the reminder was assigned',
`dismissed_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'User that dismissed this reminder',
`dismissed_at` DATETIME NULL DEFAULT NULL COMMENT 'Time the reminder was dismissed',
`remind_at` DATETIME NULL DEFAULT NULL COMMENT 'Time the user should be reminded',
`created_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
`deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,3 +0,0 @@
UPDATE `sys_settings` SET `name` = 'general.mail.logo' WHERE `rel_owner` = 0 AND `name` = 'system.defaultLogo';
UPDATE `sys_settings` SET `name` = 'general.mail.header.en' WHERE `rel_owner` = 0 AND `name` = 'system.mail.header.en';
UPDATE `sys_settings` SET `name` = 'general.mail.footer.en' WHERE `rel_owner` = 0 AND `name` = 'system.mail.footer.en';
@@ -1,22 +0,0 @@
CREATE TABLE IF NOT EXISTS sys_attachment (
id BIGINT UNSIGNED NOT NULL,
rel_owner BIGINT UNSIGNED NOT NULL,
kind VARCHAR(32) NOT NULL,
url VARCHAR(512),
preview_url VARCHAR(512),
size INT UNSIGNED,
mimetype VARCHAR(255),
name TEXT,
meta JSON,
created_at DATETIME NOT NULL DEFAULT NOW(),
updated_at DATETIME NULL,
deleted_at DATETIME NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1,20 +0,0 @@
CREATE TABLE IF NOT EXISTS sys_actionlog (
ts DATETIME NOT NULL DEFAULT NOW(),
actor_ip_addr VARCHAR(15) NOT NULL,
actor_id BIGINT UNSIGNED,
request_origin VARCHAR(32) NOT NULL,
request_id VARCHAR(64) NOT NULL,
resource VARCHAR(128) NOT NULL,
`action` VARCHAR(64) NOT NULL,
`error` VARCHAR(64) NOT NULL,
severity SMALLINT NOT NULL,
description TEXT,
meta JSON
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX ts ON sys_actionlog (ts DESC);
CREATE INDEX request_origin ON sys_actionlog (request_origin);
CREATE INDEX actor_id ON sys_actionlog (actor_id);
CREATE INDEX resource ON sys_actionlog (resource);
CREATE INDEX `action` ON sys_actionlog (`action`);
-8
View File
@@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS `migrations` (
`project` varchar(16) NOT NULL COMMENT 'sam, crm, ...',
`filename` varchar(255) NOT NULL COMMENT 'yyyymmddHHMMSS.sql',
`statement_index` int(11) NOT NULL COMMENT 'Statement number from SQL file',
`status` TEXT NOT NULL COMMENT 'ok or full error message',
PRIMARY KEY (`project`,`filename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-2
View File
@@ -1,2 +0,0 @@
#!/bin/bash
touch $(date +%Y%m%d%H%M%S).up.sql
-8
View File
@@ -1,8 +0,0 @@
package db
type migration struct {
Project string `db:"project"`
Filename string `db:"filename"`
StatementIndex int `db:"statement_index"`
Status string `db:"status"`
}