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
d9b3501f
Unverified
Commit
d9b3501f
authored
Jul 14, 2023
by
Athurg Gooth
Committed by
GitHub
Jul 14, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add support for auto backup db file (#1950)
Add support for auto backup db file
parent
39351970
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
108 additions
and
3 deletions
+108
-3
system_setting.go
api/v1/system_setting.go
+17
-0
go.mod
go.mod
+1
-1
go.sum
go.sum
+2
-2
backup.go
server/backup.go
+48
-0
server.go
server/server.go
+1
-0
store.go
store/store.go
+39
-0
No files found.
api/v1/system_setting.go
View file @
d9b3501f
...
...
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"github.com/labstack/echo/v4"
...
...
@@ -39,6 +40,8 @@ const (
SystemSettingMemoDisplayWithUpdatedTsName
SystemSettingName
=
"memo-display-with-updated-ts"
// SystemSettingOpenAIConfigName is the name of OpenAI config.
SystemSettingOpenAIConfigName
SystemSettingName
=
"openai-config"
// SystemSettingAutoBackupIntervalName is the name of auto backup interval as seconds.
SystemSettingAutoBackupIntervalName
SystemSettingName
=
"auto-backup-interval"
)
// CustomizedProfile is the struct definition for SystemSettingCustomizedProfileName system setting item.
...
...
@@ -139,6 +142,20 @@ func (upsert UpsertSystemSettingRequest) Validate() error {
if
err
:=
json
.
Unmarshal
([]
byte
(
upsert
.
Value
),
&
value
);
err
!=
nil
{
return
fmt
.
Errorf
(
systemSettingUnmarshalError
,
settingName
)
}
case
SystemSettingAutoBackupIntervalName
:
var
value
string
if
err
:=
json
.
Unmarshal
([]
byte
(
upsert
.
Value
),
&
value
);
err
!=
nil
{
return
fmt
.
Errorf
(
systemSettingUnmarshalError
,
settingName
)
}
if
value
!=
""
{
v
,
err
:=
strconv
.
Atoi
(
value
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
systemSettingUnmarshalError
,
settingName
)
}
if
v
<
0
{
return
fmt
.
Errorf
(
"backup interval should > 0"
)
}
}
case
SystemSettingTelegramBotTokenName
:
if
upsert
.
Value
==
""
{
return
nil
...
...
go.mod
View file @
d9b3501f
...
...
@@ -25,7 +25,7 @@ require (
golang.org/x/mod v0.8.0
golang.org/x/net v0.7.0
golang.org/x/oauth2 v0.5.0
modernc.org/sqlite v1.2
2.1
modernc.org/sqlite v1.2
4.0
)
require (
...
...
go.sum
View file @
d9b3501f
...
...
@@ -662,8 +662,8 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.2
2.1 h1:P2+Dhp5FR1RlVRkQ3dDfCiv3Ok8XPxqpe70IjYVA9oE
=
modernc.org/sqlite v1.2
2.1
/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
modernc.org/sqlite v1.2
4.0 h1:EsClRIWHGhLTCX44p+Ri/JLD+vFGo0QGjasg2/F9TlI
=
modernc.org/sqlite v1.2
4.0
/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
...
...
server/backup.go
0 → 100644
View file @
d9b3501f
package
server
import
(
"context"
"fmt"
"strconv"
"time"
apiv1
"github.com/usememos/memos/api/v1"
"github.com/usememos/memos/common/log"
"github.com/usememos/memos/store"
"go.uber.org/zap"
)
func
autoBackup
(
ctx
context
.
Context
,
s
*
store
.
Store
)
{
intervalStr
:=
s
.
GetSystemSettingValueWithDefault
(
&
ctx
,
apiv1
.
SystemSettingAutoBackupIntervalName
.
String
(),
""
)
if
intervalStr
==
""
{
log
.
Info
(
"no SystemSettingAutoBackupIntervalName setting, disable auto backup"
)
return
}
interval
,
err
:=
strconv
.
Atoi
(
intervalStr
)
if
err
!=
nil
||
interval
<=
0
{
log
.
Error
(
fmt
.
Sprintf
(
"invalid SystemSettingAutoBackupIntervalName value %s, disable auto backup"
,
intervalStr
),
zap
.
Error
(
err
))
return
}
log
.
Info
(
"enable auto backup every "
+
intervalStr
+
" seconds"
)
ticker
:=
time
.
NewTicker
(
time
.
Duration
(
interval
)
*
time
.
Second
)
defer
ticker
.
Stop
()
var
t
time
.
Time
for
{
select
{
case
<-
ctx
.
Done
()
:
log
.
Info
(
"stop auto backup graceful."
)
return
case
t
=
<-
ticker
.
C
:
}
filename
:=
s
.
Profile
.
DSN
+
t
.
Format
(
"-20060102-150405.bak"
)
log
.
Info
(
fmt
.
Sprintf
(
"create backup to %s"
,
filename
))
err
:=
s
.
BackupTo
(
ctx
,
filename
)
if
err
!=
nil
{
log
.
Error
(
"fail to create backup"
,
zap
.
Error
(
err
))
}
}
}
server/server.go
View file @
d9b3501f
...
...
@@ -103,6 +103,7 @@ func (s *Server) Start(ctx context.Context) error {
}
go
s
.
telegramBot
.
Start
(
ctx
)
go
autoBackup
(
ctx
,
s
.
Store
)
return
s
.
e
.
Start
(
fmt
.
Sprintf
(
":%d"
,
s
.
Profile
.
Port
))
}
...
...
store/store.go
View file @
d9b3501f
...
...
@@ -3,9 +3,11 @@ package store
import
(
"context"
"database/sql"
"fmt"
"sync"
"github.com/usememos/memos/server/profile"
"modernc.org/sqlite"
)
// Store provides database access to all raw objects.
...
...
@@ -31,6 +33,43 @@ func (s *Store) GetDB() *sql.DB {
return
s
.
db
}
func
(
s
*
Store
)
BackupTo
(
ctx
context
.
Context
,
filename
string
)
error
{
conn
,
err
:=
s
.
db
.
Conn
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"fail to get conn %s"
,
err
)
}
defer
conn
.
Close
()
err
=
conn
.
Raw
(
func
(
driverConn
any
)
error
{
type
backuper
interface
{
NewBackup
(
string
)
(
*
sqlite
.
Backup
,
error
)
}
backupConn
,
ok
:=
driverConn
.
(
backuper
)
if
!
ok
{
return
fmt
.
Errorf
(
"db connection is not a sqlite backuper"
)
}
bck
,
err
:=
backupConn
.
NewBackup
(
filename
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"fail to create sqlite backup %s"
,
err
)
}
for
more
:=
true
;
more
;
{
more
,
err
=
bck
.
Step
(
-
1
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"fail to execute sqlite backup %s"
,
err
)
}
}
return
bck
.
Finish
()
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"fail to backup %s"
,
err
)
}
return
nil
}
func
(
s
*
Store
)
Vacuum
(
ctx
context
.
Context
)
error
{
tx
,
err
:=
s
.
db
.
BeginTx
(
ctx
,
nil
)
if
err
!=
nil
{
...
...
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