1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-24 13:43:12 +02:00

Workspace switcher (#1052)

* API WIP

* WIP

* Finished changes

* Fixed colors:

* Don't enforce charset adn collation in migration, pick from database DSN

* Added MySQL query

* Updated mocks

* Added tests

* Lint fixes

* Fixed typo and removed unsed style

* Checked in a snapshot

* Updated snapshot

* Updated Cypress test

* Updated Cypress test

* Updated Cypress test

* Fixed review comments

* Fixed tests

* Added default collation for MySQL

* Added documentation for ensuring correct database collation

* Updated migrations

* Fixed a bug with collation

* Fixed lint errors

* Used correct collation

* debugging

* Updating css

* Minor UI changes

* USe inbuilt default collation

* Used only charset for mysql

* Fixed linter issue:

* Added migration for matching collation

* Reverted local config changes

* Reverted local config changes

* Handled the case of personal server running on MySQL

* WIP

* Now running collation matching migration onlyt for plugins

* Minor optimization

* Multiple review fixes

* Added group by clause to primary query

* Supported for subpacth

Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
This commit is contained in:
Harshil Sharma 2021-09-08 10:22:03 +05:30 committed by GitHub
parent de5f06c426
commit 08db4fed61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1493 additions and 696 deletions

View File

@ -2,7 +2,7 @@
"serverRoot": "http://localhost:8000",
"port": 8000,
"dbtype": "sqlite3",
"dbconfig": "./focalboard.db",
"dbconfig": "./focalboard.db",
"dbtableprefix": "",
"postgres_dbconfig": "dbname=focalboard sslmode=disable",
"test_dbconfig": "file::memory:?cache=shared",

View File

@ -118,7 +118,7 @@ func (p *Plugin) OnActivate() error {
AuthMode: "mattermost",
}
var db store.Store
db, err = sqlstore.New(cfg.DBType, cfg.DBConfigString, cfg.DBTablePrefix, logger, sqlDB)
db, err = sqlstore.New(cfg.DBType, cfg.DBConfigString, cfg.DBTablePrefix, logger, sqlDB, true)
if err != nil {
return fmt.Errorf("error initializing the DB: %w", err)
}

View File

@ -2,7 +2,7 @@
"serverRoot": "http://localhost:8000",
"port": 8000,
"dbtype": "sqlite3",
"dbconfig": "./focalboard.db",
"dbconfig": "./focalboard.db",
"postgres_dbconfig": "dbname=focalboard sslmode=disable",
"useSSL": false,
"webpath": "./pack",

View File

@ -94,6 +94,8 @@ func (a *API) RegisterRoutes(r *mux.Router) {
apiv1.HandleFunc("/workspaces/{workspaceID}/{rootID}/files", a.sessionRequired(a.handleUploadFile)).Methods("POST")
apiv1.HandleFunc("/workspaces", a.sessionRequired(a.handleGetUserWorkspaces)).Methods("GET")
// Get Files API
files := r.PathPrefix("/files").Subrouter()
@ -1460,3 +1462,21 @@ func jsonBytesResponse(w http.ResponseWriter, code int, json []byte) { //nolint:
w.WriteHeader(code)
_, _ = w.Write(json)
}
func (a *API) handleGetUserWorkspaces(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session := ctx.Value(sessionContextKey).(*model.Session)
userWorkspaces, err := a.app.GetUserWorkspaces(session.UserID)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
data, err := json.Marshal(userWorkspaces)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
jsonBytesResponse(w, http.StatusOK, data)
}

View File

@ -61,3 +61,7 @@ func (a *App) UpsertWorkspaceSignupToken(workspace model.Workspace) error {
func (a *App) GetWorkspaceCount() (int64, error) {
return a.store.GetWorkspaceCount()
}
func (a *App) GetUserWorkspaces(userID string) ([]model.UserWorkspace, error) {
return a.store.GetUserWorkspaces(userID)
}

View File

@ -27,3 +27,19 @@ type Workspace struct {
// required: true
UpdateAt int64 `json:"updateAt"`
}
// UserWorkspace is a summary of a single association between
// a user and a workspace
// swagger:model
type UserWorkspace struct {
// ID of the workspace
// required: true
ID string `json:"id"`
// Title of the workspace
// required: false
Title string `json:"title"`
// Number of boards in the workspace
BoardCount int `json:"boardCount"`
}

View File

@ -203,7 +203,7 @@ func NewStore(config *config.Configuration, logger *mlog.Logger) (store.Store, e
}
var db store.Store
db, err = sqlstore.New(config.DBType, config.DBConfigString, config.DBTablePrefix, logger, sqlDB)
db, err = sqlstore.New(config.DBType, config.DBConfigString, config.DBTablePrefix, logger, sqlDB, false)
if err != nil {
return nil, err
}

View File

@ -1,7 +1,7 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/mattermost/focalboard/server/services/store (interfaces: Store)
// Source: services/store/store.go
// Package mockstore is a generated GoMock package.
// Package mock_store is a generated GoMock package.
package mockstore
import (
@ -36,118 +36,118 @@ func (m *MockStore) EXPECT() *MockStoreMockRecorder {
}
// CleanUpSessions mocks base method.
func (m *MockStore) CleanUpSessions(arg0 int64) error {
func (m *MockStore) CleanUpSessions(expireTime int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CleanUpSessions", arg0)
ret := m.ctrl.Call(m, "CleanUpSessions", expireTime)
ret0, _ := ret[0].(error)
return ret0
}
// CleanUpSessions indicates an expected call of CleanUpSessions.
func (mr *MockStoreMockRecorder) CleanUpSessions(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) CleanUpSessions(expireTime interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanUpSessions", reflect.TypeOf((*MockStore)(nil).CleanUpSessions), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanUpSessions", reflect.TypeOf((*MockStore)(nil).CleanUpSessions), expireTime)
}
// CreateSession mocks base method.
func (m *MockStore) CreateSession(arg0 *model.Session) error {
func (m *MockStore) CreateSession(session *model.Session) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateSession", arg0)
ret := m.ctrl.Call(m, "CreateSession", session)
ret0, _ := ret[0].(error)
return ret0
}
// CreateSession indicates an expected call of CreateSession.
func (mr *MockStoreMockRecorder) CreateSession(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) CreateSession(session interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSession", reflect.TypeOf((*MockStore)(nil).CreateSession), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSession", reflect.TypeOf((*MockStore)(nil).CreateSession), session)
}
// CreateUser mocks base method.
func (m *MockStore) CreateUser(arg0 *model.User) error {
func (m *MockStore) CreateUser(user *model.User) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateUser", arg0)
ret := m.ctrl.Call(m, "CreateUser", user)
ret0, _ := ret[0].(error)
return ret0
}
// CreateUser indicates an expected call of CreateUser.
func (mr *MockStoreMockRecorder) CreateUser(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) CreateUser(user interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), user)
}
// DeleteBlock mocks base method.
func (m *MockStore) DeleteBlock(arg0 store.Container, arg1, arg2 string) error {
func (m *MockStore) DeleteBlock(c store.Container, blockID, modifiedBy string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteBlock", arg0, arg1, arg2)
ret := m.ctrl.Call(m, "DeleteBlock", c, blockID, modifiedBy)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteBlock indicates an expected call of DeleteBlock.
func (mr *MockStoreMockRecorder) DeleteBlock(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) DeleteBlock(c, blockID, modifiedBy interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlock", reflect.TypeOf((*MockStore)(nil).DeleteBlock), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlock", reflect.TypeOf((*MockStore)(nil).DeleteBlock), c, blockID, modifiedBy)
}
// DeleteSession mocks base method.
func (m *MockStore) DeleteSession(arg0 string) error {
func (m *MockStore) DeleteSession(sessionID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteSession", arg0)
ret := m.ctrl.Call(m, "DeleteSession", sessionID)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteSession indicates an expected call of DeleteSession.
func (mr *MockStoreMockRecorder) DeleteSession(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) DeleteSession(sessionID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSession", reflect.TypeOf((*MockStore)(nil).DeleteSession), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSession", reflect.TypeOf((*MockStore)(nil).DeleteSession), sessionID)
}
// GetActiveUserCount mocks base method.
func (m *MockStore) GetActiveUserCount(arg0 int64) (int, error) {
func (m *MockStore) GetActiveUserCount(updatedSecondsAgo int64) (int, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetActiveUserCount", arg0)
ret := m.ctrl.Call(m, "GetActiveUserCount", updatedSecondsAgo)
ret0, _ := ret[0].(int)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetActiveUserCount indicates an expected call of GetActiveUserCount.
func (mr *MockStoreMockRecorder) GetActiveUserCount(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetActiveUserCount(updatedSecondsAgo interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), updatedSecondsAgo)
}
// GetAllBlocks mocks base method.
func (m *MockStore) GetAllBlocks(arg0 store.Container) ([]model.Block, error) {
func (m *MockStore) GetAllBlocks(c store.Container) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllBlocks", arg0)
ret := m.ctrl.Call(m, "GetAllBlocks", c)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllBlocks indicates an expected call of GetAllBlocks.
func (mr *MockStoreMockRecorder) GetAllBlocks(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetAllBlocks(c interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBlocks", reflect.TypeOf((*MockStore)(nil).GetAllBlocks), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBlocks", reflect.TypeOf((*MockStore)(nil).GetAllBlocks), c)
}
// GetBlock mocks base method.
func (m *MockStore) GetBlock(arg0 store.Container, arg1 string) (*model.Block, error) {
func (m *MockStore) GetBlock(c store.Container, blockID string) (*model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlock", arg0, arg1)
ret := m.ctrl.Call(m, "GetBlock", c, blockID)
ret0, _ := ret[0].(*model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlock indicates an expected call of GetBlock.
func (mr *MockStoreMockRecorder) GetBlock(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetBlock(c, blockID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockStore)(nil).GetBlock), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockStore)(nil).GetBlock), c, blockID)
}
// GetBlockCountsByType mocks base method.
@ -166,78 +166,78 @@ func (mr *MockStoreMockRecorder) GetBlockCountsByType() *gomock.Call {
}
// GetBlocksWithParent mocks base method.
func (m *MockStore) GetBlocksWithParent(arg0 store.Container, arg1 string) ([]model.Block, error) {
func (m *MockStore) GetBlocksWithParent(c store.Container, parentID string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlocksWithParent", arg0, arg1)
ret := m.ctrl.Call(m, "GetBlocksWithParent", c, parentID)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlocksWithParent indicates an expected call of GetBlocksWithParent.
func (mr *MockStoreMockRecorder) GetBlocksWithParent(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetBlocksWithParent(c, parentID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParent", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParent), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParent", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParent), c, parentID)
}
// GetBlocksWithParentAndType mocks base method.
func (m *MockStore) GetBlocksWithParentAndType(arg0 store.Container, arg1, arg2 string) ([]model.Block, error) {
func (m *MockStore) GetBlocksWithParentAndType(c store.Container, parentID, blockType string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlocksWithParentAndType", arg0, arg1, arg2)
ret := m.ctrl.Call(m, "GetBlocksWithParentAndType", c, parentID, blockType)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlocksWithParentAndType indicates an expected call of GetBlocksWithParentAndType.
func (mr *MockStoreMockRecorder) GetBlocksWithParentAndType(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetBlocksWithParentAndType(c, parentID, blockType interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParentAndType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParentAndType), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParentAndType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParentAndType), c, parentID, blockType)
}
// GetBlocksWithRootID mocks base method.
func (m *MockStore) GetBlocksWithRootID(arg0 store.Container, arg1 string) ([]model.Block, error) {
func (m *MockStore) GetBlocksWithRootID(c store.Container, rootID string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlocksWithRootID", arg0, arg1)
ret := m.ctrl.Call(m, "GetBlocksWithRootID", c, rootID)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlocksWithRootID indicates an expected call of GetBlocksWithRootID.
func (mr *MockStoreMockRecorder) GetBlocksWithRootID(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetBlocksWithRootID(c, rootID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithRootID", reflect.TypeOf((*MockStore)(nil).GetBlocksWithRootID), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithRootID", reflect.TypeOf((*MockStore)(nil).GetBlocksWithRootID), c, rootID)
}
// GetBlocksWithType mocks base method.
func (m *MockStore) GetBlocksWithType(arg0 store.Container, arg1 string) ([]model.Block, error) {
func (m *MockStore) GetBlocksWithType(c store.Container, blockType string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlocksWithType", arg0, arg1)
ret := m.ctrl.Call(m, "GetBlocksWithType", c, blockType)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlocksWithType indicates an expected call of GetBlocksWithType.
func (mr *MockStoreMockRecorder) GetBlocksWithType(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetBlocksWithType(c, blockType interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithType), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithType), c, blockType)
}
// GetParentID mocks base method.
func (m *MockStore) GetParentID(arg0 store.Container, arg1 string) (string, error) {
func (m *MockStore) GetParentID(c store.Container, blockID string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetParentID", arg0, arg1)
ret := m.ctrl.Call(m, "GetParentID", c, blockID)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetParentID indicates an expected call of GetParentID.
func (mr *MockStoreMockRecorder) GetParentID(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetParentID(c, blockID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParentID", reflect.TypeOf((*MockStore)(nil).GetParentID), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParentID", reflect.TypeOf((*MockStore)(nil).GetParentID), c, blockID)
}
// GetRegisteredUserCount mocks base method.
@ -256,78 +256,78 @@ func (mr *MockStoreMockRecorder) GetRegisteredUserCount() *gomock.Call {
}
// GetRootID mocks base method.
func (m *MockStore) GetRootID(arg0 store.Container, arg1 string) (string, error) {
func (m *MockStore) GetRootID(c store.Container, blockID string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetRootID", arg0, arg1)
ret := m.ctrl.Call(m, "GetRootID", c, blockID)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetRootID indicates an expected call of GetRootID.
func (mr *MockStoreMockRecorder) GetRootID(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetRootID(c, blockID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRootID", reflect.TypeOf((*MockStore)(nil).GetRootID), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRootID", reflect.TypeOf((*MockStore)(nil).GetRootID), c, blockID)
}
// GetSession mocks base method.
func (m *MockStore) GetSession(arg0 string, arg1 int64) (*model.Session, error) {
func (m *MockStore) GetSession(token string, expireTime int64) (*model.Session, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSession", arg0, arg1)
ret := m.ctrl.Call(m, "GetSession", token, expireTime)
ret0, _ := ret[0].(*model.Session)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSession indicates an expected call of GetSession.
func (mr *MockStoreMockRecorder) GetSession(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetSession(token, expireTime interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSession", reflect.TypeOf((*MockStore)(nil).GetSession), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSession", reflect.TypeOf((*MockStore)(nil).GetSession), token, expireTime)
}
// GetSharing mocks base method.
func (m *MockStore) GetSharing(arg0 store.Container, arg1 string) (*model.Sharing, error) {
func (m *MockStore) GetSharing(c store.Container, rootID string) (*model.Sharing, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSharing", arg0, arg1)
ret := m.ctrl.Call(m, "GetSharing", c, rootID)
ret0, _ := ret[0].(*model.Sharing)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSharing indicates an expected call of GetSharing.
func (mr *MockStoreMockRecorder) GetSharing(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetSharing(c, rootID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSharing", reflect.TypeOf((*MockStore)(nil).GetSharing), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSharing", reflect.TypeOf((*MockStore)(nil).GetSharing), c, rootID)
}
// GetSubTree2 mocks base method.
func (m *MockStore) GetSubTree2(arg0 store.Container, arg1 string) ([]model.Block, error) {
func (m *MockStore) GetSubTree2(c store.Container, blockID string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSubTree2", arg0, arg1)
ret := m.ctrl.Call(m, "GetSubTree2", c, blockID)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSubTree2 indicates an expected call of GetSubTree2.
func (mr *MockStoreMockRecorder) GetSubTree2(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetSubTree2(c, blockID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree2", reflect.TypeOf((*MockStore)(nil).GetSubTree2), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree2", reflect.TypeOf((*MockStore)(nil).GetSubTree2), c, blockID)
}
// GetSubTree3 mocks base method.
func (m *MockStore) GetSubTree3(arg0 store.Container, arg1 string) ([]model.Block, error) {
func (m *MockStore) GetSubTree3(c store.Container, blockID string) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSubTree3", arg0, arg1)
ret := m.ctrl.Call(m, "GetSubTree3", c, blockID)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSubTree3 indicates an expected call of GetSubTree3.
func (mr *MockStoreMockRecorder) GetSubTree3(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetSubTree3(c, blockID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree3", reflect.TypeOf((*MockStore)(nil).GetSubTree3), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree3", reflect.TypeOf((*MockStore)(nil).GetSubTree3), c, blockID)
}
// GetSystemSettings mocks base method.
@ -346,78 +346,93 @@ func (mr *MockStoreMockRecorder) GetSystemSettings() *gomock.Call {
}
// GetUserByEmail mocks base method.
func (m *MockStore) GetUserByEmail(arg0 string) (*model.User, error) {
func (m *MockStore) GetUserByEmail(email string) (*model.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByEmail", arg0)
ret := m.ctrl.Call(m, "GetUserByEmail", email)
ret0, _ := ret[0].(*model.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByEmail indicates an expected call of GetUserByEmail.
func (mr *MockStoreMockRecorder) GetUserByEmail(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetUserByEmail(email interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockStore)(nil).GetUserByEmail), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockStore)(nil).GetUserByEmail), email)
}
// GetUserByID mocks base method.
func (m *MockStore) GetUserByID(arg0 string) (*model.User, error) {
func (m *MockStore) GetUserByID(userID string) (*model.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByID", arg0)
ret := m.ctrl.Call(m, "GetUserByID", userID)
ret0, _ := ret[0].(*model.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByID indicates an expected call of GetUserByID.
func (mr *MockStoreMockRecorder) GetUserByID(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetUserByID(userID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockStore)(nil).GetUserByID), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockStore)(nil).GetUserByID), userID)
}
// GetUserByUsername mocks base method.
func (m *MockStore) GetUserByUsername(arg0 string) (*model.User, error) {
func (m *MockStore) GetUserByUsername(username string) (*model.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByUsername", arg0)
ret := m.ctrl.Call(m, "GetUserByUsername", username)
ret0, _ := ret[0].(*model.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByUsername indicates an expected call of GetUserByUsername.
func (mr *MockStoreMockRecorder) GetUserByUsername(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetUserByUsername(username interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByUsername", reflect.TypeOf((*MockStore)(nil).GetUserByUsername), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByUsername", reflect.TypeOf((*MockStore)(nil).GetUserByUsername), username)
}
// GetUserWorkspaces mocks base method.
func (m *MockStore) GetUserWorkspaces(userID string) ([]model.UserWorkspace, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserWorkspaces", userID)
ret0, _ := ret[0].([]model.UserWorkspace)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserWorkspaces indicates an expected call of GetUserWorkspaces.
func (mr *MockStoreMockRecorder) GetUserWorkspaces(userID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserWorkspaces", reflect.TypeOf((*MockStore)(nil).GetUserWorkspaces), userID)
}
// GetUsersByWorkspace mocks base method.
func (m *MockStore) GetUsersByWorkspace(arg0 string) ([]*model.User, error) {
func (m *MockStore) GetUsersByWorkspace(workspaceID string) ([]*model.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUsersByWorkspace", arg0)
ret := m.ctrl.Call(m, "GetUsersByWorkspace", workspaceID)
ret0, _ := ret[0].([]*model.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUsersByWorkspace indicates an expected call of GetUsersByWorkspace.
func (mr *MockStoreMockRecorder) GetUsersByWorkspace(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetUsersByWorkspace(workspaceID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUsersByWorkspace", reflect.TypeOf((*MockStore)(nil).GetUsersByWorkspace), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUsersByWorkspace", reflect.TypeOf((*MockStore)(nil).GetUsersByWorkspace), workspaceID)
}
// GetWorkspace mocks base method.
func (m *MockStore) GetWorkspace(arg0 string) (*model.Workspace, error) {
func (m *MockStore) GetWorkspace(ID string) (*model.Workspace, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetWorkspace", arg0)
ret := m.ctrl.Call(m, "GetWorkspace", ID)
ret0, _ := ret[0].(*model.Workspace)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetWorkspace indicates an expected call of GetWorkspace.
func (mr *MockStoreMockRecorder) GetWorkspace(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetWorkspace(ID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspace", reflect.TypeOf((*MockStore)(nil).GetWorkspace), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspace", reflect.TypeOf((*MockStore)(nil).GetWorkspace), ID)
}
// GetWorkspaceCount mocks base method.
@ -436,74 +451,74 @@ func (mr *MockStoreMockRecorder) GetWorkspaceCount() *gomock.Call {
}
// HasWorkspaceAccess mocks base method.
func (m *MockStore) HasWorkspaceAccess(arg0, arg1 string) (bool, error) {
func (m *MockStore) HasWorkspaceAccess(userID, workspaceID string) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HasWorkspaceAccess", arg0, arg1)
ret := m.ctrl.Call(m, "HasWorkspaceAccess", userID, workspaceID)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HasWorkspaceAccess indicates an expected call of HasWorkspaceAccess.
func (mr *MockStoreMockRecorder) HasWorkspaceAccess(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) HasWorkspaceAccess(userID, workspaceID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasWorkspaceAccess", reflect.TypeOf((*MockStore)(nil).HasWorkspaceAccess), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasWorkspaceAccess", reflect.TypeOf((*MockStore)(nil).HasWorkspaceAccess), userID, workspaceID)
}
// InsertBlock mocks base method.
func (m *MockStore) InsertBlock(arg0 store.Container, arg1 *model.Block, arg2 string) error {
func (m *MockStore) InsertBlock(c store.Container, block *model.Block, userID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertBlock", arg0, arg1, arg2)
ret := m.ctrl.Call(m, "InsertBlock", c, block, userID)
ret0, _ := ret[0].(error)
return ret0
}
// InsertBlock indicates an expected call of InsertBlock.
func (mr *MockStoreMockRecorder) InsertBlock(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) InsertBlock(c, block, userID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockStore)(nil).InsertBlock), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockStore)(nil).InsertBlock), c, block, userID)
}
// PatchBlock mocks base method.
func (m *MockStore) PatchBlock(arg0 store.Container, arg1 string, arg2 *model.BlockPatch, arg3 string) error {
func (m *MockStore) PatchBlock(c store.Container, blockID string, blockPatch *model.BlockPatch, userID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PatchBlock", arg0, arg1, arg2, arg3)
ret := m.ctrl.Call(m, "PatchBlock", c, blockID, blockPatch, userID)
ret0, _ := ret[0].(error)
return ret0
}
// PatchBlock indicates an expected call of PatchBlock.
func (mr *MockStoreMockRecorder) PatchBlock(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) PatchBlock(c, blockID, blockPatch, userID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchBlock", reflect.TypeOf((*MockStore)(nil).PatchBlock), arg0, arg1, arg2, arg3)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchBlock", reflect.TypeOf((*MockStore)(nil).PatchBlock), c, blockID, blockPatch, userID)
}
// RefreshSession mocks base method.
func (m *MockStore) RefreshSession(arg0 *model.Session) error {
func (m *MockStore) RefreshSession(session *model.Session) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RefreshSession", arg0)
ret := m.ctrl.Call(m, "RefreshSession", session)
ret0, _ := ret[0].(error)
return ret0
}
// RefreshSession indicates an expected call of RefreshSession.
func (mr *MockStoreMockRecorder) RefreshSession(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) RefreshSession(session interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshSession", reflect.TypeOf((*MockStore)(nil).RefreshSession), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshSession", reflect.TypeOf((*MockStore)(nil).RefreshSession), session)
}
// SetSystemSetting mocks base method.
func (m *MockStore) SetSystemSetting(arg0, arg1 string) error {
func (m *MockStore) SetSystemSetting(key, value string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetSystemSetting", arg0, arg1)
ret := m.ctrl.Call(m, "SetSystemSetting", key, value)
ret0, _ := ret[0].(error)
return ret0
}
// SetSystemSetting indicates an expected call of SetSystemSetting.
func (mr *MockStoreMockRecorder) SetSystemSetting(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) SetSystemSetting(key, value interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSystemSetting", reflect.TypeOf((*MockStore)(nil).SetSystemSetting), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSystemSetting", reflect.TypeOf((*MockStore)(nil).SetSystemSetting), key, value)
}
// Shutdown mocks base method.
@ -521,99 +536,99 @@ func (mr *MockStoreMockRecorder) Shutdown() *gomock.Call {
}
// UpdateSession mocks base method.
func (m *MockStore) UpdateSession(arg0 *model.Session) error {
func (m *MockStore) UpdateSession(session *model.Session) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateSession", arg0)
ret := m.ctrl.Call(m, "UpdateSession", session)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateSession indicates an expected call of UpdateSession.
func (mr *MockStoreMockRecorder) UpdateSession(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpdateSession(session interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSession", reflect.TypeOf((*MockStore)(nil).UpdateSession), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSession", reflect.TypeOf((*MockStore)(nil).UpdateSession), session)
}
// UpdateUser mocks base method.
func (m *MockStore) UpdateUser(arg0 *model.User) error {
func (m *MockStore) UpdateUser(user *model.User) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateUser", arg0)
ret := m.ctrl.Call(m, "UpdateUser", user)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateUser indicates an expected call of UpdateUser.
func (mr *MockStoreMockRecorder) UpdateUser(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpdateUser(user interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockStore)(nil).UpdateUser), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockStore)(nil).UpdateUser), user)
}
// UpdateUserPassword mocks base method.
func (m *MockStore) UpdateUserPassword(arg0, arg1 string) error {
func (m *MockStore) UpdateUserPassword(username, password string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateUserPassword", arg0, arg1)
ret := m.ctrl.Call(m, "UpdateUserPassword", username, password)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateUserPassword indicates an expected call of UpdateUserPassword.
func (mr *MockStoreMockRecorder) UpdateUserPassword(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpdateUserPassword(username, password interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPassword", reflect.TypeOf((*MockStore)(nil).UpdateUserPassword), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPassword", reflect.TypeOf((*MockStore)(nil).UpdateUserPassword), username, password)
}
// UpdateUserPasswordByID mocks base method.
func (m *MockStore) UpdateUserPasswordByID(arg0, arg1 string) error {
func (m *MockStore) UpdateUserPasswordByID(userID, password string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateUserPasswordByID", arg0, arg1)
ret := m.ctrl.Call(m, "UpdateUserPasswordByID", userID, password)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateUserPasswordByID indicates an expected call of UpdateUserPasswordByID.
func (mr *MockStoreMockRecorder) UpdateUserPasswordByID(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpdateUserPasswordByID(userID, password interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPasswordByID", reflect.TypeOf((*MockStore)(nil).UpdateUserPasswordByID), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPasswordByID", reflect.TypeOf((*MockStore)(nil).UpdateUserPasswordByID), userID, password)
}
// UpsertSharing mocks base method.
func (m *MockStore) UpsertSharing(arg0 store.Container, arg1 model.Sharing) error {
func (m *MockStore) UpsertSharing(c store.Container, sharing model.Sharing) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpsertSharing", arg0, arg1)
ret := m.ctrl.Call(m, "UpsertSharing", c, sharing)
ret0, _ := ret[0].(error)
return ret0
}
// UpsertSharing indicates an expected call of UpsertSharing.
func (mr *MockStoreMockRecorder) UpsertSharing(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpsertSharing(c, sharing interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertSharing", reflect.TypeOf((*MockStore)(nil).UpsertSharing), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertSharing", reflect.TypeOf((*MockStore)(nil).UpsertSharing), c, sharing)
}
// UpsertWorkspaceSettings mocks base method.
func (m *MockStore) UpsertWorkspaceSettings(arg0 model.Workspace) error {
func (m *MockStore) UpsertWorkspaceSettings(workspace model.Workspace) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpsertWorkspaceSettings", arg0)
ret := m.ctrl.Call(m, "UpsertWorkspaceSettings", workspace)
ret0, _ := ret[0].(error)
return ret0
}
// UpsertWorkspaceSettings indicates an expected call of UpsertWorkspaceSettings.
func (mr *MockStoreMockRecorder) UpsertWorkspaceSettings(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpsertWorkspaceSettings(workspace interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSettings", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSettings), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSettings", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSettings), workspace)
}
// UpsertWorkspaceSignupToken mocks base method.
func (m *MockStore) UpsertWorkspaceSignupToken(arg0 model.Workspace) error {
func (m *MockStore) UpsertWorkspaceSignupToken(workspace model.Workspace) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpsertWorkspaceSignupToken", arg0)
ret := m.ctrl.Call(m, "UpsertWorkspaceSignupToken", workspace)
ret0, _ := ret[0].(error)
return ret0
}
// UpsertWorkspaceSignupToken indicates an expected call of UpsertWorkspaceSignupToken.
func (mr *MockStoreMockRecorder) UpsertWorkspaceSignupToken(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) UpsertWorkspaceSignupToken(workspace interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSignupToken", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSignupToken), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSignupToken", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSignupToken), workspace)
}

View File

@ -29,6 +29,7 @@ type PrefixedMigration struct {
postgres bool
sqlite bool
mysql bool
plugin bool
}
func init() {
@ -45,10 +46,22 @@ func (pm *PrefixedMigration) executeTemplate(r io.ReadCloser, identifier string)
return nil, "", err
}
buffer := bytes.NewBufferString("")
err = tmpl.Execute(buffer, map[string]interface{}{"prefix": pm.prefix, "postgres": pm.postgres, "sqlite": pm.sqlite, "mysql": pm.mysql})
params := map[string]interface{}{
"prefix": pm.prefix,
"postgres": pm.postgres,
"sqlite": pm.sqlite,
"mysql": pm.mysql,
"plugin": pm.plugin,
}
err = tmpl.Execute(buffer, params)
if err != nil {
return nil, "", err
}
if identifier == "match_collation" {
fmt.Println(buffer.String())
}
return ioutil.NopCloser(bytes.NewReader(buffer.Bytes())), identifier, nil
}
@ -145,9 +158,11 @@ func (s *SQLStore) Migrate() error {
if err != nil {
return err
}
prefixedData := &PrefixedMigration{
Bindata: d.(*bindata.Bindata),
prefix: s.tablePrefix,
plugin: s.isPlugin,
postgres: s.dbType == postgresDBType,
sqlite: s.dbType == sqliteDBType,
mysql: s.dbType == mysqlDBType,

View File

@ -1,25 +1,3 @@
// Code generated for package migrations by go-bindata DO NOT EDIT. (@generated)
// sources:
// migrations_files/000001_init.down.sql
// migrations_files/000001_init.up.sql
// migrations_files/000002_system_settings_table.down.sql
// migrations_files/000002_system_settings_table.up.sql
// migrations_files/000003_blocks_rootid.down.sql
// migrations_files/000003_blocks_rootid.up.sql
// migrations_files/000004_auth_table.down.sql
// migrations_files/000004_auth_table.up.sql
// migrations_files/000005_blocks_modifiedby.down.sql
// migrations_files/000005_blocks_modifiedby.up.sql
// migrations_files/000006_sharing_table.down.sql
// migrations_files/000006_sharing_table.up.sql
// migrations_files/000007_workspaces_table.down.sql
// migrations_files/000007_workspaces_table.up.sql
// migrations_files/000008_teams.down.sql
// migrations_files/000008_teams.up.sql
// migrations_files/000009_blocks_history.down.sql
// migrations_files/000009_blocks_history.up.sql
// migrations_files/000010_blocks_created_by.down.sql
// migrations_files/000010_blocks_created_by.up.sql
package migrations
import (
@ -27,14 +5,10 @@ import (
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)
func bindataRead(data []byte, name string) ([]byte, error) {
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
@ -42,458 +16,211 @@ func bindataRead(data []byte, name string) ([]byte, error) {
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
clErr := gz.Close()
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
if clErr != nil {
return nil, err
}
return buf.Bytes(), nil
}
type asset struct {
bytes []byte
info os.FileInfo
}
var __000001_init_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x2d\x73\xd0\xe1\x1e\x00\x00\x00")
type bindataFileInfo struct {
name string
size int64
mode os.FileMode
modTime time.Time
}
// Name return file name
func (fi bindataFileInfo) Name() string {
return fi.name
}
// Size return file size
func (fi bindataFileInfo) Size() int64 {
return fi.size
}
// Mode return file mode
func (fi bindataFileInfo) Mode() os.FileMode {
return fi.mode
}
// Mode return file modify time
func (fi bindataFileInfo) ModTime() time.Time {
return fi.modTime
}
// IsDir return file whether a directory
func (fi bindataFileInfo) IsDir() bool {
return fi.mode&os.ModeDir != 0
}
// Sys return file is sys mode
func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var __000001_initDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x2d\x73\xd0\xe1\x1e\x00\x00\x00")
func _000001_initDownSqlBytes() ([]byte, error) {
return bindataRead(
__000001_initDownSql,
func _000001_init_down_sql() ([]byte, error) {
return bindata_read(
__000001_init_down_sql,
"000001_init.down.sql",
)
}
func _000001_initDownSql() (*asset, error) {
bytes, err := _000001_initDownSqlBytes()
if err != nil {
return nil, err
}
var __000001_init_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xd0\x5d\x6f\xb2\x30\x14\x07\xf0\x6b\xf8\x14\xe7\x86\x00\x09\x7a\xf3\x3c\x31\x8b\xbb\xaa\x5a\x27\x1b\x2f\x06\xea\xd4\xdd\x28\x4a\xd9\x9a\x81\x22\xad\xc9\x4c\xd3\xef\xbe\xe0\xd0\x38\x75\x77\x3d\xa7\xcd\xaf\xe7\xfc\xfb\x11\x46\x04\x03\x41\x3d\x0f\x83\x3b\x84\x20\x24\x80\x67\x6e\x4c\x62\x90\xb2\x5d\x56\x34\x63\x5f\x4a\xad\xf2\xed\xfa\x93\x83\xa5\x6b\x2c\x85\x57\x14\xf5\x47\x28\xb2\xfe\x75\x6c\x47\xd7\xa4\x64\x19\xb4\xcb\x2d\x17\xef\x15\xe5\x4a\xb1\x0d\xa7\x95\x58\x24\x02\x88\xeb\xe3\x98\x20\x7f\x4c\xde\x8e\x6c\x30\xf1\x3c\x18\xe0\x21\x9a\x78\x04\x82\x70\x6a\xd9\x8e\x94\x74\x93\x2a\x75\x52\xf8\x2e\x67\x82\x5e\x1a\x03\x44\x70\xed\xdc\x00\x56\x4c\xa2\x61\x7d\x63\x99\xc6\xbc\x65\x14\x2d\x23\x05\x63\xd4\x35\xfc\xae\x91\x99\x0e\x98\x41\x38\x35\xed\x9b\x0f\x8a\x03\xdf\xe5\xf7\x7c\xab\x63\xdf\x9f\xb1\x73\x61\x94\x49\x45\x37\x62\xf1\x47\x04\x8d\xbd\xe4\xeb\x0f\x5a\x24\x4b\x29\x69\xce\xa9\x52\x3f\x65\x63\x40\xcf\x7d\x72\x03\xe2\xe8\x9a\x38\x94\x14\x08\x9e\x1d\xcf\x4c\xe4\xe7\x22\x63\x34\x4f\x39\x5c\xc7\xfa\x1c\x87\xc1\x89\xac\x5f\x36\xa0\xa3\x6b\xeb\x8a\x26\x82\xd6\xcb\x9c\xf1\x7d\x99\x5e\xb7\x52\x9a\xd3\xab\xd6\x38\x72\x7d\x14\xcd\xe1\x05\xcf\xc1\x62\xa9\x03\xe7\x58\x6c\xdd\x86\x5f\x4b\x9d\x12\xa9\x97\x46\x7d\x82\x23\x88\x31\x81\xbd\xc8\x1e\x8a\xd5\xff\x66\x94\x47\xfd\x3b\x00\x00\xff\xff\x60\xc4\xab\x56\x4c\x02\x00\x00")
info := bindataFileInfo{name: "000001_init.down.sql", size: 30, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000001_initUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xd2\xcf\x6f\x9b\x30\x14\x07\xf0\x33\xfc\x15\xef\x82\x00\x89\xf6\xb2\x29\x9a\xba\x93\x4b\x9d\x95\x8d\x1f\x15\xb8\x6b\xb3\x0b\xa5\xf8\xb1\x59\x03\x42\xb1\x23\x2d\xb2\xfc\xbf\x4f\x64\x24\xca\x92\xf4\xc6\x7b\x58\x1f\xbf\xf7\x95\xc3\x9c\x12\x46\x81\x91\xdb\x98\x42\xb4\x84\x34\x63\x40\x9f\xa3\x82\x15\xa0\xf5\xf5\x30\x62\x23\xfe\x18\xf3\xda\xae\xeb\xdf\x12\x3c\xdb\x12\x1c\xbe\x93\x3c\xbc\x27\xb9\xf7\x61\xe1\x07\xb6\xa5\xb5\x68\xe0\x7a\x58\x4b\xf5\x73\x44\x69\x8c\xe8\x25\x8e\xaa\xac\x14\xb0\x28\xa1\x05\x23\xc9\x03\xfb\xb1\x63\xd3\xc7\x38\x86\x3b\xba\x24\x8f\x31\x83\x34\x7b\xf2\xfc\x40\x6b\xec\xb9\x31\x7b\x45\xbe\xb5\x42\xe1\xb1\x71\x47\x18\x9d\x9c\x33\xc0\x2b\x58\xbe\x9c\xfe\x78\xae\xb3\xba\x72\xba\x2b\x87\x83\x73\x7f\xe3\x24\x37\x4e\xe3\x06\xe0\xa6\xd9\x93\xeb\x9f\x5d\xd0\x6d\xe5\x5b\x7b\xc9\xf7\x16\xfe\xe5\x19\x17\x47\xc6\x50\x8d\xd8\xab\xf2\x9d\x08\x66\xfb\x45\xd6\xbf\xb0\xab\x5e\xb4\xc6\x56\xa2\x31\xff\xca\xd9\x80\xdb\xe8\x4b\x94\xb2\xc0\xb6\xd4\x76\x40\x60\xf4\x79\xf7\x2d\x54\x7b\x28\x1a\x81\x2d\x97\x70\x1a\xeb\xd7\x22\x4b\xf7\xe4\x74\x72\x06\x03\xdb\xaa\x47\xac\x14\x4e\xcb\x1c\xf0\xcd\xc0\x4f\x5b\x1c\x5b\x3c\x69\x3d\xe4\x51\x42\xf2\x15\x7c\xa3\x2b\xf0\x04\x0f\xe0\x10\x8b\x6f\xfb\xff\xed\x34\xed\x4a\x42\x46\x73\x28\x28\x83\x8d\x6a\x3e\x75\xaf\x1f\x21\xcc\xe2\x78\x7a\x3b\x73\x5d\x6e\x7a\x51\xaf\x39\x96\xb5\x98\x87\xfb\x6c\xff\x0d\x00\x00\xff\xff\x89\x6c\x55\x1c\x5e\x02\x00\x00")
func _000001_initUpSqlBytes() ([]byte, error) {
return bindataRead(
__000001_initUpSql,
func _000001_init_up_sql() ([]byte, error) {
return bindata_read(
__000001_init_up_sql,
"000001_init.up.sql",
)
}
func _000001_initUpSql() (*asset, error) {
bytes, err := _000001_initUpSqlBytes()
if err != nil {
return nil, err
}
var __000002_system_settings_table_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\xd2\x63\x5d\x39\x27\x00\x00\x00")
info := bindataFileInfo{name: "000001_init.up.sql", size: 606, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000002_system_settings_tableDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\xd2\x63\x5d\x39\x27\x00\x00\x00")
func _000002_system_settings_tableDownSqlBytes() ([]byte, error) {
return bindataRead(
__000002_system_settings_tableDownSql,
func _000002_system_settings_table_down_sql() ([]byte, error) {
return bindata_read(
__000002_system_settings_table_down_sql,
"000002_system_settings_table.down.sql",
)
}
func _000002_system_settings_tableDownSql() (*asset, error) {
bytes, err := _000002_system_settings_tableDownSqlBytes()
if err != nil {
return nil, err
}
var __000002_system_settings_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x14\xcc\xc1\x6a\x83\x30\x18\x07\xf0\xb3\x79\x8a\xff\x51\x41\xc4\xc1\x0e\x83\x9d\x32\xf7\xc9\x64\x6e\x2d\xf1\x6b\xd1\x53\x69\x31\x96\x80\x4a\xdb\xc4\x52\x09\x79\xf7\xd2\x17\xf8\x15\x8a\x24\x13\x58\x7e\xd5\x84\xaa\xc4\xff\x86\x41\x6d\xd5\x70\x03\xef\xb3\xcb\x4d\x0f\xe6\x11\x82\x5d\xad\xd3\xd3\xc1\x6a\xe7\xcc\x7c\xb6\x88\x45\x64\x7a\xec\xa5\x2a\x7e\xa4\x8a\xdf\xf2\x3c\x49\x45\x74\x3f\x8e\x8b\x06\x53\xcb\xa9\x88\xb6\xaa\xfa\x93\xaa\xc3\x2f\x75\x88\x4d\x9f\x88\x04\xde\x9b\x01\xd9\xb4\xda\xeb\x18\xc2\x37\x95\x72\x57\x33\x5e\x80\x2c\x98\x14\x1a\x62\x2c\x6e\xf8\x98\x4e\xef\xde\xeb\xb9\x0f\xe1\x53\x3c\x03\x00\x00\xff\xff\x3e\xa0\x26\x35\x9e\x00\x00\x00")
info := bindataFileInfo{name: "000002_system_settings_table.down.sql", size: 39, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000002_system_settings_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xce\x4f\x6b\x83\x30\x18\x80\xf1\xb3\xf9\x14\xef\x51\x41\xc4\xc1\x0e\x83\x9d\xb2\xf0\x8e\xc9\xdc\x2c\xf1\xa5\xe8\x49\x5a\x13\x4b\x40\xed\x9f\xc4\x52\x09\xf9\xee\x45\xe8\xf1\x39\x3c\xf0\x13\x12\x39\x21\x10\xff\x2a\x11\x8a\x6f\xf8\xaf\x08\xb0\x29\x6a\xaa\xc1\xfb\xec\x72\xd3\x83\x79\x84\x60\x57\xeb\xf4\xd4\x59\xed\x9c\x99\x4f\x16\x62\x16\x19\x05\x7b\x2e\xc5\x0f\x97\xf1\x5b\x9e\x27\x29\x8b\xee\x87\x71\xd1\x40\xd8\x50\xca\xa2\x9d\x2c\xfe\xb8\x6c\xe1\x17\x5b\x88\x8d\x4a\x58\xe2\xbd\x19\x20\x9b\x56\x7b\x1d\x43\xd8\x3e\x2e\x08\x25\xd4\x48\xb0\xb8\xe1\x63\x3a\xbe\x83\xa8\xca\x72\xd3\xbc\xba\x5b\x66\xd3\x9f\x95\xee\x7a\xe3\xbd\x9e\x55\x08\x9f\xec\x19\x00\x00\xff\xff\x8e\xa2\x4f\x97\xb0\x00\x00\x00")
func _000002_system_settings_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__000002_system_settings_tableUpSql,
func _000002_system_settings_table_up_sql() ([]byte, error) {
return bindata_read(
__000002_system_settings_table_up_sql,
"000002_system_settings_table.up.sql",
)
}
func _000002_system_settings_tableUpSql() (*asset, error) {
bytes, err := _000002_system_settings_tableUpSqlBytes()
if err != nil {
return nil, err
}
var __000003_blocks_rootid_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xca\xcf\x2f\x89\xcf\x4c\xb1\xe6\x02\x04\x00\x00\xff\xff\x51\xe5\xe2\x3a\x33\x00\x00\x00")
info := bindataFileInfo{name: "000002_system_settings_table.up.sql", size: 176, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000003_blocks_rootidDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xca\xcf\x2f\x89\xcf\x4c\xb1\xe6\x02\x04\x00\x00\xff\xff\x51\xe5\xe2\x3a\x33\x00\x00\x00")
func _000003_blocks_rootidDownSqlBytes() ([]byte, error) {
return bindataRead(
__000003_blocks_rootidDownSql,
func _000003_blocks_rootid_down_sql() ([]byte, error) {
return bindata_read(
__000003_blocks_rootid_down_sql,
"000003_blocks_rootid.down.sql",
)
}
func _000003_blocks_rootidDownSql() (*asset, error) {
bytes, err := _000003_blocks_rootidDownSqlBytes()
if err != nil {
return nil, err
}
var __000003_blocks_rootid_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xca\xcf\x2f\x89\xcf\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\x02\x04\x00\x00\xff\xff\xc2\x68\x66\x83\x3e\x00\x00\x00")
info := bindataFileInfo{name: "000003_blocks_rootid.down.sql", size: 51, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000003_blocks_rootidUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xca\xcf\x2f\x89\xcf\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\x02\x04\x00\x00\xff\xff\xc2\x68\x66\x83\x3e\x00\x00\x00")
func _000003_blocks_rootidUpSqlBytes() ([]byte, error) {
return bindataRead(
__000003_blocks_rootidUpSql,
func _000003_blocks_rootid_up_sql() ([]byte, error) {
return bindata_read(
__000003_blocks_rootid_up_sql,
"000003_blocks_rootid.up.sql",
)
}
func _000003_blocks_rootidUpSql() (*asset, error) {
bytes, err := _000003_blocks_rootidUpSqlBytes()
if err != nil {
return nil, err
}
var __000004_auth_table_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\x2d\x4e\x2d\x2a\xb6\xe6\xc2\x2e\x59\x9c\x5a\x5c\x9c\x99\x9f\x57\x6c\xcd\x05\x08\x00\x00\xff\xff\xb6\xc1\x44\xa1\x3d\x00\x00\x00")
info := bindataFileInfo{name: "000003_blocks_rootid.up.sql", size: 62, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000004_auth_tableDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\x2d\x4e\x2d\x2a\xb6\xe6\xc2\x2e\x59\x9c\x5a\x5c\x9c\x99\x9f\x57\x6c\xcd\x05\x08\x00\x00\xff\xff\xb6\xc1\x44\xa1\x3d\x00\x00\x00")
func _000004_auth_tableDownSqlBytes() ([]byte, error) {
return bindataRead(
__000004_auth_tableDownSql,
func _000004_auth_table_down_sql() ([]byte, error) {
return bindata_read(
__000004_auth_table_down_sql,
"000004_auth_table.down.sql",
)
}
func _000004_auth_tableDownSql() (*asset, error) {
bytes, err := _000004_auth_tableDownSqlBytes()
if err != nil {
return nil, err
}
var __000004_auth_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x91\x4d\x4f\x32\x31\x14\x85\xd7\xcc\xaf\xb8\x4b\x48\x08\xe1\x25\x2f\x89\x89\xab\x82\x45\x47\x11\x4c\xa7\x1a\x58\x4d\x2a\xbd\xa3\x8d\xf3\x65\x6f\xf1\x23\x4d\xff\xbb\x99\x48\x24\x61\x30\x71\xa1\x5d\x3e\xa7\xed\xb9\xf7\x9c\xa9\xe0\x4c\x72\x90\x6c\x32\xe7\x10\xcf\x60\xb1\x94\xc0\x57\x71\x22\x13\xf0\x7e\x50\x5b\xcc\xcc\x5b\x08\x5b\x42\x4b\xd0\x8d\x3a\x46\xc3\x1d\x13\xd3\x0b\x26\xba\xff\x86\xc3\x5e\x3f\xea\x34\x52\xa9\x0a\x3c\xe4\x58\x28\x93\x7f\xc1\xd1\x78\xdc\xc0\x5a\x11\xbd\x56\xb6\xf5\x49\x91\xa9\x94\x70\x63\xd1\x1d\x2a\x6a\xeb\x1e\x53\x42\xfb\x62\x36\x7b\x8b\xd1\x5e\xd2\xca\xa9\x96\x8b\xad\x6a\x82\xcf\xe3\xbd\xc9\x60\x50\x57\xe4\x1e\x2c\x52\x08\x97\xc9\x72\xe1\x3d\xe6\x84\x21\x48\xbe\x92\xde\x63\xa9\x43\xe8\x47\x9d\x8d\x45\xe5\x30\x55\xae\x79\x36\x89\xcf\xe3\x85\x6c\xd6\xab\xf5\x11\xaa\x31\xc7\x36\xbd\x11\xf1\x35\x13\x6b\xb8\xe2\x6b\xe8\x1a\xdd\x8b\x7a\x3b\xfb\xe2\x9d\x9e\xf3\x10\xce\xf8\x8c\xdd\xce\x25\x34\xb3\xb2\xa9\xe4\x02\x12\x2e\x61\xeb\xb2\x93\xe2\xfe\xff\x6e\x90\xd3\x28\xfa\x59\x25\x84\x44\xa6\x2a\xbf\x69\xc5\x55\x4f\x58\x1e\xab\x2a\x6d\xdf\xfd\xfb\xb8\x7e\x27\x98\x8f\x00\x00\x00\xff\xff\x43\xa6\x60\x6a\xab\x02\x00\x00")
info := bindataFileInfo{name: "000004_auth_table.down.sql", size: 61, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000004_auth_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x91\x4d\x4b\x33\x31\x14\x85\xd7\x9d\x5f\x71\x97\x2d\x94\xd2\xb7\xbc\x05\xc1\xd5\x74\x88\x3a\x5a\x5b\x99\x09\xd2\xae\x86\x38\xb9\xa3\xc1\xf9\x32\x37\xe3\x07\x21\xff\x5d\x42\x8b\x85\x4e\x05\x37\xcd\x2e\xcf\x49\x72\x6e\xce\x89\x12\x16\x72\x06\x3c\x5c\x2c\x19\xc4\x57\xb0\x5a\x73\x60\x9b\x38\xe5\x29\x58\x3b\x69\x35\x16\xea\xd3\xb9\x8e\x50\x13\x0c\x83\x81\x92\xf0\x18\x26\xd1\x4d\x98\x0c\xff\x4d\xa7\xa3\x71\x30\xf0\x52\x2d\x2a\x3c\xe6\x58\x09\x55\xfe\xc0\xd9\x7c\xee\x61\x2b\x88\x3e\x1a\xdd\x7b\xa4\x2a\x44\x46\x98\x6b\x34\xc7\x8a\xe8\xcc\x4b\x46\xa8\xdf\x55\x7e\xb0\x98\x1d\x24\x29\x8c\xe8\xb9\xe8\xa6\x25\xd8\x2d\x6b\x55\x01\x93\xb6\x21\xf3\xac\x91\x9c\xbb\x4d\xd7\x2b\x6b\xb1\x24\x74\x8e\xb3\x0d\xb7\x16\x6b\xe9\xdc\x38\x18\xe4\x1a\x85\xc1\x4c\x18\x7f\x6d\x11\x5f\xc7\x2b\xee\xbf\xd7\xca\x13\x54\x62\x89\x7d\xfa\x90\xc4\xf7\x61\xb2\x85\x3b\xb6\x85\xa1\x92\xa3\x60\xb4\x73\xaf\xbe\xe8\xad\x74\xce\x8f\x18\x46\x9c\x25\x90\x32\x0e\x9d\x29\x2e\xaa\xa7\xff\x10\xad\x97\x4b\xdf\xc0\x7e\x9f\x75\xb5\xca\x1b\x89\x59\xae\xf6\xa3\x5d\x06\xc1\xdf\x4a\x22\x24\x52\x4d\xfd\x4b\x4f\xa6\x79\xc5\xfa\x54\x79\x59\xff\xec\xf9\x03\x3c\x57\x54\xdf\x01\x00\x00\xff\xff\xdb\x28\x46\xba\xcf\x02\x00\x00")
func _000004_auth_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__000004_auth_tableUpSql,
func _000004_auth_table_up_sql() ([]byte, error) {
return bindata_read(
__000004_auth_table_up_sql,
"000004_auth_table.up.sql",
)
}
func _000004_auth_tableUpSql() (*asset, error) {
bytes, err := _000004_auth_tableUpSqlBytes()
if err != nil {
return nil, err
}
var __000005_blocks_modifiedby_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\xc8\xcd\x4f\xc9\x4c\xcb\x4c\x4d\x89\x4f\xaa\xb4\xe6\x02\x04\x00\x00\xff\xff\x6a\xfe\x38\x0a\x37\x00\x00\x00")
info := bindataFileInfo{name: "000004_auth_table.up.sql", size: 719, mode: os.FileMode(436), modTime: time.Unix(1621870643, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000005_blocks_modifiedbyDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\xc8\xcd\x4f\xc9\x4c\xcb\x4c\x4d\x89\x4f\xaa\xb4\xe6\x02\x04\x00\x00\xff\xff\x6a\xfe\x38\x0a\x37\x00\x00\x00")
func _000005_blocks_modifiedbyDownSqlBytes() ([]byte, error) {
return bindataRead(
__000005_blocks_modifiedbyDownSql,
func _000005_blocks_modifiedby_down_sql() ([]byte, error) {
return bindata_read(
__000005_blocks_modifiedby_down_sql,
"000005_blocks_modifiedby.down.sql",
)
}
func _000005_blocks_modifiedbyDownSql() (*asset, error) {
bytes, err := _000005_blocks_modifiedbyDownSqlBytes()
if err != nil {
return nil, err
}
var __000005_blocks_modifiedby_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\xc8\xcd\x4f\xc9\x4c\xcb\x4c\x4d\x89\x4f\xaa\x54\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\x02\x04\x00\x00\xff\xff\x30\x55\xd2\xd8\x42\x00\x00\x00")
info := bindataFileInfo{name: "000005_blocks_modifiedby.down.sql", size: 55, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000005_blocks_modifiedbyUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\xc8\xcd\x4f\xc9\x4c\xcb\x4c\x4d\x89\x4f\xaa\x54\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\x02\x04\x00\x00\xff\xff\x30\x55\xd2\xd8\x42\x00\x00\x00")
func _000005_blocks_modifiedbyUpSqlBytes() ([]byte, error) {
return bindataRead(
__000005_blocks_modifiedbyUpSql,
func _000005_blocks_modifiedby_up_sql() ([]byte, error) {
return bindata_read(
__000005_blocks_modifiedby_up_sql,
"000005_blocks_modifiedby.up.sql",
)
}
func _000005_blocks_modifiedbyUpSql() (*asset, error) {
bytes, err := _000005_blocks_modifiedbyUpSqlBytes()
if err != nil {
return nil, err
}
var __000006_sharing_table_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xce\x48\x2c\xca\xcc\x4b\xb7\xe6\x02\x04\x00\x00\xff\xff\x7a\x74\xe5\xab\x1f\x00\x00\x00")
info := bindataFileInfo{name: "000005_blocks_modifiedby.up.sql", size: 66, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000006_sharing_tableDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xce\x48\x2c\xca\xcc\x4b\xb7\xe6\x02\x04\x00\x00\xff\xff\x7a\x74\xe5\xab\x1f\x00\x00\x00")
func _000006_sharing_tableDownSqlBytes() ([]byte, error) {
return bindataRead(
__000006_sharing_tableDownSql,
func _000006_sharing_table_down_sql() ([]byte, error) {
return bindata_read(
__000006_sharing_table_down_sql,
"000006_sharing_table.down.sql",
)
}
func _000006_sharing_tableDownSql() (*asset, error) {
bytes, err := _000006_sharing_tableDownSqlBytes()
if err != nil {
return nil, err
}
var __000006_sharing_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\xcc\x41\x4b\xc3\x30\x18\x06\xe0\x73\xf3\x2b\xde\x63\x0b\x65\x4c\x14\x11\x3c\xa5\xf5\x9b\x06\x6b\x2b\xe9\xa7\xb8\xd3\x68\x49\xaa\xc1\xb5\x9b\x5b\x06\x8e\x90\xff\x2e\xbd\x78\xd8\xfd\xe1\x29\x35\x49\x26\xb0\x2c\x2a\x82\x5a\xa1\x6e\x18\xf4\xa1\x5a\x6e\x11\xc2\x62\x7f\xb0\x83\xfb\x8d\xf1\xf8\xd5\x1d\xdc\xf4\x89\x54\x24\xce\xe0\x5d\xea\xf2\x49\xea\xf4\xfa\x36\xcb\x45\x62\xa7\xae\xdf\x5a\x83\xa2\x69\x2a\x92\x75\x2e\x12\xbf\xfb\xb6\xd3\xbf\xba\x5a\x2e\x67\x36\xee\x8c\x1b\x9c\x35\x9b\xfe\x7c\x11\x9c\xf6\xa6\xf3\x76\xd3\x79\x14\xea\x51\xd5\x9c\x8b\xe4\x55\xab\x17\xa9\xd7\x78\xa6\x35\x52\x67\x32\x91\x21\x04\x37\x60\x31\x9e\x8f\x3f\xdb\x18\x1f\x68\x25\xdf\x2a\xc6\xbc\xc8\x92\x49\xa3\x25\xc6\xc9\x0f\x77\x63\x7f\x13\x82\x9d\x4c\x8c\xf7\xe2\x2f\x00\x00\xff\xff\x82\xbb\xda\xde\xdc\x00\x00\x00")
info := bindataFileInfo{name: "000006_sharing_table.down.sql", size: 31, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000006_sharing_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\xcf\x51\x4b\x84\x40\x14\x05\xe0\x67\xe7\x57\xdc\x47\x05\x59\x36\x8a\x08\x7a\x1a\x65\xaa\x21\xd3\x18\x87\x68\x9f\x44\xf7\x5e\xeb\xd2\x3a\x6e\xbb\x0a\xc9\x30\xff\x3d\x84\xe8\x61\x1f\x0f\x7c\xe7\xc0\xc9\x8d\x92\x56\x81\x95\x59\xa1\x40\x3f\x40\x59\x59\x50\xef\xba\xb6\x35\x78\xbf\x39\x9e\xa8\xe7\x9f\x10\xce\x9f\xed\x89\xdd\x07\xc4\x22\x62\x84\x37\x69\xf2\x27\x69\xe2\xeb\xdb\x24\x15\x11\xb9\xb6\x3b\x10\x42\x56\x55\x85\x92\x65\x2a\xa2\x69\xfc\x22\xf7\xaf\xae\xb6\xdb\x95\x0d\x23\x72\xcf\x84\x4d\xb7\x5c\x0c\xcc\x47\x6c\x27\x6a\xda\x09\x32\xfd\xa8\x4b\x9b\x8a\xe8\xd5\xe8\x17\x69\x76\xf0\xac\x76\x10\x33\x26\x22\xf1\x9e\x7b\xd8\x0c\xcb\xf9\xfb\x10\xc2\x5a\x96\xb9\x55\x06\x6a\x65\x61\x9e\xfa\xbb\xa1\xbb\x81\xbc\x2a\x8a\xf5\xcb\x5f\x6e\x66\xc7\xfb\x11\xa9\xd9\xb3\xf7\xe4\x30\x84\x7b\xf1\x1b\x00\x00\xff\xff\xc9\xca\x17\x02\xee\x00\x00\x00")
func _000006_sharing_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__000006_sharing_tableUpSql,
func _000006_sharing_table_up_sql() ([]byte, error) {
return bindata_read(
__000006_sharing_table_up_sql,
"000006_sharing_table.up.sql",
)
}
func _000006_sharing_tableUpSql() (*asset, error) {
bytes, err := _000006_sharing_tableUpSqlBytes()
if err != nil {
return nil, err
}
var __000007_workspaces_table_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x2d\xb6\xe6\x02\x04\x00\x00\xff\xff\x1a\xe4\xe6\x36\x22\x00\x00\x00")
info := bindataFileInfo{name: "000006_sharing_table.up.sql", size: 238, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000007_workspaces_tableDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x2d\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x2d\xb6\xe6\x02\x04\x00\x00\xff\xff\x1a\xe4\xe6\x36\x22\x00\x00\x00")
func _000007_workspaces_tableDownSqlBytes() ([]byte, error) {
return bindataRead(
__000007_workspaces_tableDownSql,
func _000007_workspaces_table_down_sql() ([]byte, error) {
return bindata_read(
__000007_workspaces_table_down_sql,
"000007_workspaces_table.down.sql",
)
}
func _000007_workspaces_tableDownSql() (*asset, error) {
bytes, err := _000007_workspaces_tableDownSqlBytes()
if err != nil {
return nil, err
}
var __000007_workspaces_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\xcd\x41\x4b\xc3\x30\x18\xc6\xf1\x73\xf3\x29\xde\xe3\x0a\x65\x4c\x14\x11\x3c\x65\x35\xd3\x6a\xed\x24\xcd\x64\x3b\x95\xce\xbc\x2d\x61\x6b\x1b\x9b\x14\x1d\xe1\xfd\xee\x32\x19\x1e\x3c\x3f\x0f\xff\x5f\x2a\x05\x57\x02\x14\x5f\xe6\x02\xb2\x15\x14\x6b\x05\x62\x9b\x95\xaa\x84\x10\xe6\x76\xc4\xc6\x7c\x13\x7d\x0d\xe3\xc1\xd9\xfa\x03\x1d\xcc\x58\x64\x34\xbc\x73\x99\x3e\x71\x39\xbb\xbe\x8d\x13\x16\x39\xd3\xf6\x93\xad\xfc\x70\xc0\xfe\x6f\xba\x5a\x2c\xe2\xdf\x5c\xb1\xc9\xf3\xf3\x09\xbd\x37\x7d\xeb\x20\x04\xd3\xc0\xdc\x0e\xce\xb7\x23\x3a\xa2\xe7\x72\x5d\x84\x80\x47\x87\x44\x4a\x6c\x55\x08\xd8\x6b\xa2\x84\x45\xdd\xa0\x4d\x63\x50\x57\xfb\xd3\x3f\x71\xb2\xba\xf6\x58\xd5\x1e\x96\xd9\x63\x56\xa8\x84\x45\x6f\x32\x7b\xe5\x72\x07\x2f\x62\x07\x33\xa3\x63\x16\x5f\xa4\xee\xe4\x3e\x8f\x44\x0f\x62\xc5\x37\xb9\x82\x73\x85\xa7\x4a\x48\x28\x85\x82\xc9\x37\x77\xdd\xfe\xe6\x62\xde\xb3\x9f\x00\x00\x00\xff\xff\x29\x38\x4d\xc3\x10\x01\x00\x00")
info := bindataFileInfo{name: "000007_workspaces_table.down.sql", size: 34, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000007_workspaces_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8f\x51\x4f\x83\x30\x14\x85\x9f\xe9\xaf\xb8\x8f\x90\x90\x65\x46\x63\x4c\x7c\xea\x48\x55\x14\xc1\x94\x6a\xb6\x27\xc2\xe8\x85\x34\x1b\x50\x69\x89\x2e\x4d\xff\xbb\x41\x17\x1f\xf6\x78\x73\xcf\x39\xdf\x39\x09\x67\x54\x30\x10\x74\x93\x31\x48\x1f\x20\x2f\x04\xb0\x6d\x5a\x8a\x12\x9c\x5b\xe9\x09\x5b\xf5\xed\xfd\xd7\x38\x1d\x8c\xae\x1b\x34\x10\x92\x40\x49\xf8\xa0\x3c\x79\xa2\x3c\xbc\xbe\x8d\x62\x12\x18\xd5\x0d\xb3\xae\xec\x78\xc0\xe1\xff\x75\xb5\x5e\x47\xbf\x71\xf9\x7b\x96\x2d\x22\xb4\x56\x0d\x9d\x01\xe7\x54\x0b\x2b\x3d\x1a\xdb\x4d\x68\xbc\x7f\x2e\x8b\xdc\x39\x3c\x1a\xf4\x5e\xb0\xad\x70\x0e\x07\xe9\x7d\x4c\x82\x7e\x94\xaa\x55\x28\xab\xfd\xe9\x82\x38\x6b\x59\x5b\xac\x6a\x0b\x9b\xf4\x31\xcd\x45\x4c\x82\x37\x9e\xbe\x52\xbe\x83\x17\xb6\x83\x50\xc9\x88\x44\x7f\xa0\xfe\x64\x3e\x8f\xde\x2f\x66\x9a\x08\xc6\xa1\x64\x02\x66\xdb\xde\xf5\xfb\x1b\x48\x8a\x2c\x5b\xf6\x9f\xef\x6a\x1e\x54\x33\x4a\xac\x1a\x75\x6e\x71\x4f\x7e\x02\x00\x00\xff\xff\x26\xb1\xb4\x1a\x22\x01\x00\x00")
func _000007_workspaces_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__000007_workspaces_tableUpSql,
func _000007_workspaces_table_up_sql() ([]byte, error) {
return bindata_read(
__000007_workspaces_table_up_sql,
"000007_workspaces_table.up.sql",
)
}
func _000007_workspaces_tableUpSql() (*asset, error) {
bytes, err := _000007_workspaces_tableUpSqlBytes()
if err != nil {
return nil, err
}
var __000008_teams_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x8d\xcf\x4c\xb1\xe6\xe2\xc2\xa1\xb1\x38\x23\xb1\x28\x33\x2f\x9d\x1c\x9d\xa9\xc5\xc5\x99\xf9\x79\xa8\x96\x26\x96\x96\x64\xc4\x17\xa7\x16\x95\x65\x26\xa7\x5a\x73\x01\x02\x00\x00\xff\xff\x24\x48\xc4\xb6\xad\x00\x00\x00")
info := bindataFileInfo{name: "000007_workspaces_table.up.sql", size: 290, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000008_teamsDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x09\xf2\x0f\x50\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x8d\xcf\x4c\xb1\xe6\xe2\xc2\xa1\xb1\x38\x23\xb1\x28\x33\x2f\x9d\x1c\x9d\xa9\xc5\xc5\x99\xf9\x79\xa8\x96\x26\x96\x96\x64\xc4\x17\xa7\x16\x95\x65\x26\xa7\x5a\x73\x01\x02\x00\x00\xff\xff\x24\x48\xc4\xb6\xad\x00\x00\x00")
func _000008_teamsDownSqlBytes() ([]byte, error) {
return bindataRead(
__000008_teamsDownSql,
func _000008_teams_down_sql() ([]byte, error) {
return bindata_read(
__000008_teams_down_sql,
"000008_teams.down.sql",
)
}
func _000008_teamsDownSql() (*asset, error) {
bytes, err := _000008_teamsDownSqlBytes()
if err != nil {
return nil, err
}
var __000008_teams_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x8d\xcf\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\xe2\xc2\x61\x46\x71\x46\x62\x51\x66\x5e\x3a\x85\x86\xa4\x16\x17\x67\xe6\xe7\xa1\x38\x25\xb1\xb4\x24\x23\xbe\x38\xb5\xa8\x2c\x33\x39\x15\x6e\x8a\x91\x01\xc8\x94\xd0\x00\x17\xc7\x10\x2c\x3e\x51\x08\x76\x0d\x41\xb5\xdd\x56\x41\xdd\x40\x5d\x21\xdc\xc3\x35\xc8\x15\x43\x42\x5d\xc1\x3f\x08\x55\xd0\x33\x58\xc1\x2f\xd4\xc7\xc7\x9a\x0b\x10\x00\x00\xff\xff\xab\x8d\x48\xa9\x30\x01\x00\x00")
info := bindataFileInfo{name: "000008_teams.down.sql", size: 173, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000008_teamsUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xe6\x72\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xcf\x2f\xca\x2e\x2e\x48\x4c\x4e\x8d\xcf\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x36\xd3\xb4\xe6\xe2\xc2\x61\x46\x71\x46\x62\x51\x66\x5e\x3a\x85\x86\xa4\x16\x17\x67\xe6\xe7\xa1\x38\x25\xb1\xb4\x24\x23\xbe\x38\xb5\xa8\x2c\x33\x39\x15\x6e\x8a\x91\x01\xc8\x94\xd0\x00\x17\xc7\x10\x2c\x3e\x51\x08\x76\x0d\x41\xb5\xdd\x56\x41\xdd\x40\x5d\x21\xdc\xc3\x35\xc8\x15\x43\x42\x5d\xc1\x3f\x08\x55\xd0\x33\x58\xc1\x2f\xd4\xc7\xc7\x9a\x0b\x10\x00\x00\xff\xff\xab\x8d\x48\xa9\x30\x01\x00\x00")
func _000008_teamsUpSqlBytes() ([]byte, error) {
return bindataRead(
__000008_teamsUpSql,
func _000008_teams_up_sql() ([]byte, error) {
return bindata_read(
__000008_teams_up_sql,
"000008_teams.up.sql",
)
}
func _000008_teamsUpSql() (*asset, error) {
bytes, err := _000008_teamsUpSqlBytes()
if err != nil {
return nil, err
}
var __000009_blocks_history_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xb6\xe6\x72\xf4\x09\x71\x0d\xc2\x25\x1d\x9f\x91\x59\x5c\x92\x5f\x54\xa9\x10\xe4\xea\xe7\xe8\xeb\xaa\x10\xe2\x8f\xcd\x08\x40\x00\x00\x00\xff\xff\x38\xe5\xec\x7a\x61\x00\x00\x00")
info := bindataFileInfo{name: "000008_teams.up.sql", size: 304, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000009_blocks_historyDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xa8\xae\xd6\x2b\x28\x4a\x4d\xcb\xac\xa8\xad\x4d\xca\xc9\x4f\xce\x2e\xb6\xe6\x72\xf4\x09\x71\x0d\xc2\x25\x1d\x9f\x91\x59\x5c\x92\x5f\x54\xa9\x10\xe4\xea\xe7\xe8\xeb\xaa\x10\xe2\x8f\xcd\x08\x40\x00\x00\x00\xff\xff\x38\xe5\xec\x7a\x61\x00\x00\x00")
func _000009_blocks_historyDownSqlBytes() ([]byte, error) {
return bindataRead(
__000009_blocks_historyDownSql,
func _000009_blocks_history_down_sql() ([]byte, error) {
return bindata_read(
__000009_blocks_history_down_sql,
"000009_blocks_history.down.sql",
)
}
func _000009_blocks_historyDownSql() (*asset, error) {
bytes, err := _000009_blocks_historyDownSqlBytes()
if err != nil {
return nil, err
}
var __000009_blocks_history_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x93\xd1\x6f\xda\x30\x10\xc6\x9f\xc9\x5f\x71\x2f\x11\xc9\x94\x56\x93\x36\xa1\xa9\x48\x93\x42\x38\xc0\x5b\x62\x57\x8e\xbb\x96\xbd\x50\x20\xce\xb0\x1a\x48\x1a\xa7\xea\x50\x94\xff\x7d\x4a\x47\x28\x0d\xa0\x3d\x4c\x7d\xc3\x3e\xdf\xef\xbe\xfb\xf8\xe2\xfa\x02\x39\x08\x77\xe0\x23\x94\xe5\x65\x96\xcb\x58\xfd\xae\xaa\x45\x92\x2e\x1f\x34\x70\xa4\x6e\x80\x20\xd8\x71\x6d\xb6\x52\xba\x48\xf3\x6d\xdf\xf0\x38\xba\x02\x77\x0c\x32\x02\xca\x04\xe0\x1d\x09\x45\x78\x82\x68\x19\x1d\x15\xc1\x0f\x97\x7b\x13\x97\x5b\x9f\x7a\xb6\x63\x74\xca\x52\xc5\x70\x99\xa5\xba\xf8\x95\x4b\x5d\x55\x6a\xa3\x65\x5e\xcc\xe6\x05\x08\x12\x60\x28\xdc\xe0\x5a\xfc\x7c\xc1\xd2\x1b\xdf\x87\x21\x8e\xdc\x1b\x5f\x00\x65\xb7\x96\xed\x94\xa5\xdc\x44\x55\xd5\x50\xf4\x63\xa2\x0a\x79\xc8\x18\xba\x02\x6b\xce\x11\xc0\x0a\x05\x1f\xd5\x15\xab\x6b\x4e\x2f\xcc\xf5\x85\x19\x81\x39\xb9\x32\x83\x2b\x33\xee\x3a\xd0\xa5\xec\xb6\x6b\x1f\x0d\x58\x6f\xf5\x63\x72\x8a\x6f\xf5\xec\xd3\x1a\x7b\x07\x8c\x6c\x9e\xcb\x4d\x31\x3b\x63\xc1\x8e\x7d\xaf\x97\x2b\xb9\x9e\xdf\x97\xa5\x4c\xb4\xac\xaa\xbf\xc7\x1d\x03\x06\x64\x4c\xa8\x70\x8c\x4e\xb1\xcd\x24\x08\xbc\x7b\xf9\xad\x8a\x64\x7f\x88\x95\x4c\x22\x0d\x6d\x5b\xbf\x85\x8c\x36\xc8\xfa\xe5\x0e\xe8\x18\x9d\x65\x2e\xe7\x85\xac\x97\xd9\xc3\x9f\xb2\xa8\x7d\x15\xc9\x44\xb6\xae\xf2\x34\x3d\xb1\xcc\x3a\x8d\x54\xac\x64\x34\x5b\x6c\x5b\x95\xe7\x34\x7f\xd0\xd9\x7c\x29\x8f\x9b\xae\x39\x09\x5c\x3e\x85\xef\x38\x05\xeb\xf0\x9d\xa3\x22\xdb\xb0\xe1\x8d\x43\x8d\xbd\x75\xbf\xeb\xd5\x09\x0e\x51\xc0\x53\x11\x7f\x59\x2f\x3e\xef\xf6\xea\x1b\xc6\x9b\x1e\x83\xd0\x10\xb9\x00\x32\xa6\x8c\x23\x10\x7a\x2a\xd5\x60\x85\xe8\xa3\x27\xe0\x03\x8c\x38\x0b\xce\xc7\x1e\x18\x1f\x22\x87\xc1\x14\x0e\x92\x80\xa1\x67\xf7\x8d\xe6\xcf\x6e\xfb\xbf\x17\xf0\x4e\x93\x81\x51\xf0\x18\x1d\xf9\xc4\x13\x30\x64\x75\x18\x27\x84\x8e\xdb\x82\x9a\x2f\xa4\x91\xc3\xf8\x3f\x2c\xf9\x4f\x5d\xaf\xf3\x87\xe8\xa3\xc0\x33\x18\x78\x5e\xc9\x5c\xc2\x6b\xc8\xbe\xc2\xc7\xbe\xf1\x27\x00\x00\xff\xff\xd3\x97\xb4\x77\x9f\x04\x00\x00")
info := bindataFileInfo{name: "000009_blocks_history.down.sql", size: 97, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000009_blocks_historyUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x93\xd1\x6f\x9b\x3e\x10\xc7\x9f\xc3\x5f\x71\x2f\x28\xf0\x13\xad\x7e\xd2\xa6\x68\x6a\xa4\x49\x84\x5c\x12\x36\xb0\x2b\xe3\xae\xcd\x5e\x68\x02\x66\xb1\x4a\x02\xc5\x44\x5d\x84\xf8\xdf\x27\x3a\x92\xa6\x24\xd1\x1e\xa6\xbd\xf9\x7c\xf6\xe7\xbe\x77\xfe\xda\xf6\x38\x32\xe0\xf6\xc8\x43\xa8\xaa\xeb\xbc\x10\x89\xfc\x59\xd7\xcb\x34\x8b\x9e\x14\x30\x24\xb6\x8f\xc0\xe9\x69\x2e\x5c\x49\x55\x66\xc5\x6e\xa8\x39\x0c\x6d\x8e\x2d\xc3\x9d\x00\xa1\x1c\xf0\xc1\x0d\x78\x70\x86\x68\x68\x3d\x19\xc3\x37\x9b\x39\x33\x9b\x19\x1f\x06\xa6\xa5\xf5\xaa\x4a\x26\x70\x9d\x67\xaa\xfc\x51\x08\x55\xd7\x72\xa3\x44\x51\x86\x8b\x12\xb8\xeb\x63\xc0\x6d\xff\x96\x7f\x7f\xc5\x92\x3b\xcf\x83\x31\x4e\xec\x3b\x8f\x03\xa1\xf7\x86\x69\x55\x95\xd8\xc4\x75\xbd\xa7\xa8\xe7\x54\x96\xe2\x98\x31\xb6\x39\x36\x9c\x13\x80\x11\x70\x36\x69\x32\x46\x5f\x9f\x5f\xe9\xeb\x2b\x3d\x06\x7d\x76\xa3\xfb\x37\x7a\xd2\xb7\xa0\x4f\xe8\x7d\xdf\x3c\x29\xb0\xde\xa9\xe7\xf4\x1c\xdf\x18\x98\xe7\x35\x0e\x8e\x18\xf9\xa2\x10\x9b\x32\xbc\x30\x82\x96\xfd\xa8\xa2\x95\x58\x2f\x1e\xab\x4a\xa4\x4a\xd4\xf5\xef\xb0\x65\xc0\xc8\x9d\xba\x84\x5b\x5a\xaf\xdc\xe5\x02\x38\x3e\xbc\xae\x65\x99\x1e\x82\x44\x8a\x34\x56\xd0\x1d\xeb\x97\x80\x92\x3d\xb2\x39\xd9\x02\x2d\xad\x17\x15\x62\x51\x8a\xa6\x99\x03\x7c\x9b\xc7\xdd\xad\x58\xa4\xa2\xb3\x55\x64\xd9\x99\x66\xd6\x59\x2c\x13\x29\xe2\x70\xb9\xeb\x64\x5e\xb2\xe2\x49\xe5\x8b\x48\x9c\x5e\xba\x65\xae\x6f\xb3\x39\x7c\xc5\x39\x18\xc7\xe7\x2c\x19\x9b\x9a\xf9\x6e\x40\xcd\x35\xdb\x69\x8c\x1b\x20\x87\x6d\x99\x7c\x5a\x2f\x3f\x82\x43\x3d\xaf\x31\x62\x1b\x87\xdb\x8d\x8c\xb2\x58\x84\x91\x6c\x3b\x1d\x6a\xda\x3b\x8c\xe6\x92\x00\x19\x07\x77\x4a\x28\x43\x70\xc9\x39\x9f\x83\x11\xa0\x87\x0e\x87\xff\x60\xc2\xa8\x7f\xf9\x23\x00\x65\x63\x64\x30\x9a\xc3\x91\x37\x30\x70\xcc\xa1\xb6\x7f\xfe\xee\x8b\x1c\x04\xfc\xa3\xca\x40\x09\x38\x94\x4c\x3c\xd7\xe1\x30\xa6\x8d\x3d\x67\x2e\x99\x76\x05\xed\xff\xcc\x5e\x0e\x65\x7f\x18\xc9\x5f\xea\x7a\xab\x3f\x46\x0f\x39\x5e\xc0\xc0\xcb\x4a\x14\x02\xde\x6c\xf7\x19\xfe\x1f\x6a\xbf\x02\x00\x00\xff\xff\xfe\x36\xd4\x6a\xb1\x04\x00\x00")
func _000009_blocks_historyUpSqlBytes() ([]byte, error) {
return bindataRead(
__000009_blocks_historyUpSql,
func _000009_blocks_history_up_sql() ([]byte, error) {
return bindata_read(
__000009_blocks_history_up_sql,
"000009_blocks_history.up.sql",
)
}
func _000009_blocks_historyUpSql() (*asset, error) {
bytes, err := _000009_blocks_historyUpSqlBytes()
if err != nil {
return nil, err
}
var __000010_blocks_created_by_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x54\xc1\x6e\x9b\x40\x10\xbd\xf3\x15\x73\x41\x86\xca\x89\x2a\xb5\xb2\xaa\x58\xaa\x84\x61\x6c\xd3\xc2\xae\xb5\x6c\x9a\xb8\x17\xc7\x36\x4b\x8d\x82\x0d\x01\xa2\xd4\x42\xfc\x7b\x85\x0d\x0e\x8e\xb1\xa3\xaa\xce\xa5\xca\x71\x77\x67\xde\x7b\x33\x3b\xf3\x34\x8b\x23\x03\xae\xf5\x2c\x84\x2c\xbb\x8c\x62\xe1\xf9\xbf\xf3\x7c\x16\x84\xf3\xfb\x04\x18\x12\xcd\x46\xe0\xf4\xf0\x6d\x12\x06\x6e\x57\xd2\x19\x6a\x1c\xcb\x7c\xb3\x0f\x84\x72\xc0\x5b\xd3\xe1\x4e\x03\x9a\x22\x01\x00\xf8\x2e\xfc\xd0\x98\x3e\xd4\x98\xf2\xa9\xa3\xb6\x37\x77\x59\xe6\x7b\x70\x19\x85\x49\xfa\x2b\x16\x49\x9e\xfb\xab\x44\xc4\xe9\x64\x9a\x02\x37\x6d\x74\xb8\x66\x8f\xf8\xcf\x0d\x38\xb9\xb6\x2c\x30\xb0\xaf\x5d\x5b\x1c\x08\xbd\x51\xd4\x76\x96\x89\x95\x9b\xe7\x35\xa0\xe4\x21\xf0\x53\x51\x87\x31\x34\x8e\x05\xd4\x01\x86\xe2\x70\xd6\x2f\x5e\x94\x96\x3c\xbe\x90\x97\x17\xb2\x0b\xf2\xf0\x4a\xb6\xaf\x64\xaf\xd5\x86\x16\xa1\x37\x2d\xb5\x89\x63\xb9\x4e\x1e\x82\x26\x0a\xa5\xa3\x36\x2b\xed\xec\xc3\x44\xd3\x58\xac\xd2\xc9\xf1\x76\x94\x0c\x77\xc9\x7c\x21\x96\xd3\xbb\x2c\x13\x41\x22\xf2\x7c\x7b\x2c\x91\xa0\x67\x0e\x4c\xc2\xb7\x69\xe9\x3a\x12\xc0\xf1\xb6\x3a\xfa\x69\x50\x3f\x7b\xbe\x08\xdc\xe4\xa0\xd7\xdf\x1c\x4a\x2a\xec\x22\xb8\x44\xde\xe6\xcc\x63\x31\x4d\x45\x51\x5e\x9d\xe8\x31\x72\x1b\x6e\x5d\x11\x88\xc3\xdb\x38\x0c\x9b\x8b\x5c\x86\xae\xef\xf9\xc2\x9d\xcc\xd6\x87\x8f\x4f\x61\x7c\x9f\x44\xd3\xb9\x68\x4c\x1d\x31\xd3\xd6\xd8\x18\xbe\xe3\x18\x94\x7a\x68\xdb\x77\xd5\x4d\x84\xba\xdf\xc3\xea\x1b\x0a\x18\x4d\x2f\x26\xde\x41\x0e\x8f\xa9\xf7\x65\x39\xfb\x5c\x16\xdc\x95\xa4\xbd\x1c\xc9\x24\x0e\x32\x0e\xe6\x80\x50\x86\x60\x92\xa6\x2d\x00\xc5\x41\x0b\x75\x0e\x1f\xa0\xcf\xa8\xdd\xbc\x26\x40\x99\x81\x0c\x7a\x63\xa8\x4d\x0b\x3a\xba\xda\x95\xaa\x81\x78\xf9\x29\x3b\xf2\x37\x60\x05\x4a\x40\xa7\xa4\x6f\x99\x3a\x07\x83\x16\xc3\x3a\x34\xc9\xe0\xa5\x98\x6a\x89\x2a\x29\x94\xbd\xd2\x8a\x7f\xd0\xf4\xcc\x6d\xa0\x85\x1c\x8f\x40\xc0\xd3\x42\xc4\xa2\x36\x68\x5f\xe1\x63\x57\x32\x18\x1d\x1d\x73\xb0\xad\x4b\x49\xd2\x49\x9b\x9b\x2c\xfc\x24\x0d\xe3\xf5\x49\xbb\x2b\x63\xfe\xde\xf6\x76\xe8\xef\xf6\xf7\x6e\x7f\xff\x99\xfd\x3d\xcf\xf6\x6b\xcb\x5f\x5b\x9f\xb3\xdb\xe1\x79\x55\xbc\x91\x3d\xee\x44\x9e\x41\x63\xcd\x2e\x4f\x79\xdf\x9e\x65\xfd\x09\x00\x00\xff\xff\x5f\xbd\x27\xe2\xe9\x09\x00\x00")
info := bindataFileInfo{name: "000009_blocks_history.up.sql", size: 1201, mode: os.FileMode(436), modTime: time.Unix(1620140256, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000010_blocks_created_byDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x94\x51\x6f\x9b\x30\x10\xc7\xdf\xf9\x14\xf7\x82\x02\x53\x5a\x4d\xda\x54\x4d\x8d\x34\x89\x82\xd3\xb0\x81\x1d\x19\x77\x6d\xf6\x42\x13\x30\x8b\x55\x12\x28\x26\xea\x22\xc4\x77\x9f\x48\x48\x4a\x1a\x92\x6a\x5a\xfa\x32\xf5\xd1\xf6\xdd\xff\x8e\xe3\x7f\x3f\xc3\x61\x88\x02\x33\xae\x1c\x04\x45\x71\x9e\x66\x3c\x12\xbf\xcb\x72\x12\x27\xc1\x83\x04\x8a\xb0\xe1\x22\x60\x64\xff\xcd\x4f\xe2\xb0\xa7\x98\x14\x19\x0c\xd5\xf9\x76\x1f\x30\x61\x80\xee\x6c\x8f\x79\x2d\x6a\x9a\x02\x00\x20\x42\xf8\x61\x50\x73\x60\x50\xed\xd3\x85\xde\x5d\xdd\x15\x85\x88\xe0\x3c\x4d\x64\xfe\x2b\xe3\xb2\x2c\xc5\x5c\xf2\x2c\xf7\xc7\x39\x30\xdb\x45\x1e\x33\xdc\x21\xfb\xb9\x12\xc7\x37\x8e\x03\x16\xea\x1b\x37\x0e\x03\x4c\x6e\x35\xbd\x5b\x14\x7c\x1e\x96\x65\x43\x48\x3e\xc6\x22\xe7\x4d\x19\xcb\x60\xa8\x92\xda\xd3\xd0\x3c\x46\xfb\xd5\x8b\xd6\x51\x47\x67\xea\xec\x4c\x0d\x41\x1d\x5c\xaa\xee\xa5\x1a\x75\xba\xd0\xc1\xe4\xb6\xa3\xb7\xd5\x98\x2d\xe5\x63\xdc\x56\x42\xbb\xd0\xdb\x3b\xbd\xd8\x95\x49\xc7\x19\x9f\xe7\xfe\xe1\x71\xd4\x15\xee\x65\x30\xe5\xb3\xf1\x7d\x51\xf0\x58\xf2\xb2\x5c\x1f\x6b\x25\xb8\xb2\xaf\x6d\xcc\xd6\x69\xf9\x32\xe5\xc0\xd0\xdd\xe6\x28\xf2\xb8\x79\x8e\x04\x8f\x43\xb9\x37\xeb\x6f\x1e\xc1\x1b\xed\x2a\xb8\x56\x5e\xe7\x04\x19\x1f\xe7\xbc\xfa\xbc\x66\xa1\x45\x1a\xb6\xdc\x86\x3c\xe6\xfb\xb7\x59\x92\xb4\x7f\xe4\x2c\x09\x45\x24\x78\xe8\x4f\x96\xfb\x8f\x4f\x49\xf6\x20\xd3\x71\xc0\x5b\x53\x87\xd4\x76\x0d\x3a\x82\xef\x68\x04\x5a\x33\xb4\x2b\x42\x7d\x15\xa1\xef\x8c\xb0\xca\x36\xcc\xca\xe8\x1e\x62\xb0\xc8\xa3\x2f\xb3\xc9\x67\x30\x89\xe3\x54\xe6\xad\xcf\xfe\x62\x2e\x82\x24\xe4\x7e\x20\xea\x11\xf4\x14\x65\x47\x46\xb1\xb1\x87\x28\x03\xfb\x1a\x13\x8a\xc0\xc6\x6d\x7b\x01\x9a\x87\x1c\x64\x32\xf8\x00\x7d\x4a\xdc\xf6\xc5\x01\x42\x2d\x44\xe1\x6a\x04\x0d\xff\x20\xcf\xd4\x7b\xca\xc6\x22\x2f\x7f\xd3\xb6\xf8\x1b\x54\x05\x82\xc1\x24\xb8\xef\xd8\x26\x03\x8b\x54\xf6\x1d\xd8\xf8\xfa\x65\x33\x9b\xb5\xda\xb4\x42\xe8\x2b\xa3\xf8\x87\x9e\x9e\x6b\x5b\xc8\x41\x0c\x1d\x90\x80\xa7\x29\xcf\x78\xc3\x7a\x5f\xe1\x63\x4f\xb1\x28\x19\x1e\x62\xda\x9a\x5b\x8a\x72\x14\x7c\xfe\x54\xc8\x3c\xc9\x96\x47\x01\x58\xc7\xfc\x3d\x08\xb7\xea\xef\x40\x7c\x07\xe2\x7f\x0f\xc4\x67\xb7\xbf\x86\x83\xc6\x42\x9d\x1c\x90\xa7\xed\xe2\x8d\x80\xb9\x6d\xf2\x04\x3d\x36\x00\x7a\x8c\x86\x3b\x10\xfb\x13\x00\x00\xff\xff\xbd\xdd\x75\x63\x0d\x0a\x00\x00")
func _000010_blocks_created_byDownSqlBytes() ([]byte, error) {
return bindataRead(
__000010_blocks_created_byDownSql,
func _000010_blocks_created_by_down_sql() ([]byte, error) {
return bindata_read(
__000010_blocks_created_by_down_sql,
"000010_blocks_created_by.down.sql",
)
}
func _000010_blocks_created_byDownSql() (*asset, error) {
bytes, err := _000010_blocks_created_byDownSqlBytes()
if err != nil {
return nil, err
}
var __000010_blocks_created_by_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8e\x41\x4b\xc4\x30\x10\x85\xef\xfd\x15\x73\x6b\x0a\xb2\x20\x82\x97\x65\x0f\xb3\x49\x44\x21\x6e\x25\x4d\x05\x4f\x65\xb7\x9d\xb2\xc1\xc6\x48\x12\xd0\x52\xfa\xdf\xa5\x78\x11\xd4\xb2\x97\x39\xcc\x7b\xef\xe3\x43\x65\xa4\x06\x83\x7b\x25\x61\x9a\x36\xef\x81\x7a\xfb\x39\xcf\xa7\xc1\xb7\xaf\x11\x50\x08\xe0\xa5\xaa\x1f\x0f\xd0\x06\x3a\x26\xea\x9a\xd3\x08\xcf\xa8\xf9\x3d\x6a\x76\x73\x5b\x6c\xb3\x55\x40\x73\xb6\x31\xf9\x30\x5e\x02\xca\xea\x27\x81\xe6\x2f\x8b\x4a\x9a\x9f\xab\x1d\xf0\x12\x95\xac\xb8\x64\x87\x5a\xa9\x87\x3b\xc6\x22\x0d\xd4\x26\x70\xbe\xb3\xbd\xfd\x6e\xf5\xc1\xbb\x15\xa1\x8f\x33\x05\xfa\x3f\xdf\xd8\x0e\x76\xbf\xe3\xe5\x5d\x6a\x21\x35\xec\x5f\xd6\xc6\x6f\x91\x42\x6a\x8e\x09\xb0\xe2\x30\x58\x67\x13\x5c\x17\x57\x90\xe7\xcb\x89\x63\x4c\xe4\xf2\x62\x9b\x7d\x05\x00\x00\xff\xff\xcb\x4a\xd7\xe3\x7d\x01\x00\x00")
info := bindataFileInfo{name: "000010_blocks_created_by.down.sql", size: 2573, mode: os.FileMode(436), modTime: time.Unix(1625856521, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var __000010_blocks_created_byUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8e\x41\x4b\xc4\x30\x10\x85\xef\xfd\x15\x73\x6b\x0a\xb2\x20\x82\x97\x65\x0f\xb3\x49\x44\x21\x6e\x25\x4d\x05\x4f\x65\xb7\x9d\xb2\xc1\xc6\x48\x12\xd0\x52\xfa\xdf\xa5\x78\x11\xd4\xb2\x97\x39\xcc\x7b\xef\xe3\x43\x65\xa4\x06\x83\x7b\x25\x61\x9a\x36\xef\x81\x7a\xfb\x39\xcf\xa7\xc1\xb7\xaf\x11\x50\x08\xe0\xa5\xaa\x1f\x0f\xd0\x06\x3a\x26\xea\x9a\xd3\x08\xcf\xa8\xf9\x3d\x6a\x76\x73\x5b\x6c\xb3\x55\x40\x73\xb6\x31\xf9\x30\x5e\x02\xca\xea\x27\x81\xe6\x2f\x8b\x4a\x9a\x9f\xab\x1d\xf0\x12\x95\xac\xb8\x64\x87\x5a\xa9\x87\x3b\xc6\x22\x0d\xd4\x26\x70\xbe\xb3\xbd\xfd\x6e\xf5\xc1\xbb\x15\xa1\x8f\x33\x05\xfa\x3f\xdf\xd8\x0e\x76\xbf\xe3\xe5\x5d\x6a\x21\x35\xec\x5f\xd6\xc6\x6f\x91\x42\x6a\x8e\x09\xb0\xe2\x30\x58\x67\x13\x5c\x17\x57\x90\xe7\xcb\x89\x63\x4c\xe4\xf2\x62\x9b\x7d\x05\x00\x00\xff\xff\xcb\x4a\xd7\xe3\x7d\x01\x00\x00")
func _000010_blocks_created_byUpSqlBytes() ([]byte, error) {
return bindataRead(
__000010_blocks_created_byUpSql,
func _000010_blocks_created_by_up_sql() ([]byte, error) {
return bindata_read(
__000010_blocks_created_by_up_sql,
"000010_blocks_created_by.up.sql",
)
}
func _000010_blocks_created_byUpSql() (*asset, error) {
bytes, err := _000010_blocks_created_byUpSqlBytes()
if err != nil {
return nil, err
}
var __000011_match_collation_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x04\xc0\xb1\x0d\x85\x30\x0c\x04\xd0\x3e\x53\xdc\x02\x5e\xe5\x57\x7f\x81\x44\x1c\x89\x85\x75\x46\xc4\x0d\xdb\xf3\xcc\xf0\xcb\x5a\xae\x89\x4a\x0c\xe2\x48\x11\x8b\x0f\x9b\x19\xfe\xcb\x37\xee\x3e\x09\xdf\x70\x15\x55\x9e\xea\x11\x2f\x82\x67\x61\x44\xd7\xd5\xbe\x00\x00\x00\xff\xff\xeb\x41\x32\x0f\x44\x00\x00\x00")
info := bindataFileInfo{name: "000010_blocks_created_by.up.sql", size: 381, mode: os.FileMode(436), modTime: time.Unix(1625856521, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
func _000011_match_collation_down_sql() ([]byte, error) {
return bindata_read(
__000011_match_collation_down_sql,
"000011_match_collation.down.sql",
)
}
var __000011_match_collation_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x95\x4d\x6b\xdc\x30\x10\x86\xef\xfb\x2b\xe6\xe6\x5d\x68\x0c\x3d\x87\x85\x2a\x5a\x95\x1e\xdc\x38\xf5\xaa\xb4\x37\xa3\x78\xe5\xb5\x88\x3e\x5c\x8d\x4c\x6b\x8c\xff\x7b\xa9\x3f\xe2\x50\xf6\xe6\x42\x7d\x1d\xbd\xf3\xbc\x7a\xd0\x41\x5d\xa7\x4a\x10\xf6\x02\xb1\x69\xf1\x87\x86\xb8\xd6\xcd\x55\xd9\xbe\xdf\x01\x00\xdc\xdd\x41\xe1\xb4\x16\x41\x39\x0b\xae\x04\x23\x42\x90\xde\x38\x0c\x11\x02\xad\x84\xb5\x52\x23\x04\xf1\xac\xe5\x90\x3f\x33\x0e\x1f\x96\x10\x7d\xdd\x3d\xc2\xfe\xcc\x12\x46\xf9\x18\xce\x17\x6a\xe9\x9d\x01\x65\x4b\xe7\xcd\x30\xc8\xb1\xa8\xa4\x11\xf1\x90\x43\xf8\xf6\x89\x65\x6c\x5a\xb2\xc2\x48\x38\x42\x34\x17\x47\x40\x1e\x4f\xd3\xd9\xb8\xf5\xa6\xe7\x44\x38\x79\x20\x67\xb6\x3f\x1c\x0e\xf7\xbb\xd9\xe6\x59\xbb\xe2\x05\x97\xbb\x36\xf5\x45\x04\xf9\x7a\xcf\x2f\x8d\xf4\x2d\x1c\x81\xa6\x8f\x94\xf0\x7d\x44\x12\xce\x32\xe0\xe4\x21\x61\xd0\x75\x71\xed\x65\xa9\x7e\xf5\xfd\x48\x01\x9a\x26\x09\xe1\x0c\xa2\x77\x37\xa5\x0f\xf7\x43\xcf\x53\xc6\x9e\x48\xc6\x00\x83\x09\xf0\x31\x4b\x3f\xdf\x6e\x1d\xc3\xec\x3b\xa3\x5f\xf9\x18\x1e\x27\x27\x46\x92\x24\xa5\x7f\x7a\xde\x92\xfe\x56\x82\x4a\x61\x70\xbe\xfd\x37\x6a\xf9\x44\xdb\x88\x22\x4a\x44\xe5\xec\xea\x77\x9b\x39\x5b\xd1\xaa\x84\x57\xf6\xba\xda\x6a\xc4\x6c\x45\xaa\xc5\x20\x0d\xa0\x0c\x41\xd9\xeb\xfa\x27\x1b\x70\xf9\x8c\xdb\x88\x64\x83\xd2\xaf\x56\x1b\x20\x1b\x11\xfa\xe9\xfc\x0b\xd6\xa2\x90\xab\xad\x16\xd2\x7f\x56\xeb\x3a\xa9\x51\x4e\x1f\xd9\xf4\x29\xbc\x1f\xc6\xf6\xd2\xf7\xbb\xdf\x01\x00\x00\xff\xff\xf8\xa0\x61\xa4\xf9\x06\x00\x00")
func _000011_match_collation_up_sql() ([]byte, error) {
return bindata_read(
__000011_match_collation_up_sql,
"000011_match_collation.up.sql",
)
}
// Asset loads and returns the asset for the given name.
@ -502,41 +229,11 @@ func _000010_blocks_created_byUpSql() (*asset, error) {
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
}
return a.bytes, nil
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
a, err := Asset(name)
if err != nil {
panic("asset: Asset(" + name + "): " + err.Error())
}
return a
}
// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
}
return a.info, nil
}
return nil, fmt.Errorf("AssetInfo %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
@ -547,29 +244,30 @@ func AssetNames() []string {
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"000001_init.down.sql": _000001_initDownSql,
"000001_init.up.sql": _000001_initUpSql,
"000002_system_settings_table.down.sql": _000002_system_settings_tableDownSql,
"000002_system_settings_table.up.sql": _000002_system_settings_tableUpSql,
"000003_blocks_rootid.down.sql": _000003_blocks_rootidDownSql,
"000003_blocks_rootid.up.sql": _000003_blocks_rootidUpSql,
"000004_auth_table.down.sql": _000004_auth_tableDownSql,
"000004_auth_table.up.sql": _000004_auth_tableUpSql,
"000005_blocks_modifiedby.down.sql": _000005_blocks_modifiedbyDownSql,
"000005_blocks_modifiedby.up.sql": _000005_blocks_modifiedbyUpSql,
"000006_sharing_table.down.sql": _000006_sharing_tableDownSql,
"000006_sharing_table.up.sql": _000006_sharing_tableUpSql,
"000007_workspaces_table.down.sql": _000007_workspaces_tableDownSql,
"000007_workspaces_table.up.sql": _000007_workspaces_tableUpSql,
"000008_teams.down.sql": _000008_teamsDownSql,
"000008_teams.up.sql": _000008_teamsUpSql,
"000009_blocks_history.down.sql": _000009_blocks_historyDownSql,
"000009_blocks_history.up.sql": _000009_blocks_historyUpSql,
"000010_blocks_created_by.down.sql": _000010_blocks_created_byDownSql,
"000010_blocks_created_by.up.sql": _000010_blocks_created_byUpSql,
var _bindata = map[string]func() ([]byte, error){
"000001_init.down.sql": _000001_init_down_sql,
"000001_init.up.sql": _000001_init_up_sql,
"000002_system_settings_table.down.sql": _000002_system_settings_table_down_sql,
"000002_system_settings_table.up.sql": _000002_system_settings_table_up_sql,
"000003_blocks_rootid.down.sql": _000003_blocks_rootid_down_sql,
"000003_blocks_rootid.up.sql": _000003_blocks_rootid_up_sql,
"000004_auth_table.down.sql": _000004_auth_table_down_sql,
"000004_auth_table.up.sql": _000004_auth_table_up_sql,
"000005_blocks_modifiedby.down.sql": _000005_blocks_modifiedby_down_sql,
"000005_blocks_modifiedby.up.sql": _000005_blocks_modifiedby_up_sql,
"000006_sharing_table.down.sql": _000006_sharing_table_down_sql,
"000006_sharing_table.up.sql": _000006_sharing_table_up_sql,
"000007_workspaces_table.down.sql": _000007_workspaces_table_down_sql,
"000007_workspaces_table.up.sql": _000007_workspaces_table_up_sql,
"000008_teams.down.sql": _000008_teams_down_sql,
"000008_teams.up.sql": _000008_teams_up_sql,
"000009_blocks_history.down.sql": _000009_blocks_history_down_sql,
"000009_blocks_history.up.sql": _000009_blocks_history_up_sql,
"000010_blocks_created_by.down.sql": _000010_blocks_created_by_down_sql,
"000010_blocks_created_by.up.sql": _000010_blocks_created_by_up_sql,
"000011_match_collation.down.sql": _000011_match_collation_down_sql,
"000011_match_collation.up.sql": _000011_match_collation_up_sql,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
@ -599,83 +297,59 @@ func AssetDir(name string) ([]string, error) {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for childName := range node.Children {
rv = append(rv, childName)
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &bintree{nil, map[string]*bintree{
"000001_init.down.sql": &bintree{_000001_initDownSql, map[string]*bintree{}},
"000001_init.up.sql": &bintree{_000001_initUpSql, map[string]*bintree{}},
"000002_system_settings_table.down.sql": &bintree{_000002_system_settings_tableDownSql, map[string]*bintree{}},
"000002_system_settings_table.up.sql": &bintree{_000002_system_settings_tableUpSql, map[string]*bintree{}},
"000003_blocks_rootid.down.sql": &bintree{_000003_blocks_rootidDownSql, map[string]*bintree{}},
"000003_blocks_rootid.up.sql": &bintree{_000003_blocks_rootidUpSql, map[string]*bintree{}},
"000004_auth_table.down.sql": &bintree{_000004_auth_tableDownSql, map[string]*bintree{}},
"000004_auth_table.up.sql": &bintree{_000004_auth_tableUpSql, map[string]*bintree{}},
"000005_blocks_modifiedby.down.sql": &bintree{_000005_blocks_modifiedbyDownSql, map[string]*bintree{}},
"000005_blocks_modifiedby.up.sql": &bintree{_000005_blocks_modifiedbyUpSql, map[string]*bintree{}},
"000006_sharing_table.down.sql": &bintree{_000006_sharing_tableDownSql, map[string]*bintree{}},
"000006_sharing_table.up.sql": &bintree{_000006_sharing_tableUpSql, map[string]*bintree{}},
"000007_workspaces_table.down.sql": &bintree{_000007_workspaces_tableDownSql, map[string]*bintree{}},
"000007_workspaces_table.up.sql": &bintree{_000007_workspaces_tableUpSql, map[string]*bintree{}},
"000008_teams.down.sql": &bintree{_000008_teamsDownSql, map[string]*bintree{}},
"000008_teams.up.sql": &bintree{_000008_teamsUpSql, map[string]*bintree{}},
"000009_blocks_history.down.sql": &bintree{_000009_blocks_historyDownSql, map[string]*bintree{}},
"000009_blocks_history.up.sql": &bintree{_000009_blocks_historyUpSql, map[string]*bintree{}},
"000010_blocks_created_by.down.sql": &bintree{_000010_blocks_created_byDownSql, map[string]*bintree{}},
"000010_blocks_created_by.up.sql": &bintree{_000010_blocks_created_byUpSql, map[string]*bintree{}},
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"000001_init.down.sql": &_bintree_t{_000001_init_down_sql, map[string]*_bintree_t{
}},
"000001_init.up.sql": &_bintree_t{_000001_init_up_sql, map[string]*_bintree_t{
}},
"000002_system_settings_table.down.sql": &_bintree_t{_000002_system_settings_table_down_sql, map[string]*_bintree_t{
}},
"000002_system_settings_table.up.sql": &_bintree_t{_000002_system_settings_table_up_sql, map[string]*_bintree_t{
}},
"000003_blocks_rootid.down.sql": &_bintree_t{_000003_blocks_rootid_down_sql, map[string]*_bintree_t{
}},
"000003_blocks_rootid.up.sql": &_bintree_t{_000003_blocks_rootid_up_sql, map[string]*_bintree_t{
}},
"000004_auth_table.down.sql": &_bintree_t{_000004_auth_table_down_sql, map[string]*_bintree_t{
}},
"000004_auth_table.up.sql": &_bintree_t{_000004_auth_table_up_sql, map[string]*_bintree_t{
}},
"000005_blocks_modifiedby.down.sql": &_bintree_t{_000005_blocks_modifiedby_down_sql, map[string]*_bintree_t{
}},
"000005_blocks_modifiedby.up.sql": &_bintree_t{_000005_blocks_modifiedby_up_sql, map[string]*_bintree_t{
}},
"000006_sharing_table.down.sql": &_bintree_t{_000006_sharing_table_down_sql, map[string]*_bintree_t{
}},
"000006_sharing_table.up.sql": &_bintree_t{_000006_sharing_table_up_sql, map[string]*_bintree_t{
}},
"000007_workspaces_table.down.sql": &_bintree_t{_000007_workspaces_table_down_sql, map[string]*_bintree_t{
}},
"000007_workspaces_table.up.sql": &_bintree_t{_000007_workspaces_table_up_sql, map[string]*_bintree_t{
}},
"000008_teams.down.sql": &_bintree_t{_000008_teams_down_sql, map[string]*_bintree_t{
}},
"000008_teams.up.sql": &_bintree_t{_000008_teams_up_sql, map[string]*_bintree_t{
}},
"000009_blocks_history.down.sql": &_bintree_t{_000009_blocks_history_down_sql, map[string]*_bintree_t{
}},
"000009_blocks_history.up.sql": &_bintree_t{_000009_blocks_history_up_sql, map[string]*_bintree_t{
}},
"000010_blocks_created_by.down.sql": &_bintree_t{_000010_blocks_created_by_down_sql, map[string]*_bintree_t{
}},
"000010_blocks_created_by.up.sql": &_bintree_t{_000010_blocks_created_by_up_sql, map[string]*_bintree_t{
}},
"000011_match_collation.down.sql": &_bintree_t{_000011_match_collation_down_sql, map[string]*_bintree_t{
}},
"000011_match_collation.up.sql": &_bintree_t{_000011_match_collation_up_sql, map[string]*_bintree_t{
}},
}}
// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
data, err := Asset(name)
if err != nil {
return err
}
info, err := AssetInfo(name)
if err != nil {
return err
}
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
if err != nil {
return err
}
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
if err != nil {
return err
}
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
if err != nil {
return err
}
return nil
}
// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
children, err := AssetDir(name)
// File
if err != nil {
return RestoreAsset(dir, name)
}
// Dir
for _, child := range children {
err = RestoreAssets(dir, filepath.Join(name, child))
if err != nil {
return err
}
}
return nil
}
func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

View File

@ -12,4 +12,4 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}blocks (
update_at BIGINT,
delete_at BIGINT,
PRIMARY KEY (id, insert_at)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};

View File

@ -2,4 +2,4 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}system_settings (
id VARCHAR(100),
value TEXT,
PRIMARY KEY (id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};

View File

@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}users (
update_at BIGINT,
delete_at BIGINT,
PRIMARY KEY (id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
CREATE TABLE IF NOT EXISTS {{.prefix}}sessions (
id VARCHAR(100),
@ -21,4 +21,4 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}sessions (
create_at BIGINT,
update_at BIGINT,
PRIMARY KEY (id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};

View File

@ -5,4 +5,4 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}sharing (
modified_by VARCHAR(36),
update_at BIGINT,
PRIMARY KEY (id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};

View File

@ -5,4 +5,4 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}workspaces (
modified_by VARCHAR(36),
update_at BIGINT,
PRIMARY KEY (id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};

View File

@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}blocks (
modified_by VARCHAR(36),
workspace_id VARCHAR(36),
PRIMARY KEY (workspace_id,id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
{{if .mysql}}
INSERT IGNORE INTO {{.prefix}}blocks (SELECT * FROM {{.prefix}}blocks_history ORDER BY insert_at DESC);

View File

@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}blocks (
modified_by VARCHAR(36),
workspace_id VARCHAR(36),
PRIMARY KEY (workspace_id,id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
{{if .mysql}}
INSERT IGNORE INTO {{.prefix}}blocks (SELECT * FROM {{.prefix}}blocks_old ORDER BY insert_at DESC);
@ -49,7 +49,7 @@ CREATE TABLE IF NOT EXISTS {{.prefix}}blocks_history (
modified_by VARCHAR(36),
workspace_id VARCHAR(36),
PRIMARY KEY (workspace_id,id)
){{if .mysql}}CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci{{end}};
) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
{{if .mysql}}
INSERT IGNORE INTO {{.prefix}}blocks_history (SELECT * FROM {{.prefix}}blocks_history_old ORDER BY insert_at DESC);

View File

@ -0,0 +1,3 @@
-- Nothing to be done here
-- This page is intentionally left blank
SELECT 1;

View File

@ -0,0 +1,51 @@
{{if and .mysql .plugin}}
-- collation of mattermost's Channels table
SET @mattermostCollation = (SELECT table_collation from information_schema.tables WHERE table_name = 'Channels' AND table_schema = (SELECT DATABASE()));
-- blocks
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}blocks COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- blocks history
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}blocks_history COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- sessions
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}sessions COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- sharing
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}sharing COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- system settings
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}system_settings COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- users
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}users COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- workspaces
SET @updateCollationQuery = CONCAT('ALTER TABLE {{.prefix}}workspaces COLLATE ', @mattermostCollation);
PREPARE stmt FROM @updateCollationQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
{{else}}
-- We need a query here otherwise the migration will result
-- in an empty query when the if condition is false.
-- Empty query causes a "Query was empty" error.
SELECT 1;
{{end}}

View File

@ -20,11 +20,12 @@ type SQLStore struct {
dbType string
tablePrefix string
connectionString string
isPlugin bool
logger *mlog.Logger
}
// New creates a new SQL implementation of the store.
func New(dbType, connectionString, tablePrefix string, logger *mlog.Logger, db *sql.DB) (*SQLStore, error) {
func New(dbType, connectionString, tablePrefix string, logger *mlog.Logger, db *sql.DB, isPlugin bool) (*SQLStore, error) {
logger.Info("connectDatabase", mlog.String("dbType", dbType), mlog.String("connStr", connectionString))
store := &SQLStore{
// TODO: add replica DB support too.
@ -33,6 +34,7 @@ func New(dbType, connectionString, tablePrefix string, logger *mlog.Logger, db *
tablePrefix: tablePrefix,
connectionString: connectionString,
logger: logger,
isPlugin: isPlugin,
}
err := store.Migrate()

View File

@ -29,7 +29,7 @@ func SetupTests(t *testing.T) (store.Store, func()) {
require.NoError(t, err)
err = sqlDB.Ping()
require.NoError(t, err)
store, err := New(dbType, connectionString, "test_", logger, sqlDB)
store, err := New(dbType, connectionString, "test_", logger, sqlDB, false)
require.Nil(t, err)
tearDown := func() {

View File

@ -1,7 +1,10 @@
package sqlstore
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"time"
"github.com/mattermost/focalboard/server/model"
@ -12,6 +15,10 @@ import (
sq "github.com/Masterminds/squirrel"
)
var (
errUnsupportedDatabaseError = errors.New("method is unsupported on current database. Supported databases are - MySQL and PostgreSQL")
)
func (s *SQLStore) UpsertWorkspaceSignupToken(workspace model.Workspace) error {
now := time.Now().Unix()
@ -34,7 +41,7 @@ func (s *SQLStore) UpsertWorkspaceSignupToken(workspace model.Workspace) error {
workspace.SignupToken, workspace.ModifiedBy, now)
} else {
query = query.Suffix(
`ON CONFLICT (id)
`ON CONFLICT (id)
DO UPDATE SET signup_token = EXCLUDED.signup_token, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at`,
)
}
@ -72,7 +79,7 @@ func (s *SQLStore) UpsertWorkspaceSettings(workspace model.Workspace) error {
query = query.Suffix("ON DUPLICATE KEY UPDATE settings = ?, modified_by = ?, update_at = ?", settingsJSON, workspace.ModifiedBy, now)
} else {
query = query.Suffix(
`ON CONFLICT (id)
`ON CONFLICT (id)
DO UPDATE SET settings = EXCLUDED.settings, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at`,
)
}
@ -145,3 +152,57 @@ func (s *SQLStore) GetWorkspaceCount() (int64, error) {
}
return count, nil
}
func (s *SQLStore) GetUserWorkspaces(userID string) ([]model.UserWorkspace, error) {
var query sq.SelectBuilder
query = s.getQueryBuilder().
Select("Channels.ID", "Channels.DisplayName", "COUNT(focalboard_blocks.id)").
From("focalboard_blocks").
Join("ChannelMembers ON focalboard_blocks.workspace_id = ChannelMembers.ChannelId").
Join("Channels ON ChannelMembers.ChannelId = Channels.Id").
Where(sq.Eq{"ChannelMembers.UserId": userID}).
Where(sq.Eq{"focalboard_blocks.type": "board"}).
GroupBy("Channels.Id", "Channels.DisplayName")
switch s.dbType {
case mysqlDBType:
query = query.Where(sq.Like{"focalboard_blocks.fields": "%\"isTemplate\":false%"})
case postgresDBType:
query = query.Where("focalboard_blocks.fields ->> 'isTemplate' = 'false'")
default:
return nil, fmt.Errorf("GetUserWorkspaces - %w", errUnsupportedDatabaseError)
}
rows, err := query.Query()
if err != nil {
s.logger.Error("ERROR GetUserWorkspaces", mlog.Err(err))
return nil, err
}
defer s.CloseRows(rows)
return s.userWorkspacesFromRows(rows)
}
func (s *SQLStore) userWorkspacesFromRows(rows *sql.Rows) ([]model.UserWorkspace, error) {
userWorkspaces := []model.UserWorkspace{}
for rows.Next() {
var userWorkspace model.UserWorkspace
err := rows.Scan(
&userWorkspace.ID,
&userWorkspace.Title,
&userWorkspace.BoardCount,
)
if err != nil {
s.logger.Error("ERROR userWorkspacesFromRows", mlog.Err(err))
return nil, err
}
userWorkspaces = append(userWorkspaces, userWorkspace)
}
return userWorkspaces, nil
}

View File

@ -57,4 +57,5 @@ type Store interface {
GetWorkspace(ID string) (*model.Workspace, error)
HasWorkspaceAccess(userID string, workspaceID string) (bool, error)
GetWorkspaceCount() (int64, error)
GetUserWorkspaces(userID string) ([]model.UserWorkspace, error)
}

View File

@ -31,12 +31,16 @@ describe('Create and delete board / card', () => {
should('have.value', boardTitle);
});
it('Can hide and show the sidebar with active board', () => {
// Hide and show the sidebar
cy.get('.Sidebar .heading ~ .Button').click();
it('Can hide and show the sidebar with active board', async () => {
// Hide and show the sidebar option available on mobile devices
cy.viewport(767, 1024);
cy.get('.sidebarSwitcher').click();
cy.get('.Sidebar .heading').should('not.exist');
cy.get('.Sidebar .show-button').click();
cy.get('.Sidebar .heading').should('exist');
cy.viewport(1024, 1024);
cy.get('.sidebarSwitcher').should('not.exist');
});
it('Can rename the board view', () => {

View File

@ -110,6 +110,7 @@
"Sidebar.untitled": "Untitled",
"Sidebar.untitled-board": "(Untitled Board)",
"Sidebar.untitled-view": "(Untitled View)",
"Sidebar.no-more-workspaces": "No more workspaces",
"TableComponent.add-icon": "Add icon",
"TableComponent.name": "Name",
"TableComponent.plus-new": "+ New",
@ -164,4 +165,4 @@
"login.register-button": "or create an account if you don't have one",
"register.login-button": "or login if you already have an account",
"register.signup-title": "Sign up for your account"
}
}

View File

@ -13,6 +13,8 @@ import './dialog.scss'
type Props = {
children: React.ReactNode
toolsMenu: React.ReactNode
hideCloseButton?: boolean
className?: string
onClose: () => void,
}
@ -28,7 +30,7 @@ const Dialog = React.memo((props: Props) => {
useHotkeys('esc', () => props.onClose())
return (
<div className='Dialog dialog-back'>
<div className={`Dialog dialog-back ${props.className}`}>
<div
className='wrapper'
onMouseDown={(e) => {
@ -39,12 +41,15 @@ const Dialog = React.memo((props: Props) => {
>
<div className='dialog' >
<div className='toolbar'>
<IconButton
onClick={props.onClose}
icon={<CloseIcon/>}
title={closeDialogText}
className='IconButton--large'
/>
{
!props.hideCloseButton &&
<IconButton
onClick={props.onClose}
icon={<CloseIcon/>}
title={closeDialogText}
className='IconButton--large'
/>
}
<div className='octo-spacer'/>
{toolsMenu && <MenuWrapper>
<IconButton

View File

@ -3,12 +3,12 @@
import React from 'react'
import {FormattedMessage} from 'react-intl'
import {getWorkspace} from '../store/workspace'
import {getCurrentWorkspace} from '../store/workspace'
import {useAppSelector} from '../store/hooks'
import './emptyCenterPanel.scss'
const EmptyCenterPanel = React.memo(() => {
const workspace = useAppSelector(getWorkspace)
const workspace = useAppSelector(getCurrentWorkspace)
return (
<div className='EmptyCenterPanel'>

View File

@ -8,7 +8,7 @@ import {sendFlashMessage} from '../../components/flashMessages'
import client from '../../octoClient'
import {Utils} from '../../utils'
import Button from '../../widgets/buttons/button'
import {getWorkspace, fetchWorkspace} from '../../store/workspace'
import {getCurrentWorkspace, fetchWorkspace} from '../../store/workspace'
import {useAppSelector, useAppDispatch} from '../../store/hooks'
import Modal from '../modal'
@ -22,7 +22,7 @@ type Props = {
const RegistrationLink = React.memo((props: Props) => {
const {onClose} = props
const intl = useIntl()
const workspace = useAppSelector<IWorkspace|null>(getWorkspace)
const workspace = useAppSelector<IWorkspace|null>(getCurrentWorkspace)
const dispatch = useAppDispatch()
const [wasCopied, setWasCopied] = useState(false)

View File

@ -127,4 +127,10 @@
stroke: rgba(var(--sidebar-text-rgb), 0.5);
stroke-width: 6px;
}
@media screen and (min-width: 768px) {
.sidebarSwitcher {
display: none;
}
}
}

View File

@ -9,12 +9,14 @@ import HideSidebarIcon from '../../widgets/icons/hideSidebar'
import ShowSidebarIcon from '../../widgets/icons/showSidebar'
import {getSortedBoards} from '../../store/boards'
import {getSortedViews} from '../../store/views'
import {getWorkspace} from '../../store/workspace'
import {getCurrentWorkspace} from '../../store/workspace'
import {useAppSelector} from '../../store/hooks'
import {Utils} from '../../utils'
import './sidebar.scss'
import WorkspaceSwitcher from '../workspaceSwitcher/workspaceSwitcher'
import SidebarAddBoardMenu from './sidebarAddBoardMenu'
import SidebarBoardItem from './sidebarBoardItem'
import SidebarSettingsMenu from './sidebarSettingsMenu'
@ -34,7 +36,7 @@ const Sidebar = React.memo((props: Props) => {
loadTheme()
}, [])
const workspace = useAppSelector(getWorkspace)
const workspace = useAppSelector(getCurrentWorkspace)
if (!boards) {
return <div/>
}
@ -69,21 +71,26 @@ const Sidebar = React.memo((props: Props) => {
</div>
<div className='octo-spacer'/>
<IconButton
onClick={() => setHidden(true)}
icon={<HideSidebarIcon/>}
/>
</div>}
{workspace && workspace.id !== '0' &&
<div className='WorkspaceTitle'>
{workspace.title}
{Utils.isFocalboardPlugin() &&
<>
<div className='octo-spacer'/>
<div className='sidebarSwitcher'>
<IconButton
onClick={() => setHidden(true)}
icon={<HideSidebarIcon/>}
/>
</div>
</div>}
{workspace && workspace.id !== '0' &&
<div className='WorkspaceTitle'>
<WorkspaceSwitcher activeWorkspace={workspace}/>
{Utils.isFocalboardPlugin() &&
<>
<div className='octo-spacer'/>
<div className='sidebarSwitcher'>
<IconButton
onClick={() => setHidden(true)}
icon={<HideSidebarIcon/>}
/>
</div>
</>
}
</div>

View File

@ -0,0 +1,194 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/workspaceSwitcher/WorkspaceOptions 2 more workspaces available 1`] = `
<div>
<div
class="WorkspaceOptions css-2b097c-container"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
>
<span
id="aria-selection"
/>
<span
id="aria-context"
>
2 results available. Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu.
</span>
</span>
<div
class="WorkspaceOptions__control WorkspaceOptions__control--is-focused WorkspaceOptions__control--menu-is-open css-1pahdxg-control"
>
<div
class="WorkspaceOptions__value-container css-g1d714-ValueContainer"
>
<div
class="WorkspaceOptions__placeholder css-1wa3eu0-placeholder"
>
Search...
</div>
<div
class="css-b8ldur-Input"
>
<div
class="WorkspaceOptions__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-2-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="WorkspaceOptions__indicators css-1hb7zxy-IndicatorsContainer"
>
<i
class="CompassIcon icon-magnify CompassIcon"
/>
</div>
</div>
<div
class="WorkspaceOptions__menu css-26l3qy-menu"
>
<div
class="WorkspaceOptions__menu-list css-4ljt47-MenuList"
>
<div
class="Option "
id="react-select-2-option-0"
tabindex="-1"
>
<div
class="workspaceTitle"
>
Workspace 2
</div>
<div
class="boardCount"
>
2
Boards
</div>
</div>
<div
class="Option "
id="react-select-2-option-1"
tabindex="-1"
>
<div
class="workspaceTitle"
>
Workspace 3
</div>
<div
class="boardCount"
>
3
Boards
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`components/workspaceSwitcher/WorkspaceOptions no more workspaces available 1`] = `
<div>
<div
class="WorkspaceOptions css-2b097c-container"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
>
<span
id="aria-selection"
/>
<span
id="aria-context"
>
Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu.
</span>
</span>
<div
class="WorkspaceOptions__control WorkspaceOptions__control--is-focused WorkspaceOptions__control--menu-is-open css-1pahdxg-control"
>
<div
class="WorkspaceOptions__value-container css-g1d714-ValueContainer"
>
<div
class="WorkspaceOptions__placeholder css-1wa3eu0-placeholder"
>
Search...
</div>
<div
class="css-b8ldur-Input"
>
<div
class="WorkspaceOptions__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-3-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="WorkspaceOptions__indicators css-1hb7zxy-IndicatorsContainer"
>
<i
class="CompassIcon icon-magnify CompassIcon"
/>
</div>
</div>
<div
class="WorkspaceOptions__menu css-26l3qy-menu"
>
<div
class="WorkspaceOptions__menu-list css-4ljt47-MenuList"
>
<div
class="WorkspaceOptions__menu-notice WorkspaceOptions__menu-notice--no-options css-gg45go-NoOptionsMessage"
>
No more workspaces
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,194 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/workspaceSwitcher/WorkspaceSwitcher 2 more workspaces available 1`] = `
<div>
<div
class="WorkspaceOptions css-2b097c-container"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
>
<span
id="aria-selection"
/>
<span
id="aria-context"
>
2 results available. Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu.
</span>
</span>
<div
class="WorkspaceOptions__control WorkspaceOptions__control--is-focused WorkspaceOptions__control--menu-is-open css-1pahdxg-control"
>
<div
class="WorkspaceOptions__value-container css-g1d714-ValueContainer"
>
<div
class="WorkspaceOptions__placeholder css-1wa3eu0-placeholder"
>
Search...
</div>
<div
class="css-b8ldur-Input"
>
<div
class="WorkspaceOptions__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-2-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="WorkspaceOptions__indicators css-1hb7zxy-IndicatorsContainer"
>
<i
class="CompassIcon icon-magnify CompassIcon"
/>
</div>
</div>
<div
class="WorkspaceOptions__menu css-26l3qy-menu"
>
<div
class="WorkspaceOptions__menu-list css-4ljt47-MenuList"
>
<div
class="Option "
id="react-select-2-option-0"
tabindex="-1"
>
<div
class="workspaceTitle"
>
Workspace 2
</div>
<div
class="boardCount"
>
2
Boards
</div>
</div>
<div
class="Option "
id="react-select-2-option-1"
tabindex="-1"
>
<div
class="workspaceTitle"
>
Workspace 3
</div>
<div
class="boardCount"
>
3
Boards
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`components/workspaceSwitcher/WorkspaceSwitcher no more workspaces available 1`] = `
<div>
<div
class="WorkspaceOptions css-2b097c-container"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
>
<span
id="aria-selection"
/>
<span
id="aria-context"
>
Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu.
</span>
</span>
<div
class="WorkspaceOptions__control WorkspaceOptions__control--is-focused WorkspaceOptions__control--menu-is-open css-1pahdxg-control"
>
<div
class="WorkspaceOptions__value-container css-g1d714-ValueContainer"
>
<div
class="WorkspaceOptions__placeholder css-1wa3eu0-placeholder"
>
Search...
</div>
<div
class="css-b8ldur-Input"
>
<div
class="WorkspaceOptions__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-3-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="WorkspaceOptions__indicators css-1hb7zxy-IndicatorsContainer"
>
<i
class="CompassIcon icon-magnify CompassIcon"
/>
</div>
</div>
<div
class="WorkspaceOptions__menu css-26l3qy-menu"
>
<div
class="WorkspaceOptions__menu-list css-4ljt47-MenuList"
>
<div
class="WorkspaceOptions__menu-notice WorkspaceOptions__menu-notice--no-options css-gg45go-NoOptionsMessage"
>
No more workspaces
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,97 @@
.Option {
padding: 0 20px;
display: flex;
flex-direction: column;
cursor: pointer;
&:first-child {
margin-top: 8px;
}
&:last-child {
margin-bottom: 8px;
}
&.focused {
background-color: rgba(var(--button-bg-rgb), 0.08);
}
.workspaceTitle {
color: rgb(var(--center-channel-color-rgb));
font-size: 14px;
}
.boardCount {
color: rgba(var(--center-channel-color-rgb), 0.56);
font-size: 12px;
}
}
.WorkspaceOptions {
font-weight: 400;
&__menu-list {
padding-bottom: 0 !important;
> div {
height: 56px;
display: flex;
justify-content: center;
&.focused {
background: rgba(var(--center-channel-color-rgb), 0.08);
}
}
}
&__placeholder {
color: rgba(var(--center-channel-color-rgb), 0.64);
}
&__indicators {
color: rgba(var(--center-channel-color-rgb), 0.64);
font-size: 18px;
}
&__value-container {
padding: 6px 2px !important;
}
&__control {
flex-direction: row-reverse;
box-shadow: 0 0 0 1px rgba(var(--center-channel-color-rgb), 0.16);
padding: 0 12px;
border: 0 !important;
&--is-focused {
box-shadow: 0 0 0 2px rgba(var(--button-bg-rgb)) !important;
}
}
&__menu {
position: relative !important;
margin-top: 0 !important;
box-shadow: none !important;
border: 0 !important;
margin: 0 -16px;
width: auto !important;
margin-bottom: 0 !important;
}
&__input {
color: rgb(var(--center-channel-color-rgb)) !important;
}
&__control,
&__menu {
background-color: transparent !important;
}
&__value-container {
cursor: text !important;
}
&__indicators {
cursor: pointer !important;
}
}

View File

@ -0,0 +1,84 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import configureStore from 'redux-mock-store'
import {IntlProvider} from 'react-intl'
import {Provider as ReduxProvider} from 'react-redux'
import {render} from '@testing-library/react'
import {UserWorkspace} from '../../user'
import WorkspaceOptions from './workspaceOptions'
const wrapProviders = (children: any) => {
return (
<IntlProvider locale='en'>{children}</IntlProvider>
)
}
describe('components/workspaceSwitcher/WorkspaceOptions', () => {
const mockStore = configureStore([])
const workspace1: UserWorkspace = {
id: 'workspace_1',
title: 'Workspace 1',
boardCount: 1,
}
const workspace2: UserWorkspace = {
id: 'workspace_2',
title: 'Workspace 2',
boardCount: 2,
}
const workspace3: UserWorkspace = {
id: 'workspace_3',
title: 'Workspace 3',
boardCount: 3,
}
test('2 more workspaces available', () => {
const store = mockStore({
workspace: {
userWorkspaces: new Array<UserWorkspace>(workspace1, workspace2, workspace3),
},
})
const component = wrapProviders(
<ReduxProvider store={store}>
<WorkspaceOptions
onChange={() => {
}}
activeWorkspaceId={workspace1.id}
/>
</ReduxProvider>,
)
const {container} = render(component)
expect(container).toMatchSnapshot()
})
test('no more workspaces available', () => {
const store = mockStore({
workspace: {
userWorkspaces: [],
},
})
const component = wrapProviders(
<ReduxProvider store={store}>
<WorkspaceOptions
onChange={() => {
}}
activeWorkspaceId={workspace1.id}
/>
</ReduxProvider>,
)
const {container} = render(component)
expect(container).toMatchSnapshot()
})
})

View File

@ -0,0 +1,87 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import Select from 'react-select'
import {useIntl} from 'react-intl'
import {UserWorkspace} from '../../user'
import {useAppSelector} from '../../store/hooks'
import './workspaceOptions.scss'
import Search from '../../widgets/icons/search'
import {getUserWorkspaceList} from '../../store/workspace'
type Props = {
onBlur?: () => void
onChange: (value: string) => void
activeWorkspaceId: string
}
const WorkspaceOptions = (props: Props): JSX.Element => {
const intl = useIntl()
const userWorkspaces = useAppSelector<UserWorkspace[]>(getUserWorkspaceList)
const options = userWorkspaces.filter((workspace) => workspace.id !== props.activeWorkspaceId).map((workspace) => {
return {
label: workspace.title,
value: workspace.id,
boardCount: workspace.boardCount,
}
})
return (
<Select
className='WorkspaceOptions'
classNamePrefix='WorkspaceOptions'
autoFocus={true}
backspaceRemovesValue={false}
controlShouldRenderValue={false}
hideSelectedOptions={false}
isClearable={false}
placeholder={'Search...'}
tabSelectsValue={false}
options={options}
menuIsOpen={true}
noOptionsMessage={() => intl.formatMessage({
id: 'Sidebar.no-more-workspaces',
defaultMessage: 'No more workspaces',
})}
onBlur={() => {
if (props.onBlur) {
props.onBlur()
}
}}
components={{
DropdownIndicator: Search,
IndicatorSeparator: null,
Option,
}}
onChange={(item) => {
if (item?.value) {
props.onChange(item.value)
}
}}
/>
)
}
const Option = (props: any): JSX.Element => {
const {innerProps, innerRef} = props
return (
<div
ref={innerRef}
{...innerProps}
className={`Option ${props.isFocused ? 'focused' : ''}`}
>
<div className='workspaceTitle'>
{props.data.label}
</div>
<div className='boardCount'>
{props.data.boardCount} {props.data.boardCount > 1 ? 'Boards' : 'Board'}
</div>
</div>
)
}
export default WorkspaceOptions

View File

@ -0,0 +1,35 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
.WorkspaceSwitcherWrapper {
display: flex;
flex-direction: column;
gap: 4px;
width: 100%;
position: relative;
> div:nth-child(2) {
position: absolute;
width: 280px;
top: calc(100% + 8px);
z-index: 10;
padding: 12px 16px 0;
background: rgb(var(--center-channel-bg-rgb));
border-radius: 4px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
}
.WorkspaceSwitcher {
display: flex;
flex-direction: row;
background: var(--global-header-background);
border-radius: 8px;
padding: 10px 16px;
cursor: pointer;
.icon-chevron-down {
margin-left: auto;
font-size: 18px;
}
}

View File

@ -0,0 +1,82 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import configureStore from 'redux-mock-store'
import {Provider as ReduxProvider} from 'react-redux'
import {render} from '@testing-library/react'
import {IntlProvider} from 'react-intl'
import {UserWorkspace} from '../../user'
import WorkspaceOptions from './workspaceOptions'
const wrapProviders = (children: any) => {
return (
<IntlProvider locale='en'>{children}</IntlProvider>
)
}
describe('components/workspaceSwitcher/WorkspaceSwitcher', () => {
const mockStore = configureStore([])
const workspace1: UserWorkspace = {
id: 'workspace_1',
title: 'Workspace 1',
boardCount: 1,
}
const workspace2: UserWorkspace = {
id: 'workspace_2',
title: 'Workspace 2',
boardCount: 2,
}
const workspace3: UserWorkspace = {
id: 'workspace_3',
title: 'Workspace 3',
boardCount: 3,
}
test('2 more workspaces available', () => {
const store = mockStore({
workspace: {
userWorkspaces: new Array<UserWorkspace>(workspace1, workspace2, workspace3),
},
})
const component = wrapProviders(
<ReduxProvider store={store}>
<WorkspaceOptions
onChange={() => {}}
activeWorkspaceId={workspace1.id}
/>
</ReduxProvider>,
)
const {container} = render(component)
expect(container).toMatchSnapshot()
})
test('no more workspaces available', () => {
const store = mockStore({
workspace: {
userWorkspaces: [],
},
})
const component = wrapProviders(
<ReduxProvider store={store}>
<WorkspaceOptions
onChange={() => {}}
activeWorkspaceId={workspace1.id}
/>
</ReduxProvider>,
)
const {container} = render(component)
expect(container).toMatchSnapshot()
})
})

View File

@ -0,0 +1,54 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useState} from 'react'
import './workspaceSwitcher.scss'
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
import {IWorkspace} from '../../blocks/workspace'
import ChevronDown from '../../widgets/icons/chevronDown'
import WorkspaceOptions from './workspaceOptions'
type Props = {
activeWorkspace: IWorkspace
}
const WorkspaceSwitcher = (props: Props): JSX.Element => {
const history = useHistory()
const match = useRouteMatch()
const [showMenu, setShowMenu] = useState<boolean>(false)
return (
<div className={'WorkspaceSwitcherWrapper'}>
<div
className='WorkspaceSwitcher'
onClick={() => {
if (!showMenu) {
setShowMenu(true)
}
}}
>
<span>{props.activeWorkspace.title}</span>
<ChevronDown/>
</div>
{
showMenu &&
<WorkspaceOptions
activeWorkspaceId={props.activeWorkspace.id}
onBlur={() => {
setShowMenu(false)
}}
onChange={(workspaceId: string) => {
setShowMenu(false)
const newPath = generatePath(match.path, {workspaceId})
history.replace(newPath)
}}
/>
}
</div>
)
}
export default WorkspaceSwitcher

View File

@ -4,7 +4,7 @@ import {Block, BlockPatch} from './blocks/block'
import {ISharing} from './blocks/sharing'
import {IWorkspace} from './blocks/workspace'
import {OctoUtils} from './octoUtils'
import {IUser} from './user'
import {IUser, UserWorkspace} from './user'
import {Utils} from './utils'
import {ClientConfig} from './config/clientConfig'
@ -415,6 +415,16 @@ class OctoClient {
}
return (await this.getJson(response, [])) as IUser[]
}
async getUserWorkspaces(): Promise<UserWorkspace[]> {
const path = '/api/v1/workspaces'
const response = await fetch(this.getBaseURL() + path, {headers: this.headers()})
if (response.status !== 200) {
return []
}
return (await this.getJson(response, [])) as UserWorkspace[]
}
}
const octoClient = new OctoClient()

View File

@ -15,3 +15,8 @@
background-color: rgba(230, 192, 192, 0.9);
}
}
.Dialog.dialog-back.workspaceSwitcherModal > div > .dialog {
width: 600px;
height: 468px;
}

View File

@ -4,14 +4,23 @@
import {createAsyncThunk} from '@reduxjs/toolkit'
import {default as client} from '../octoClient'
import {UserWorkspace} from '../user'
import {Utils} from '../utils'
const getUserWorkspaces = async ():Promise<UserWorkspace[]> => {
// Concept of workspaces is only applicable when running as a plugin.
// There is always only one, single workspace in personal server edition.
return Utils.isFocalboardPlugin() ? client.getUserWorkspaces() : []
}
export const initialLoad = createAsyncThunk(
'initialLoad',
async () => {
const [workspace, workspaceUsers, blocks] = await Promise.all([
const [workspace, workspaceUsers, blocks, userWorkspaces] = await Promise.all([
client.getWorkspace(),
client.getWorkspaceUsers(),
client.getAllBlocks(),
getUserWorkspaces(),
])
if (!workspace) {
throw new Error('no_workspace')
@ -20,6 +29,7 @@ export const initialLoad = createAsyncThunk(
workspace,
workspaceUsers,
blocks,
userWorkspaces,
}
},
)

View File

@ -23,7 +23,7 @@ type UsersStatus = {
const usersSlice = createSlice({
name: 'users',
initialState: {me: null, workspaceUsers: {}, loggedIn: null} as UsersStatus,
initialState: {me: null, workspaceUsers: {}, loggedIn: null, userWorkspaces: []} as UsersStatus,
reducers: {
setMe: (state, action: PayloadAction<IUser>) => {
state.me = action.payload

View File

@ -1,11 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {createSlice, createAsyncThunk, PayloadAction} from '@reduxjs/toolkit'
import {createSlice, createAsyncThunk, PayloadAction, createSelector} from '@reduxjs/toolkit'
import {default as client} from '../octoClient'
import {IWorkspace} from '../blocks/workspace'
import {UserWorkspace} from '../user'
import {initialLoad} from './initialLoad'
import {RootState} from './index'
@ -15,20 +17,26 @@ export const fetchWorkspace = createAsyncThunk(
async () => client.getWorkspace(),
)
type WorkspaceState = {
current: IWorkspace|null
userWorkspaces: UserWorkspace[]
}
const workspaceSlice = createSlice({
name: 'workspace',
initialState: {value: null} as {value: IWorkspace|null},
initialState: {current: null} as WorkspaceState,
reducers: {
setWorkspace: (state, action: PayloadAction<IWorkspace>) => {
state.value = action.payload
state.current = action.payload
},
},
extraReducers: (builder) => {
builder.addCase(initialLoad.fulfilled, (state, action) => {
state.value = action.payload.workspace || null
state.current = action.payload.workspace || null
state.userWorkspaces = action.payload.userWorkspaces
})
builder.addCase(fetchWorkspace.fulfilled, (state, action) => {
state.value = action.payload || null
state.current = action.payload || null
})
},
})
@ -36,6 +44,13 @@ const workspaceSlice = createSlice({
export const {setWorkspace} = workspaceSlice.actions
export const {reducer} = workspaceSlice
export function getWorkspace(state: RootState): IWorkspace|null {
return state.workspace.value
export const getUserWorkspaces = (state: RootState): UserWorkspace[] => state.workspace.userWorkspaces
export const getUserWorkspaceList = createSelector(
getUserWorkspaces,
(userWorkspaces) => userWorkspaces,
)
export function getCurrentWorkspace(state: RootState): IWorkspace|null {
return state.workspace.current
}

View File

@ -10,4 +10,10 @@ interface IUser {
updateAt: number,
}
export {IUser}
interface UserWorkspace {
id: string
title: string
boardCount: number
}
export {IUser, UserWorkspace}

View File

@ -0,0 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import CompassIcon from './compassIcon'
export default function ChevronDown(): JSX.Element {
return (
<CompassIcon
icon='chevron-down'
className='ChevronDownIcon'
/>
)
}

View File

@ -0,0 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import CompassIcon from './compassIcon'
export default function Search(): JSX.Element {
return (
<CompassIcon
icon='magnify'
className='CompassIcon'
/>
)
}

View File

@ -195,6 +195,15 @@ nano /opt/focalboard/config.json
Change the dbconfig setting to use the MySQL database you created:
When MySQL is being used, using collation is recommended over using charset.
Using a variant of `utf8mb4` collation is required. For example, `utf8mb4_general_ci`
is used by default when no collation is specified.
If you're using Focalboard as a Mattermost Plugin prior to version 0.9 with MySQL,
please ensure the collations of focalboard tables (tables with the prefix `focalboard_`)
is the same as the collation of mattermost tables.
```
"dbtype": "mysql",
"dbconfig": "boardsuser:boardsuser-password@tcp(127.0.0.1:3306)/boards",