Add rootId to blocks. Requires archive export / re-import.
This commit is contained in:
parent
b9b1020748
commit
850f60e1fb
|
@ -238,7 +238,7 @@ func (a *API) handleImport(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err = a.app().InsertBlocks(blocks)
|
||||
if err != nil {
|
||||
log.Printf(`ERROR: %v`, r)
|
||||
log.Printf(`ERROR: %v`, err)
|
||||
errorResponse(w, http.StatusInternalServerError, nil)
|
||||
|
||||
return
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
type Block struct {
|
||||
ID string `json:"id"`
|
||||
ParentID string `json:"parentId"`
|
||||
RootID string `json:"rootId"`
|
||||
Schema int64 `json:"schema"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
|
|
|
@ -3,6 +3,7 @@ package sqlstore
|
|||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
|
@ -23,7 +24,7 @@ func (s *SQLStore) latestsBlocksSubquery() sq.SelectBuilder {
|
|||
|
||||
func (s *SQLStore) GetBlocksWithParentAndType(parentID string, blockType string) ([]model.Block, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("id", "parent_id", "schema", "type", "title",
|
||||
Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "latest").
|
||||
|
@ -42,7 +43,7 @@ func (s *SQLStore) GetBlocksWithParentAndType(parentID string, blockType string)
|
|||
|
||||
func (s *SQLStore) GetBlocksWithParent(parentID string) ([]model.Block, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("id", "parent_id", "schema", "type", "title",
|
||||
Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "latest").
|
||||
|
@ -60,7 +61,7 @@ func (s *SQLStore) GetBlocksWithParent(parentID string) ([]model.Block, error) {
|
|||
|
||||
func (s *SQLStore) GetBlocksWithType(blockType string) ([]model.Block, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("id", "parent_id", "schema", "type", "title",
|
||||
Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "latest").
|
||||
|
@ -79,7 +80,7 @@ func (s *SQLStore) GetBlocksWithType(blockType string) ([]model.Block, error) {
|
|||
// GetSubTree2 returns blocks within 2 levels of the given blockID
|
||||
func (s *SQLStore) GetSubTree2(blockID string) ([]model.Block, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("id", "parent_id", "schema", "type", "title",
|
||||
Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "latest").
|
||||
|
@ -98,7 +99,7 @@ func (s *SQLStore) GetSubTree2(blockID string) ([]model.Block, error) {
|
|||
// GetSubTree3 returns blocks within 3 levels of the given blockID
|
||||
func (s *SQLStore) GetSubTree3(blockID string) ([]model.Block, error) {
|
||||
// This first subquery returns repeated blocks
|
||||
subquery1 := sq.Select("l3.id", "l3.parent_id", "l3.schema", "l3.type", "l3.title",
|
||||
subquery1 := sq.Select("l3.id", "l3.parent_id", "l3.root_id", "l3.schema", "l3.type", "l3.title",
|
||||
"l3.fields", "l3.create_at", "l3.update_at",
|
||||
"l3.delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "l1").
|
||||
|
@ -111,7 +112,7 @@ func (s *SQLStore) GetSubTree3(blockID string) ([]model.Block, error) {
|
|||
subquery2 := sq.Select("*", "ROW_NUMBER() OVER (PARTITION BY id) AS rn").
|
||||
FromSelect(subquery1, "sub1")
|
||||
|
||||
query := s.getQueryBuilder().Select("id", "parent_id", "schema", "type", "title",
|
||||
query := s.getQueryBuilder().Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(subquery2, "sub2").
|
||||
|
@ -129,7 +130,7 @@ func (s *SQLStore) GetSubTree3(blockID string) ([]model.Block, error) {
|
|||
|
||||
func (s *SQLStore) GetAllBlocks() ([]model.Block, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("id", "parent_id", "schema", "type", "title",
|
||||
Select("id", "parent_id", "root_id", "schema", "type", "title",
|
||||
"COALESCE(\"fields\", '{}')", "create_at", "update_at",
|
||||
"delete_at").
|
||||
FromSelect(s.latestsBlocksSubquery(), "latest")
|
||||
|
@ -156,6 +157,7 @@ func blocksFromRows(rows *sql.Rows) ([]model.Block, error) {
|
|||
err := rows.Scan(
|
||||
&block.ID,
|
||||
&block.ParentID,
|
||||
&block.RootID,
|
||||
&block.Schema,
|
||||
&block.Type,
|
||||
&block.Title,
|
||||
|
@ -202,14 +204,18 @@ func (s *SQLStore) GetParentID(blockID string) (string, error) {
|
|||
}
|
||||
|
||||
func (s *SQLStore) InsertBlock(block model.Block) error {
|
||||
if block.RootID == "" {
|
||||
return errors.New("rootId is nil")
|
||||
}
|
||||
|
||||
fieldsJSON, err := json.Marshal(block.Fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := s.getQueryBuilder().Insert("blocks").
|
||||
Columns("id", "parent_id", "schema", "type", "title", "fields", "create_at", "update_at", "delete_at").
|
||||
Values(block.ID, block.ParentID, block.Schema, block.Type, block.Title,
|
||||
Columns("id", "parent_id", "root_id", "schema", "type", "title", "fields", "create_at", "update_at", "delete_at").
|
||||
Values(block.ID, block.ParentID, block.RootID, block.Schema, block.Type, block.Title,
|
||||
fieldsJSON, block.CreateAt, block.UpdateAt, block.DeleteAt)
|
||||
|
||||
_, err = query.Exec()
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
// Code generated by go-bindata. DO NOT EDIT.
|
||||
// sources:
|
||||
// postgres_files/000001_init.down.sql
|
||||
// postgres_files/000001_init.up.sql
|
||||
// postgres_files/000002_system_settings_table.down.sql
|
||||
// postgres_files/000002_system_settings_table.up.sql
|
||||
// postgres_files/000003_blocks_rootid.down.sql
|
||||
// postgres_files/000003_blocks_rootid.up.sql
|
||||
package postgres
|
||||
|
||||
import (
|
||||
|
@ -5,10 +13,14 @@ import (
|
|||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindata_read(data []byte, name string) ([]byte, error) {
|
||||
func bindataRead(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)
|
||||
|
@ -16,62 +28,210 @@ func bindata_read(data []byte, name string) ([]byte, error) {
|
|||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, gz)
|
||||
gz.Close()
|
||||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
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\x48\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x45\xbe\x01\x0f\x13\x00\x00\x00")
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
func _000001_init_down_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000001_init_down_sql,
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
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\x48\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x45\xbe\x01\x0f\x13\x00\x00\x00")
|
||||
|
||||
func _000001_initDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000001_initDownSql,
|
||||
"000001_init.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
var __000001_init_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8f\x31\x4f\xc3\x30\x10\x85\xe7\xf8\x57\xbc\x31\x91\xb2\x21\xb1\x30\xb9\xe5\x0a\x86\xc4\xa9\x9c\x2b\xb4\x2c\x55\x88\x0f\x61\x11\x4a\x14\x9b\x81\x7f\x8f\xda\x21\x43\xba\xdd\x7d\xba\xef\x9e\xde\xda\x91\x66\x02\xeb\x55\x45\x30\x1b\xd8\x86\x41\x7b\xd3\x72\x8b\xf7\xe1\xa7\xff\x8a\xc8\x55\x16\x3c\x5e\xb4\x5b\x3f\x6a\x97\xdf\xdc\x16\xa5\xca\xc2\x29\xca\x94\x8e\x5d\x02\x9b\x9a\x5a\xd6\xf5\x96\xdf\x2e\xae\xdd\x55\x15\xee\x69\xa3\x77\x15\xc3\x36\xaf\xf9\xf9\x7c\xec\x26\x39\xa5\xe3\xd5\x9b\xd8\x7f\xca\x77\x87\x95\x79\x30\x96\x4b\x95\xa5\xbf\x51\xc0\xb4\xbf\xcc\x21\x0d\xf3\xf2\x11\x64\xf0\x11\x4f\x6d\x63\x4b\x95\xf5\x93\x74\x49\xce\xe9\xb3\xf9\x3b\xfa\x25\xf2\x32\xc8\x02\x6d\x9d\xa9\xb5\x3b\xe0\x99\x0e\xc8\x83\x2f\x31\xf7\x28\x54\x71\xa7\xfe\x03\x00\x00\xff\xff\xa3\xc9\xa2\x70\x0c\x01\x00\x00")
|
||||
func _000001_initDownSql() (*asset, error) {
|
||||
bytes, err := _000001_initDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000001_init_up_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000001_init_up_sql,
|
||||
info := bindataFileInfo{name: "000001_init.down.sql", size: 19, mode: os.FileMode(420), modTime: time.Unix(1603074564, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var __000001_initUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8f\x31\x4f\xc3\x30\x10\x85\xe7\xf8\x57\xbc\x31\x91\xb2\x21\xb1\x30\xb9\xe5\x0a\x86\xc4\xa9\x9c\x2b\xb4\x2c\x55\x88\x0f\x61\x11\x4a\x14\x9b\x81\x7f\x8f\xda\x21\x43\xba\xdd\x7d\xba\xef\x9e\xde\xda\x91\x66\x02\xeb\x55\x45\x30\x1b\xd8\x86\x41\x7b\xd3\x72\x8b\xf7\xe1\xa7\xff\x8a\xc8\x55\x16\x3c\x5e\xb4\x5b\x3f\x6a\x97\xdf\xdc\x16\xa5\xca\xc2\x29\xca\x94\x8e\x5d\x02\x9b\x9a\x5a\xd6\xf5\x96\xdf\x2e\xae\xdd\x55\x15\xee\x69\xa3\x77\x15\xc3\x36\xaf\xf9\xf9\x7c\xec\x26\x39\xa5\xe3\xd5\x9b\xd8\x7f\xca\x77\x87\x95\x79\x30\x96\x4b\x95\xa5\xbf\x51\xc0\xb4\xbf\xcc\x21\x0d\xf3\xf2\x11\x64\xf0\x11\x4f\x6d\x63\x4b\x95\xf5\x93\x74\x49\xce\xe9\xb3\xf9\x3b\xfa\x25\xf2\x32\xc8\x02\x6d\x9d\xa9\xb5\x3b\xe0\x99\x0e\xc8\x83\x2f\x31\xf7\x28\x54\x71\xa7\xfe\x03\x00\x00\xff\xff\xa3\xc9\xa2\x70\x0c\x01\x00\x00")
|
||||
|
||||
func _000001_initUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000001_initUpSql,
|
||||
"000001_init.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
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\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\x8b\x60\xbf\x1e\x1c\x00\x00\x00")
|
||||
func _000001_initUpSql() (*asset, error) {
|
||||
bytes, err := _000001_initUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000002_system_settings_table_down_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000002_system_settings_table_down_sql,
|
||||
info := bindataFileInfo{name: "000001_init.up.sql", size: 268, mode: os.FileMode(420), modTime: time.Unix(1607029670, 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\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\x8b\x60\xbf\x1e\x1c\x00\x00\x00")
|
||||
|
||||
func _000002_system_settings_tableDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000002_system_settings_tableDownSql,
|
||||
"000002_system_settings_table.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
var __000002_system_settings_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x0e\x72\x75\x0c\x71\x55\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\xf0\xf3\x0f\x51\x70\x8d\xf0\x0c\x0e\x09\x56\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\x56\xd0\xe0\xe2\xcc\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x34\x30\xd0\xd4\xe1\xe2\x2c\x4b\xcc\x29\x4d\x55\x08\x71\x8d\x08\xd1\xe1\xe2\x0c\x08\xf2\xf4\x75\x0c\x8a\x54\xf0\x76\x8d\x54\xd0\xc8\x4c\xd1\xe4\xd2\xb4\xe6\x02\x04\x00\x00\xff\xff\x17\x95\xca\x5b\x61\x00\x00\x00")
|
||||
func _000002_system_settings_tableDownSql() (*asset, error) {
|
||||
bytes, err := _000002_system_settings_tableDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000002_system_settings_table_up_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000002_system_settings_table_up_sql,
|
||||
info := bindataFileInfo{name: "000002_system_settings_table.down.sql", size: 28, mode: os.FileMode(420), modTime: time.Unix(1603229117, 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\x72\x0e\x72\x75\x0c\x71\x55\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\xf0\xf3\x0f\x51\x70\x8d\xf0\x0c\x0e\x09\x56\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\x56\xd0\xe0\xe2\xcc\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x34\x30\xd0\xd4\xe1\xe2\x2c\x4b\xcc\x29\x4d\x55\x08\x71\x8d\x08\xd1\xe1\xe2\x0c\x08\xf2\xf4\x75\x0c\x8a\x54\xf0\x76\x8d\x54\xd0\xc8\x4c\xd1\xe4\xd2\xb4\xe6\x02\x04\x00\x00\xff\xff\x17\x95\xca\x5b\x61\x00\x00\x00")
|
||||
|
||||
func _000002_system_settings_tableUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000002_system_settings_tableUpSql,
|
||||
"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
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000002_system_settings_table.up.sql", size: 97, mode: os.FileMode(420), modTime: time.Unix(1603229117, 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\x48\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\x94\x1c\x55\xb9\x28\x00\x00\x00")
|
||||
|
||||
func _000003_blocks_rootidDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000003_blocks_rootidDownSql,
|
||||
"000003_blocks_rootid.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _000003_blocks_rootidDownSql() (*asset, error) {
|
||||
bytes, err := _000003_blocks_rootidDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000003_blocks_rootid.down.sql", size: 40, mode: os.FileMode(420), modTime: time.Unix(1607029815, 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\x48\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\xce\x60\x70\x4e\x33\x00\x00\x00")
|
||||
|
||||
func _000003_blocks_rootidUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000003_blocks_rootidUpSql,
|
||||
"000003_blocks_rootid.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _000003_blocks_rootidUpSql() (*asset, error) {
|
||||
bytes, err := _000003_blocks_rootidUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000003_blocks_rootid.up.sql", size: 51, mode: os.FileMode(420), modTime: time.Unix(1607029769, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
return f()
|
||||
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 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))
|
||||
|
@ -82,12 +242,15 @@ func AssetNames() []string {
|
|||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
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,
|
||||
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,
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -117,23 +280,69 @@ func AssetDir(name string) ([]string, error) {
|
|||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for name := range node.Children {
|
||||
rv = append(rv, name)
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type _bintree_t struct {
|
||||
Func func() ([]byte, error)
|
||||
Children map[string]*_bintree_t
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children 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{
|
||||
}},
|
||||
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{}},
|
||||
}}
|
||||
|
||||
// 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, "/")...)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE blocks
|
||||
DROP COLUMN root_id;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE blocks
|
||||
ADD COLUMN root_id VARCHAR(36);
|
|
@ -1,3 +1,11 @@
|
|||
// Code generated by go-bindata. DO NOT EDIT.
|
||||
// sources:
|
||||
// sqlite_files/000001_init.down.sql
|
||||
// sqlite_files/000001_init.up.sql
|
||||
// sqlite_files/000002_system_settings_table.down.sql
|
||||
// sqlite_files/000002_system_settings_table.up.sql
|
||||
// sqlite_files/000003_blocks_rootid.down.sql
|
||||
// sqlite_files/000003_blocks_rootid.up.sql
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
|
@ -5,10 +13,14 @@ import (
|
|||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindata_read(data []byte, name string) ([]byte, error) {
|
||||
func bindataRead(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)
|
||||
|
@ -16,62 +28,210 @@ func bindata_read(data []byte, name string) ([]byte, error) {
|
|||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, gz)
|
||||
gz.Close()
|
||||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
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\x48\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x45\xbe\x01\x0f\x13\x00\x00\x00")
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
func _000001_init_down_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000001_init_down_sql,
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
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\x48\xca\xc9\x4f\xce\x2e\xb6\xe6\x02\x04\x00\x00\xff\xff\x45\xbe\x01\x0f\x13\x00\x00\x00")
|
||||
|
||||
func _000001_initDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000001_initDownSql,
|
||||
"000001_init.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
var __000001_init_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8f\xbf\x6e\x83\x30\x10\x87\x67\xfc\x14\xb7\x58\x18\x89\x4c\x95\x3a\xa4\x93\x93\x1c\x8d\x55\x20\x95\xb9\xb4\x61\x8a\x28\xbe\xa8\x56\x49\x8a\xc0\x1d\xfa\xf6\x15\x91\xca\x90\x6c\xf7\xfb\x4e\xdf\xfd\x59\x5b\xd4\x84\x40\x7a\x95\x23\x98\x0c\xca\x1d\x01\x1e\x4c\x45\x15\x7c\x74\xdf\xed\xd7\x08\x4a\x44\xde\xc1\x9b\xb6\xeb\xad\xb6\xea\xe1\x31\x49\x45\xe4\x2f\x23\x0f\xe1\xd8\x04\xd8\x68\x42\x32\x05\x5e\xc5\x72\x9f\xe7\xb0\xc1\x4c\xef\x73\x52\x15\xd9\x6c\xea\xa8\x58\xd6\x0b\x79\x5e\x48\x07\x72\xbb\x94\xc5\x52\x9e\xe2\x14\xe2\x72\xf7\x1e\x27\xd3\xac\xbe\x19\xf8\x12\x8e\x77\x3b\xc6\xf6\x93\xcf\x0d\xac\xcc\xb3\x29\x29\x15\x51\xf8\xed\x19\x08\x0f\xd7\xda\x87\x6e\x0e\x27\xcf\x9d\x1b\xff\x53\x3b\x70\x13\x78\x3a\x6d\x36\x7f\x7a\x77\x8b\x1c\x77\x7c\x83\x5e\xad\x29\xb4\xad\xe1\x05\x6b\x50\xde\xa5\x30\x3f\x99\x88\xe4\x49\xfc\x05\x00\x00\xff\xff\xa2\x33\x30\x8e\x29\x01\x00\x00")
|
||||
func _000001_initDownSql() (*asset, error) {
|
||||
bytes, err := _000001_initDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000001_init_up_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000001_init_up_sql,
|
||||
info := bindataFileInfo{name: "000001_init.down.sql", size: 19, mode: os.FileMode(420), modTime: time.Unix(1603074564, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var __000001_initUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8f\xbf\x6e\x83\x30\x10\x87\x67\xfc\x14\xb7\x58\x18\x89\x4c\x95\x3a\xa4\x93\x93\x1c\x8d\x55\x20\x95\xb9\xb4\x61\x8a\x28\xbe\xa8\x56\x49\x8a\xc0\x1d\xfa\xf6\x15\x91\xca\x90\x6c\xf7\xfb\x4e\xdf\xfd\x59\x5b\xd4\x84\x40\x7a\x95\x23\x98\x0c\xca\x1d\x01\x1e\x4c\x45\x15\x7c\x74\xdf\xed\xd7\x08\x4a\x44\xde\xc1\x9b\xb6\xeb\xad\xb6\xea\xe1\x31\x49\x45\xe4\x2f\x23\x0f\xe1\xd8\x04\xd8\x68\x42\x32\x05\x5e\xc5\x72\x9f\xe7\xb0\xc1\x4c\xef\x73\x52\x15\xd9\x6c\xea\xa8\x58\xd6\x0b\x79\x5e\x48\x07\x72\xbb\x94\xc5\x52\x9e\xe2\x14\xe2\x72\xf7\x1e\x27\xd3\xac\xbe\x19\xf8\x12\x8e\x77\x3b\xc6\xf6\x93\xcf\x0d\xac\xcc\xb3\x29\x29\x15\x51\xf8\xed\x19\x08\x0f\xd7\xda\x87\x6e\x0e\x27\xcf\x9d\x1b\xff\x53\x3b\x70\x13\x78\x3a\x6d\x36\x7f\x7a\x77\x8b\x1c\x77\x7c\x83\x5e\xad\x29\xb4\xad\xe1\x05\x6b\x50\xde\xa5\x30\x3f\x99\x88\xe4\x49\xfc\x05\x00\x00\xff\xff\xa2\x33\x30\x8e\x29\x01\x00\x00")
|
||||
|
||||
func _000001_initUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000001_initUpSql,
|
||||
"000001_init.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
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\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\x8b\x60\xbf\x1e\x1c\x00\x00\x00")
|
||||
func _000001_initUpSql() (*asset, error) {
|
||||
bytes, err := _000001_initUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000002_system_settings_table_down_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000002_system_settings_table_down_sql,
|
||||
info := bindataFileInfo{name: "000001_init.up.sql", size: 297, mode: os.FileMode(420), modTime: time.Unix(1607029839, 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\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x02\x04\x00\x00\xff\xff\x8b\x60\xbf\x1e\x1c\x00\x00\x00")
|
||||
|
||||
func _000002_system_settings_tableDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000002_system_settings_tableDownSql,
|
||||
"000002_system_settings_table.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
var __000002_system_settings_table_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x0e\x72\x75\x0c\x71\x55\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\xf0\xf3\x0f\x51\x70\x8d\xf0\x0c\x0e\x09\x56\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xd6\xe0\xe2\xcc\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x34\x30\xd0\xd4\xe1\xe2\x2c\x4b\xcc\x29\x4d\x55\x08\x71\x8d\x08\xd1\xe1\xe2\x0c\x08\xf2\xf4\x75\x0c\x8a\x54\xf0\x76\x8d\x54\xd0\xc8\x4c\xd1\xe4\xd2\xb4\xe6\x02\x04\x00\x00\xff\xff\x1e\xfb\x02\xf2\x60\x00\x00\x00")
|
||||
func _000002_system_settings_tableDownSql() (*asset, error) {
|
||||
bytes, err := _000002_system_settings_tableDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func _000002_system_settings_table_up_sql() ([]byte, error) {
|
||||
return bindata_read(
|
||||
__000002_system_settings_table_up_sql,
|
||||
info := bindataFileInfo{name: "000002_system_settings_table.down.sql", size: 28, mode: os.FileMode(420), modTime: time.Unix(1603229117, 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\x72\x0e\x72\x75\x0c\x71\x55\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\xf0\xf3\x0f\x51\x70\x8d\xf0\x0c\x0e\x09\x56\x28\xae\x2c\x2e\x49\xcd\x8d\x2f\x4e\x2d\x29\xc9\xcc\x4b\x2f\xd6\xe0\xe2\xcc\x4c\x51\x08\x73\x0c\x72\xf6\x70\x0c\xd2\x30\x34\x30\xd0\xd4\xe1\xe2\x2c\x4b\xcc\x29\x4d\x55\x08\x71\x8d\x08\xd1\xe1\xe2\x0c\x08\xf2\xf4\x75\x0c\x8a\x54\xf0\x76\x8d\x54\xd0\xc8\x4c\xd1\xe4\xd2\xb4\xe6\x02\x04\x00\x00\xff\xff\x1e\xfb\x02\xf2\x60\x00\x00\x00")
|
||||
|
||||
func _000002_system_settings_tableUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000002_system_settings_tableUpSql,
|
||||
"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
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000002_system_settings_table.up.sql", size: 96, mode: os.FileMode(420), modTime: time.Unix(1603229117, 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\x48\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\x94\x1c\x55\xb9\x28\x00\x00\x00")
|
||||
|
||||
func _000003_blocks_rootidDownSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000003_blocks_rootidDownSql,
|
||||
"000003_blocks_rootid.down.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _000003_blocks_rootidDownSql() (*asset, error) {
|
||||
bytes, err := _000003_blocks_rootidDownSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000003_blocks_rootid.down.sql", size: 40, mode: os.FileMode(420), modTime: time.Unix(1607029815, 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\x48\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\xce\x60\x70\x4e\x33\x00\x00\x00")
|
||||
|
||||
func _000003_blocks_rootidUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__000003_blocks_rootidUpSql,
|
||||
"000003_blocks_rootid.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _000003_blocks_rootidUpSql() (*asset, error) {
|
||||
bytes, err := _000003_blocks_rootidUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "000003_blocks_rootid.up.sql", size: 51, mode: os.FileMode(420), modTime: time.Unix(1607029769, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
return f()
|
||||
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 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))
|
||||
|
@ -82,12 +242,15 @@ func AssetNames() []string {
|
|||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
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,
|
||||
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,
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -117,23 +280,69 @@ func AssetDir(name string) ([]string, error) {
|
|||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for name := range node.Children {
|
||||
rv = append(rv, name)
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type _bintree_t struct {
|
||||
Func func() ([]byte, error)
|
||||
Children map[string]*_bintree_t
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children 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{
|
||||
}},
|
||||
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{}},
|
||||
}}
|
||||
|
||||
// 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, "/")...)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE blocks
|
||||
DROP COLUMN root_id;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE blocks
|
||||
ADD COLUMN root_id VARCHAR(36);
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
import {BoardTree} from './viewModel/boardTree'
|
||||
import mutator from './mutator'
|
||||
import {IBlock} from './blocks/block'
|
||||
import {IBlock, IMutableBlock} from './blocks/block'
|
||||
import {Utils} from './utils'
|
||||
|
||||
interface Archive {
|
||||
|
@ -67,14 +67,15 @@ class Archiver {
|
|||
Utils.log(`Import archive, version: ${archive.version}, date/time: ${date.toLocaleString()}, ${blocks.length} block(s).`)
|
||||
|
||||
// Basic error checking
|
||||
const filteredBlocks = blocks.filter((o) => {
|
||||
if (!o.id) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
let filteredBlocks = blocks.filter((o) => Boolean(o.id))
|
||||
|
||||
Utils.log(`Import ${filteredBlocks.length} filtered blocks.`)
|
||||
Utils.log(`Import ${filteredBlocks.length} filtered blocks with ids.`)
|
||||
|
||||
this.fixRootIds(filteredBlocks)
|
||||
|
||||
filteredBlocks = filteredBlocks.filter((o) => Boolean(o.rootId))
|
||||
|
||||
Utils.log(`Import ${filteredBlocks.length} filtered blocks with rootIds.`)
|
||||
|
||||
await mutator.importFullArchive(filteredBlocks)
|
||||
Utils.log('Import completed')
|
||||
|
@ -87,6 +88,42 @@ class Archiver {
|
|||
|
||||
// TODO: Remove or reuse input
|
||||
}
|
||||
|
||||
private static fixRootIds(blocks: IMutableBlock[]) {
|
||||
const blockMap = new Map(blocks.map((o) => [o.id, o]))
|
||||
const maxLevels = 5
|
||||
for (let i = 0; i < maxLevels; i++) {
|
||||
let missingRootIds = false
|
||||
blocks.forEach((o) => {
|
||||
if (o.parentId) {
|
||||
const parent = blockMap.get(o.parentId)
|
||||
if (parent) {
|
||||
o.rootId = parent.rootId
|
||||
} else {
|
||||
Utils.assert(`No parent for ${o.type}: ${o.id} (${o.title})`)
|
||||
}
|
||||
if (!o.rootId) {
|
||||
missingRootIds = true
|
||||
}
|
||||
} else {
|
||||
o.rootId = o.id
|
||||
}
|
||||
})
|
||||
|
||||
if (!missingRootIds) {
|
||||
Utils.log(`fixRootIds in ${i} levels`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check and log remaining errors
|
||||
blocks.forEach((o) => {
|
||||
if (!o.rootId) {
|
||||
const parent = blockMap.get(o.parentId)
|
||||
Utils.logError(`RootId is null: ${o.type} ${o.id}, parentId ${o.parentId}: ${o.title}, parent: ${parent?.type}, parent.rootId: ${parent?.rootId}, parent.title: ${parent?.title}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export {Archiver}
|
||||
|
|
|
@ -7,6 +7,7 @@ type BlockTypes = 'board' | 'view' | 'card' | 'text' | 'image' | 'divider' | 'co
|
|||
interface IBlock {
|
||||
readonly id: string
|
||||
readonly parentId: string
|
||||
readonly rootId: string
|
||||
|
||||
readonly schema: number
|
||||
readonly type: BlockTypes
|
||||
|
@ -21,6 +22,7 @@ interface IBlock {
|
|||
interface IMutableBlock extends IBlock {
|
||||
id: string
|
||||
parentId: string
|
||||
rootId: string
|
||||
|
||||
schema: number
|
||||
type: BlockTypes
|
||||
|
@ -36,6 +38,7 @@ class MutableBlock implements IMutableBlock {
|
|||
id: string = Utils.createGuid()
|
||||
schema: number
|
||||
parentId: string
|
||||
rootId: string
|
||||
type: BlockTypes
|
||||
title: string
|
||||
fields: Record<string, any> = {}
|
||||
|
@ -59,6 +62,7 @@ class MutableBlock implements IMutableBlock {
|
|||
this.id = block.id || Utils.createGuid()
|
||||
this.schema = 1
|
||||
this.parentId = block.parentId || ''
|
||||
this.rootId = block.rootId || ''
|
||||
this.type = block.type || ''
|
||||
|
||||
// Shallow copy here. Derived classes must make deep copies of their known properties in their constructors.
|
||||
|
|
|
@ -102,9 +102,9 @@ class MutableBoard extends MutableBlock {
|
|||
}
|
||||
|
||||
duplicate(): MutableBoard {
|
||||
const card = new MutableBoard(this)
|
||||
card.id = Utils.createGuid()
|
||||
return card
|
||||
const board = new MutableBoard(this)
|
||||
board.id = Utils.createGuid()
|
||||
return board
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -497,6 +497,7 @@ class BoardComponent extends React.Component<Props, State> {
|
|||
const card = new MutableCard()
|
||||
|
||||
card.parentId = boardTree.board.id
|
||||
card.rootId = boardTree.board.rootId
|
||||
const propertiesThatMeetFilters = CardFilter.propertiesThatMeetFilterGroup(activeView.filter, board.cardProperties)
|
||||
if (boardTree.groupByProperty) {
|
||||
if (groupByOptionId) {
|
||||
|
@ -527,6 +528,7 @@ class BoardComponent extends React.Component<Props, State> {
|
|||
const cardTemplate = new MutableCard()
|
||||
cardTemplate.isTemplate = true
|
||||
cardTemplate.parentId = boardTree.board.id
|
||||
cardTemplate.rootId = boardTree.board.rootId
|
||||
await mutator.insertBlock(
|
||||
cardTemplate,
|
||||
'add card template',
|
||||
|
|
|
@ -72,7 +72,7 @@ class CardDetail extends React.Component<Props, State> {
|
|||
<ContentBlock
|
||||
key={block.id}
|
||||
block={block}
|
||||
cardId={card.id}
|
||||
card={card}
|
||||
contents={cardTree.contents}
|
||||
/>
|
||||
))}
|
||||
|
@ -88,6 +88,7 @@ class CardDetail extends React.Component<Props, State> {
|
|||
if (text) {
|
||||
const block = new MutableTextBlock()
|
||||
block.parentId = card.id
|
||||
block.rootId = card.rootId
|
||||
block.title = text
|
||||
block.order = (this.props.cardTree.contents.length + 1) * 1000
|
||||
mutator.insertBlock(block, 'add card text')
|
||||
|
@ -215,6 +216,7 @@ class CardDetail extends React.Component<Props, State> {
|
|||
onClick={() => {
|
||||
const block = new MutableTextBlock()
|
||||
block.parentId = card.id
|
||||
block.rootId = card.rootId
|
||||
block.order = (this.props.cardTree.contents.length + 1) * 1000
|
||||
mutator.insertBlock(block, 'add text')
|
||||
}}
|
||||
|
@ -223,7 +225,7 @@ class CardDetail extends React.Component<Props, State> {
|
|||
id='image'
|
||||
name={intl.formatMessage({id: 'CardDetail.image', defaultMessage: 'Image'})}
|
||||
onClick={() => Utils.selectLocalFile(
|
||||
(file) => mutator.createImageBlock(card.id, file, (this.props.cardTree.contents.length + 1) * 1000),
|
||||
(file) => mutator.createImageBlock(card, file, (this.props.cardTree.contents.length + 1) * 1000),
|
||||
'.jpg,.jpeg,.png',
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import React from 'react'
|
||||
|
||||
import {IBlock} from '../blocks/block'
|
||||
import {MutableDividerBlock} from '../blocks/dividerBlock'
|
||||
import {IOrderedBlock} from '../blocks/orderedBlock'
|
||||
import {MutableTextBlock} from '../blocks/textBlock'
|
||||
|
@ -26,13 +27,13 @@ import {MarkdownEditor} from './markdownEditor'
|
|||
|
||||
type Props = {
|
||||
block: IOrderedBlock
|
||||
cardId: string
|
||||
card: IBlock
|
||||
contents: readonly IOrderedBlock[]
|
||||
}
|
||||
|
||||
class ContentBlock extends React.PureComponent<Props> {
|
||||
public render(): JSX.Element | null {
|
||||
const {cardId, contents, block} = this.props
|
||||
const {card, contents, block} = this.props
|
||||
|
||||
if (block.type !== 'text' && block.type !== 'image' && block.type !== 'divider') {
|
||||
Utils.assertFailure(`Block type is unknown: ${block.type}`)
|
||||
|
@ -81,7 +82,8 @@ class ContentBlock extends React.PureComponent<Props> {
|
|||
icon={<TextIcon/>}
|
||||
onClick={() => {
|
||||
const newBlock = new MutableTextBlock()
|
||||
newBlock.parentId = cardId
|
||||
newBlock.parentId = card.id
|
||||
newBlock.rootId = card.rootId
|
||||
|
||||
// TODO: Handle need to reorder all blocks
|
||||
newBlock.order = OctoUtils.getOrderBefore(block, contents)
|
||||
|
@ -96,7 +98,7 @@ class ContentBlock extends React.PureComponent<Props> {
|
|||
onClick={() => {
|
||||
Utils.selectLocalFile(
|
||||
(file) => {
|
||||
mutator.createImageBlock(cardId, file, OctoUtils.getOrderBefore(block, contents))
|
||||
mutator.createImageBlock(card, file, OctoUtils.getOrderBefore(block, contents))
|
||||
},
|
||||
'.jpg,.jpeg,.png')
|
||||
}}
|
||||
|
@ -107,7 +109,8 @@ class ContentBlock extends React.PureComponent<Props> {
|
|||
icon={<DividerIcon/>}
|
||||
onClick={() => {
|
||||
const newBlock = new MutableDividerBlock()
|
||||
newBlock.parentId = cardId
|
||||
newBlock.parentId = card.id
|
||||
newBlock.rootId = card.rootId
|
||||
|
||||
// TODO: Handle need to reorder all blocks
|
||||
newBlock.order = OctoUtils.getOrderBefore(block, contents)
|
||||
|
|
|
@ -334,10 +334,12 @@ class Sidebar extends React.Component<Props, State> {
|
|||
const oldBoardId = this.props.activeBoardId
|
||||
|
||||
const board = new MutableBoard()
|
||||
board.rootId = board.id
|
||||
|
||||
const view = new MutableBoardView()
|
||||
view.viewType = 'board'
|
||||
view.parentId = board.id
|
||||
view.rootId = board.rootId
|
||||
view.title = intl.formatMessage({id: 'View.NewBoardTitle', defaultMessage: 'Board View'})
|
||||
|
||||
await mutator.insertBlocks(
|
||||
|
@ -412,6 +414,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||
const {activeBoardId} = this.props
|
||||
|
||||
const boardTemplate = new MutableBoard()
|
||||
boardTemplate.rootId = boardTemplate.id
|
||||
boardTemplate.isTemplate = true
|
||||
await mutator.insertBlock(
|
||||
boardTemplate,
|
||||
|
|
|
@ -323,6 +323,7 @@ class TableComponent extends React.Component<Props, State> {
|
|||
const card = new MutableCard()
|
||||
|
||||
card.parentId = boardTree.board.id
|
||||
card.rootId = boardTree.board.rootId
|
||||
if (!card.icon) {
|
||||
card.icon = BlockIcons.shared.randomIcon()
|
||||
}
|
||||
|
@ -346,6 +347,7 @@ class TableComponent extends React.Component<Props, State> {
|
|||
const cardTemplate = new MutableCard()
|
||||
cardTemplate.isTemplate = true
|
||||
cardTemplate.parentId = boardTree.board.id
|
||||
cardTemplate.rootId = boardTree.board.rootId
|
||||
await mutator.insertBlock(
|
||||
cardTemplate,
|
||||
'add card template',
|
||||
|
|
|
@ -99,6 +99,7 @@ class ViewHeader extends React.Component<Props, State> {
|
|||
for (let i = 0; i < count; i++) {
|
||||
const card = new MutableCard()
|
||||
card.parentId = boardTree.board.id
|
||||
card.rootId = boardTree.board.rootId
|
||||
card.properties = CardFilter.propertiesThatMeetFilterGroup(activeView.filter, board.cardProperties)
|
||||
card.title = `Test Card ${startCount + i + 1}`
|
||||
card.icon = BlockIcons.shared.randomIcon()
|
||||
|
|
|
@ -47,6 +47,7 @@ export class ViewMenu extends React.PureComponent<Props> {
|
|||
view.title = intl.formatMessage({id: 'View.NewBoardTitle', defaultMessage: 'Board View'})
|
||||
view.viewType = 'board'
|
||||
view.parentId = board.id
|
||||
view.rootId = board.rootId
|
||||
|
||||
const oldViewId = boardTree.activeView.id
|
||||
|
||||
|
@ -69,6 +70,7 @@ export class ViewMenu extends React.PureComponent<Props> {
|
|||
view.title = intl.formatMessage({id: 'View.NewTableTitle', defaultMessage: 'Table View'})
|
||||
view.viewType = 'table'
|
||||
view.parentId = board.id
|
||||
view.rootId = board.rootId
|
||||
view.visiblePropertyIds = board.cardProperties.map((o) => o.id)
|
||||
view.columnWidths = {}
|
||||
view.columnWidths[Constants.titleColumnId] = Constants.defaultTitleColumnWidth
|
||||
|
|
|
@ -573,18 +573,19 @@ class Mutator {
|
|||
}
|
||||
|
||||
// Not a mutator, but convenient to put here since Mutator wraps OctoClient
|
||||
async importFullArchive(blocks: IBlock[]): Promise<Response> {
|
||||
async importFullArchive(blocks: readonly IBlock[]): Promise<Response> {
|
||||
return octoClient.importFullArchive(blocks)
|
||||
}
|
||||
|
||||
async createImageBlock(parentId: string, file: File, order = 1000): Promise<IBlock | undefined> {
|
||||
async createImageBlock(parent: IBlock, file: File, order = 1000): Promise<IBlock | undefined> {
|
||||
const url = await octoClient.uploadFile(file)
|
||||
if (!url) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const block = new MutableImageBlock()
|
||||
block.parentId = parentId
|
||||
block.parentId = parent.id
|
||||
block.rootId = parent.rootId
|
||||
block.order = order
|
||||
block.url = url
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class OctoClient {
|
|||
return blocks
|
||||
}
|
||||
|
||||
async importFullArchive(blocks: IBlock[]): Promise<Response> {
|
||||
async importFullArchive(blocks: readonly IBlock[]): Promise<Response> {
|
||||
Utils.log(`importFullArchive: ${blocks.length} blocks(s)`)
|
||||
blocks.forEach((block) => {
|
||||
Utils.log(`\t ${block.type}, ${block.id}`)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {IBlock, MutableBlock} from './blocks/block'
|
||||
import {IPropertyTemplate, MutableBoard} from './blocks/board'
|
||||
import {MutableBoardView} from './blocks/boardView'
|
||||
|
@ -88,7 +89,7 @@ class OctoUtils {
|
|||
}
|
||||
|
||||
// Creates a copy of the blocks with new ids and parentIDs
|
||||
static duplicateBlockTree(blocks: IBlock[], rootBlockId: string): [MutableBlock[], MutableBlock, Readonly<Record<string, string>>] {
|
||||
static duplicateBlockTree(blocks: IBlock[], sourceBlockId: string): [MutableBlock[], MutableBlock, Readonly<Record<string, string>>] {
|
||||
const idMap: Record<string, string> = {}
|
||||
const newBlocks = blocks.map((block) => {
|
||||
const newBlock = this.hydrateBlock(block)
|
||||
|
@ -97,14 +98,29 @@ class OctoUtils {
|
|||
return newBlock
|
||||
})
|
||||
|
||||
const newRootBlockId = idMap[rootBlockId]
|
||||
const newSourceBlockId = idMap[sourceBlockId]
|
||||
|
||||
// Determine the new rootId if needed
|
||||
let newRootId: string
|
||||
const sourceBlock = blocks.find((block) => block.id === sourceBlockId)!
|
||||
if (sourceBlock.rootId === sourceBlock.id) {
|
||||
// Special case: when duplicating a tree from root, remap all the descendant rootIds
|
||||
const newSourceBlock = newBlocks.find((block) => block.id === newSourceBlockId)!
|
||||
newRootId = newSourceBlock.id
|
||||
}
|
||||
|
||||
newBlocks.forEach((newBlock) => {
|
||||
// Note: Don't remap the parent of the new root block
|
||||
if (newBlock.id !== newRootBlockId && newBlock.parentId) {
|
||||
if (newBlock.id !== newSourceBlockId && newBlock.parentId) {
|
||||
newBlock.parentId = idMap[newBlock.parentId] || newBlock.parentId
|
||||
Utils.assert(newBlock.parentId, `Block ${newBlock.id} (${newBlock.type} ${newBlock.title}) has no parent`)
|
||||
}
|
||||
|
||||
// Remap the rootIds if we are duplicating a tree from root
|
||||
if (newRootId) {
|
||||
newBlock.rootId = newRootId
|
||||
}
|
||||
|
||||
// Remap manual card order
|
||||
if (newBlock.type === 'view') {
|
||||
const view = newBlock as MutableBoardView
|
||||
|
@ -112,8 +128,8 @@ class OctoUtils {
|
|||
}
|
||||
})
|
||||
|
||||
const newRootBlock = newBlocks.find((block) => block.id === newRootBlockId)!
|
||||
return [newBlocks, newRootBlock, idMap]
|
||||
const newSourceBlock = newBlocks.find((block) => block.id === newSourceBlockId)!
|
||||
return [newBlocks, newSourceBlock, idMap]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,14 +84,13 @@ class MutableBoardTree implements BoardTree {
|
|||
}
|
||||
|
||||
private ensureMinimumSchema(): boolean {
|
||||
const {board} = this
|
||||
|
||||
let didChange = false
|
||||
|
||||
// At least one select property
|
||||
const selectProperties = board?.cardProperties.find((o) => o.type === 'select')
|
||||
const selectProperties = this.board?.cardProperties.find((o) => o.type === 'select')
|
||||
if (!selectProperties) {
|
||||
const newBoard = new MutableBoard(board)
|
||||
const newBoard = new MutableBoard(this.board)
|
||||
newBoard.rootId = newBoard.id
|
||||
const property: IPropertyTemplate = {
|
||||
id: Utils.createGuid(),
|
||||
name: 'Status',
|
||||
|
@ -106,8 +105,9 @@ class MutableBoardTree implements BoardTree {
|
|||
// At least one view
|
||||
if (this.views.length < 1) {
|
||||
const view = new MutableBoardView()
|
||||
view.parentId = board?.id
|
||||
view.groupById = board?.cardProperties.find((o) => o.type === 'select')?.id
|
||||
view.parentId = this.board.id
|
||||
view.rootId = this.board.rootId
|
||||
view.groupById = this.board.cardProperties.find((o) => o.type === 'select')?.id
|
||||
this.views.push(view)
|
||||
didChange = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user