Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
07012e3f
Commit
07012e3f
authored
Aug 16, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: remove unused files
parent
1b6685d7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
0 additions
and
234 deletions
+0
-234
migrator.go
store/db/sqlite/migrator.go
+0
-234
No files found.
store/db/sqlite/migrator.go
deleted
100644 → 0
View file @
1b6685d7
package
sqlite
import
(
"context"
"embed"
"fmt"
"io/fs"
"os"
"regexp"
"sort"
"time"
"github.com/pkg/errors"
"github.com/usememos/memos/server/version"
"github.com/usememos/memos/store"
)
//go:embed migration
var
migrationFS
embed
.
FS
//go:embed seed
var
seedFS
embed
.
FS
// Migrate applies the latest schema to the database.
func
(
d
*
DB
)
Migrate
(
ctx
context
.
Context
)
error
{
currentVersion
:=
version
.
GetCurrentVersion
(
d
.
profile
.
Mode
)
if
d
.
profile
.
Mode
==
"prod"
{
_
,
err
:=
os
.
Stat
(
d
.
profile
.
DSN
)
if
err
!=
nil
{
// If db file not exists, we should create a new one with latest schema.
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
if
err
:=
d
.
applyLatestSchema
(
ctx
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to apply latest schema"
)
}
// Upsert the newest version to migration_history.
if
_
,
err
:=
d
.
UpsertMigrationHistory
(
ctx
,
&
store
.
UpsertMigrationHistory
{
Version
:
currentVersion
,
});
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to upsert migration history"
)
}
}
else
{
return
errors
.
Wrap
(
err
,
"failed to get db file stat"
)
}
}
else
{
// If db file exists, we should check if we need to migrate the database.
migrationHistoryList
,
err
:=
d
.
FindMigrationHistoryList
(
ctx
,
&
store
.
FindMigrationHistory
{})
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to find migration history"
)
}
// If no migration history, we should apply the latest version migration and upsert the migration history.
if
len
(
migrationHistoryList
)
==
0
{
minorVersion
:=
version
.
GetMinorVersion
(
currentVersion
)
if
err
:=
d
.
applyMigrationForMinorVersion
(
ctx
,
minorVersion
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to apply version %s migration"
,
minorVersion
)
}
_
,
err
:=
d
.
UpsertMigrationHistory
(
ctx
,
&
store
.
UpsertMigrationHistory
{
Version
:
currentVersion
,
})
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to upsert migration history"
)
}
return
nil
}
migrationHistoryVersionList
:=
[]
string
{}
for
_
,
migrationHistory
:=
range
migrationHistoryList
{
migrationHistoryVersionList
=
append
(
migrationHistoryVersionList
,
migrationHistory
.
Version
)
}
sort
.
Sort
(
version
.
SortVersion
(
migrationHistoryVersionList
))
latestMigrationHistoryVersion
:=
migrationHistoryVersionList
[
len
(
migrationHistoryVersionList
)
-
1
]
if
version
.
IsVersionGreaterThan
(
version
.
GetSchemaVersion
(
currentVersion
),
latestMigrationHistoryVersion
)
{
minorVersionList
:=
getMinorVersionList
()
// Backup the raw database file before migration.
rawBytes
,
err
:=
os
.
ReadFile
(
d
.
profile
.
DSN
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to read raw database file"
)
}
backupDBFilePath
:=
fmt
.
Sprintf
(
"%s/memos_%s_%d_backup.db"
,
d
.
profile
.
Data
,
d
.
profile
.
Version
,
time
.
Now
()
.
Unix
())
if
err
:=
os
.
WriteFile
(
backupDBFilePath
,
rawBytes
,
0644
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to write raw database file"
)
}
fmt
.
Println
(
"succeed to copy a backup database file"
)
fmt
.
Println
(
"start migrate"
)
for
_
,
minorVersion
:=
range
minorVersionList
{
normalizedVersion
:=
minorVersion
+
".0"
if
version
.
IsVersionGreaterThan
(
normalizedVersion
,
latestMigrationHistoryVersion
)
&&
version
.
IsVersionGreaterOrEqualThan
(
currentVersion
,
normalizedVersion
)
{
fmt
.
Println
(
"applying migration for"
,
normalizedVersion
)
if
err
:=
d
.
applyMigrationForMinorVersion
(
ctx
,
minorVersion
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to apply minor version migration"
)
}
}
}
fmt
.
Println
(
"end migrate"
)
// Remove the created backup db file after migrate succeed.
if
err
:=
os
.
Remove
(
backupDBFilePath
);
err
!=
nil
{
fmt
.
Printf
(
"Failed to remove temp database file, err %v"
,
err
)
}
}
}
}
else
{
// In non-prod mode, we should always migrate the database.
if
_
,
err
:=
os
.
Stat
(
d
.
profile
.
DSN
);
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
if
err
:=
d
.
applyLatestSchema
(
ctx
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to apply latest schema"
)
}
// In demo mode, we should seed the database.
if
d
.
profile
.
Mode
==
"demo"
{
if
err
:=
d
.
seed
(
ctx
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to seed"
)
}
}
}
}
return
nil
}
const
(
latestSchemaFileName
=
"LATEST__SCHEMA.sql"
)
func
(
d
*
DB
)
applyLatestSchema
(
ctx
context
.
Context
)
error
{
schemaMode
:=
"dev"
if
d
.
profile
.
Mode
==
"prod"
{
schemaMode
=
"prod"
}
latestSchemaPath
:=
fmt
.
Sprintf
(
"migration/%s/%s"
,
schemaMode
,
latestSchemaFileName
)
buf
,
err
:=
migrationFS
.
ReadFile
(
latestSchemaPath
)
if
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to read latest schema %q"
,
latestSchemaPath
)
}
stmt
:=
string
(
buf
)
if
err
:=
d
.
execute
(
ctx
,
stmt
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"migrate error: %s"
,
stmt
)
}
return
nil
}
func
(
d
*
DB
)
applyMigrationForMinorVersion
(
ctx
context
.
Context
,
minorVersion
string
)
error
{
filenames
,
err
:=
fs
.
Glob
(
migrationFS
,
fmt
.
Sprintf
(
"%s/%s/*.sql"
,
"migration/prod"
,
minorVersion
))
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to read ddl files"
)
}
sort
.
Strings
(
filenames
)
migrationStmt
:=
""
// Loop over all migration files and execute them in order.
for
_
,
filename
:=
range
filenames
{
buf
,
err
:=
migrationFS
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to read minor version migration file, filename=%s"
,
filename
)
}
stmt
:=
string
(
buf
)
migrationStmt
+=
stmt
if
err
:=
d
.
execute
(
ctx
,
stmt
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"migrate error: %s"
,
stmt
)
}
}
// Upsert the newest version to migration_history.
version
:=
minorVersion
+
".0"
if
_
,
err
=
d
.
UpsertMigrationHistory
(
ctx
,
&
store
.
UpsertMigrationHistory
{
Version
:
version
,
});
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to upsert migration history with version: %s"
,
version
)
}
return
nil
}
func
(
d
*
DB
)
seed
(
ctx
context
.
Context
)
error
{
filenames
,
err
:=
fs
.
Glob
(
seedFS
,
fmt
.
Sprintf
(
"%s/*.sql"
,
"seed"
))
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to read seed files"
)
}
sort
.
Strings
(
filenames
)
// Loop over all seed files and execute them in order.
for
_
,
filename
:=
range
filenames
{
buf
,
err
:=
seedFS
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to read seed file, filename=%s"
,
filename
)
}
stmt
:=
string
(
buf
)
if
err
:=
d
.
execute
(
ctx
,
stmt
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"seed error: %s"
,
stmt
)
}
}
return
nil
}
// execute runs a single SQL statement within a transaction.
func
(
d
*
DB
)
execute
(
ctx
context
.
Context
,
stmt
string
)
error
{
tx
,
err
:=
d
.
db
.
Begin
()
if
err
!=
nil
{
return
err
}
defer
tx
.
Rollback
()
if
_
,
err
:=
tx
.
ExecContext
(
ctx
,
stmt
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to execute statement"
)
}
return
tx
.
Commit
()
}
// minorDirRegexp is a regular expression for minor version directory.
var
minorDirRegexp
=
regexp
.
MustCompile
(
`^migration/prod/[0-9]+\.[0-9]+$`
)
func
getMinorVersionList
()
[]
string
{
minorVersionList
:=
[]
string
{}
if
err
:=
fs
.
WalkDir
(
migrationFS
,
"migration"
,
func
(
path
string
,
file
fs
.
DirEntry
,
err
error
)
error
{
if
err
!=
nil
{
return
err
}
if
file
.
IsDir
()
&&
minorDirRegexp
.
MatchString
(
path
)
{
minorVersionList
=
append
(
minorVersionList
,
file
.
Name
())
}
return
nil
});
err
!=
nil
{
panic
(
err
)
}
sort
.
Sort
(
version
.
SortVersion
(
minorVersionList
))
return
minorVersionList
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment