mirror of
https://github.com/usememos/memos.git
synced 2024-09-11 03:55:30 +03:00
chore: retire auto backup for sqlite
This commit is contained in:
parent
b575064d47
commit
e0cacfc6d6
@ -26,8 +26,6 @@ type SystemStatus struct {
|
||||
DisablePublicMemos bool `json:"disablePublicMemos"`
|
||||
// Max upload size.
|
||||
MaxUploadSizeMiB int `json:"maxUploadSizeMiB"`
|
||||
// Auto Backup Interval.
|
||||
AutoBackupInterval int `json:"autoBackupInterval"`
|
||||
// Additional style.
|
||||
AdditionalStyle string `json:"additionalStyle"`
|
||||
// Additional script.
|
||||
@ -124,8 +122,6 @@ func (s *APIV1Service) GetSystemStatus(c echo.Context) error {
|
||||
systemStatus.DisablePublicMemos = baseValue.(bool)
|
||||
case SystemSettingMaxUploadSizeMiBName.String():
|
||||
systemStatus.MaxUploadSizeMiB = int(baseValue.(float64))
|
||||
case SystemSettingAutoBackupIntervalName.String():
|
||||
systemStatus.AutoBackupInterval = int(baseValue.(float64))
|
||||
case SystemSettingAdditionalStyleName.String():
|
||||
systemStatus.AdditionalStyle = baseValue.(string)
|
||||
case SystemSettingAdditionalScriptName.String():
|
||||
|
@ -40,8 +40,6 @@ const (
|
||||
SystemSettingTelegramBotTokenName SystemSettingName = "telegram-bot-token"
|
||||
// SystemSettingMemoDisplayWithUpdatedTsName is the name of memo display with updated ts.
|
||||
SystemSettingMemoDisplayWithUpdatedTsName SystemSettingName = "memo-display-with-updated-ts"
|
||||
// SystemSettingAutoBackupIntervalName is the name of auto backup interval as seconds.
|
||||
SystemSettingAutoBackupIntervalName SystemSettingName = "auto-backup-interval"
|
||||
// SystemSettingInstanceURLName is the name of instance url setting.
|
||||
SystemSettingInstanceURLName SystemSettingName = "instance-url"
|
||||
)
|
||||
@ -244,14 +242,6 @@ func (upsert UpsertSystemSettingRequest) Validate() error {
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
case SystemSettingAutoBackupIntervalName:
|
||||
var value int
|
||||
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
|
||||
return errors.Errorf(systemSettingUnmarshalError, settingName)
|
||||
}
|
||||
if value < 0 {
|
||||
return errors.New("must be positive")
|
||||
}
|
||||
case SystemSettingTelegramBotTokenName:
|
||||
if upsert.Value == "" {
|
||||
return nil
|
||||
|
@ -17,8 +17,6 @@
|
||||
- [InboxMessage.Type](#memos-store-InboxMessage-Type)
|
||||
|
||||
- [store/system_setting.proto](#store_system_setting-proto)
|
||||
- [BackupConfig](#memos-store-BackupConfig)
|
||||
|
||||
- [SystemSettingKey](#memos-store-SystemSettingKey)
|
||||
|
||||
- [store/user_setting.proto](#store_user_setting-proto)
|
||||
@ -178,23 +176,6 @@
|
||||
## store/system_setting.proto
|
||||
|
||||
|
||||
|
||||
<a name="memos-store-BackupConfig"></a>
|
||||
|
||||
### BackupConfig
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| enabled | [bool](#bool) | | enabled indicates whether backup is enabled. |
|
||||
| cron | [string](#string) | | cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format |
|
||||
| max_keep | [int32](#int32) | | max_keep is the maximum number of backups to keep. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -206,7 +187,6 @@
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| SYSTEM_SETTING_KEY_UNSPECIFIED | 0 | |
|
||||
| BACKUP_CONFIG | 1 | BackupConfig is the key for auto-backup configuration. |
|
||||
|
||||
|
||||
|
||||
|
@ -24,19 +24,15 @@ type SystemSettingKey int32
|
||||
|
||||
const (
|
||||
SystemSettingKey_SYSTEM_SETTING_KEY_UNSPECIFIED SystemSettingKey = 0
|
||||
// BackupConfig is the key for auto-backup configuration.
|
||||
SystemSettingKey_BACKUP_CONFIG SystemSettingKey = 1
|
||||
)
|
||||
|
||||
// Enum value maps for SystemSettingKey.
|
||||
var (
|
||||
SystemSettingKey_name = map[int32]string{
|
||||
0: "SYSTEM_SETTING_KEY_UNSPECIFIED",
|
||||
1: "BACKUP_CONFIG",
|
||||
}
|
||||
SystemSettingKey_value = map[string]int32{
|
||||
"SYSTEM_SETTING_KEY_UNSPECIFIED": 0,
|
||||
"BACKUP_CONFIG": 1,
|
||||
}
|
||||
)
|
||||
|
||||
@ -67,99 +63,26 @@ func (SystemSettingKey) EnumDescriptor() ([]byte, []int) {
|
||||
return file_store_system_setting_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type BackupConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// enabled indicates whether backup is enabled.
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
// cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format
|
||||
Cron string `protobuf:"bytes,2,opt,name=cron,proto3" json:"cron,omitempty"`
|
||||
// max_keep is the maximum number of backups to keep.
|
||||
MaxKeep int32 `protobuf:"varint,3,opt,name=max_keep,json=maxKeep,proto3" json:"max_keep,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupConfig) Reset() {
|
||||
*x = BackupConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_system_setting_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BackupConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BackupConfig) ProtoMessage() {}
|
||||
|
||||
func (x *BackupConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_system_setting_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BackupConfig.ProtoReflect.Descriptor instead.
|
||||
func (*BackupConfig) Descriptor() ([]byte, []int) {
|
||||
return file_store_system_setting_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *BackupConfig) GetEnabled() bool {
|
||||
if x != nil {
|
||||
return x.Enabled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *BackupConfig) GetCron() string {
|
||||
if x != nil {
|
||||
return x.Cron
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BackupConfig) GetMaxKeep() int32 {
|
||||
if x != nil {
|
||||
return x.MaxKeep
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_store_system_setting_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_store_system_setting_proto_rawDesc = []byte{
|
||||
0x0a, 0x1a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x73,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x57, 0x0a, 0x0c, 0x42, 0x61, 0x63,
|
||||
0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x6b,
|
||||
0x65, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4b, 0x65,
|
||||
0x65, 0x70, 0x2a, 0x49, 0x0a, 0x10, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x74, 0x74,
|
||||
0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d,
|
||||
0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53,
|
||||
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x41,
|
||||
0x43, 0x4b, 0x55, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01, 0x42, 0x9d, 0x01,
|
||||
0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x42, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
|
||||
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2a, 0x36, 0x0a, 0x10, 0x53, 0x79, 0x73,
|
||||
0x74, 0x65, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a,
|
||||
0x1e, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f,
|
||||
0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
|
||||
0x00, 0x42, 0x9d, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x74,
|
||||
0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e,
|
||||
0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -175,10 +98,8 @@ func file_store_system_setting_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_store_system_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_store_system_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_store_system_setting_proto_goTypes = []interface{}{
|
||||
(SystemSettingKey)(0), // 0: memos.store.SystemSettingKey
|
||||
(*BackupConfig)(nil), // 1: memos.store.BackupConfig
|
||||
}
|
||||
var file_store_system_setting_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
@ -193,34 +114,19 @@ func file_store_system_setting_proto_init() {
|
||||
if File_store_system_setting_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_store_system_setting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_store_system_setting_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 1,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_store_system_setting_proto_goTypes,
|
||||
DependencyIndexes: file_store_system_setting_proto_depIdxs,
|
||||
EnumInfos: file_store_system_setting_proto_enumTypes,
|
||||
MessageInfos: file_store_system_setting_proto_msgTypes,
|
||||
}.Build()
|
||||
File_store_system_setting_proto = out.File
|
||||
file_store_system_setting_proto_rawDesc = nil
|
||||
|
@ -6,16 +6,4 @@ option go_package = "gen/store";
|
||||
|
||||
enum SystemSettingKey {
|
||||
SYSTEM_SETTING_KEY_UNSPECIFIED = 0;
|
||||
|
||||
// BackupConfig is the key for auto-backup configuration.
|
||||
BACKUP_CONFIG = 1;
|
||||
}
|
||||
|
||||
message BackupConfig {
|
||||
// enabled indicates whether backup is enabled.
|
||||
bool enabled = 1;
|
||||
// cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format
|
||||
string cron = 2;
|
||||
// max_keep is the maximum number of backups to keep.
|
||||
int32 max_keep = 3;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
"github.com/usememos/memos/server/frontend"
|
||||
"github.com/usememos/memos/server/integration"
|
||||
"github.com/usememos/memos/server/profile"
|
||||
"github.com/usememos/memos/server/service/backup"
|
||||
"github.com/usememos/memos/server/service/metric"
|
||||
versionchecker "github.com/usememos/memos/server/service/version_checker"
|
||||
"github.com/usememos/memos/store"
|
||||
@ -34,8 +33,7 @@ type Server struct {
|
||||
Store *store.Store
|
||||
|
||||
// Asynchronous runners.
|
||||
backupRunner *backup.BackupRunner
|
||||
telegramBot *telegram.Bot
|
||||
telegramBot *telegram.Bot
|
||||
}
|
||||
|
||||
func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store) (*Server, error) {
|
||||
@ -53,10 +51,6 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
||||
telegramBot: telegram.NewBotWithHandler(integration.NewTelegramHandler(store)),
|
||||
}
|
||||
|
||||
if profile.Driver == "sqlite" {
|
||||
s.backupRunner = backup.NewBackupRunner(store)
|
||||
}
|
||||
|
||||
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Format: `{"time":"${time_rfc3339}","latency":"${latency_human}",` +
|
||||
`"method":"${method}","uri":"${uri}",` +
|
||||
@ -121,10 +115,6 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
go versionchecker.NewVersionChecker(s.Store, s.Profile).Start(ctx)
|
||||
go s.telegramBot.Start(ctx)
|
||||
|
||||
if s.backupRunner != nil {
|
||||
go s.backupRunner.Run(ctx)
|
||||
}
|
||||
|
||||
metric.Enqueue("server start")
|
||||
return s.e.Start(fmt.Sprintf("%s:%d", s.Profile.Addr, s.Profile.Port))
|
||||
}
|
||||
|
@ -1,94 +0,0 @@
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
apiv1 "github.com/usememos/memos/api/v1"
|
||||
"github.com/usememos/memos/internal/log"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
// nolint
|
||||
type BackupRunner struct {
|
||||
Store *store.Store
|
||||
}
|
||||
|
||||
func NewBackupRunner(store *store.Store) *BackupRunner {
|
||||
return &BackupRunner{
|
||||
Store: store,
|
||||
}
|
||||
}
|
||||
|
||||
const MaxBackupFiles = 5
|
||||
|
||||
func (r *BackupRunner) Run(ctx context.Context) {
|
||||
intervalStr := r.Store.GetSystemSettingValueWithDefault(ctx, apiv1.SystemSettingAutoBackupIntervalName.String(), "")
|
||||
if intervalStr == "" {
|
||||
log.Debug("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
|
||||
}
|
||||
|
||||
if interval == 0 {
|
||||
println("AutoBackupIntervalName value is 0, disable auto backup")
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("enable auto backup every " + intervalStr + " seconds")
|
||||
ticker := time.NewTicker(time.Duration(interval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Info("stop auto backup graceful.")
|
||||
return
|
||||
case <-ticker.C:
|
||||
}
|
||||
|
||||
filename := r.Store.Profile.DSN + ".bak"
|
||||
|
||||
if err := rotateFiles(filename, MaxBackupFiles); err != nil {
|
||||
log.Error("fail to rotate backup files", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info(fmt.Sprintf("create backup to %s", filename))
|
||||
if err := r.Store.BackupTo(ctx, filename); err != nil {
|
||||
log.Error("fail to create backup", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rotateFiles(filename string, cnt int) error {
|
||||
// Generate suffix slices of history files like "",".1",".2",".3"...
|
||||
ss := make([]string, cnt-1)
|
||||
for i := 1; i < len(ss); i++ {
|
||||
ss[i] = fmt.Sprintf(".%d", i)
|
||||
}
|
||||
|
||||
// Iterate through the suffix slices and rename the files
|
||||
for i := len(ss) - 1; i >= 0; i-- {
|
||||
from := filename + ss[i]
|
||||
to := filename + "." + strconv.Itoa(i+1)
|
||||
|
||||
log.Info("rotate file", zap.String("from", from), zap.String("to", to))
|
||||
err := os.Rename(from, to)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -75,10 +75,6 @@ func (d *DB) Vacuum(ctx context.Context) error {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (*DB) BackupTo(context.Context, string) error {
|
||||
return errors.New("Please use mysqldump to backup")
|
||||
}
|
||||
|
||||
func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) {
|
||||
query := "SELECT SUM(`data_length` + `index_length`) AS `size` " +
|
||||
" FROM information_schema.TABLES" +
|
||||
|
@ -74,10 +74,6 @@ func (d *DB) Vacuum(ctx context.Context) error {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (*DB) BackupTo(context.Context, string) error {
|
||||
return errors.New("Please use postgresdump to backup")
|
||||
}
|
||||
|
||||
func (*DB) GetCurrentDBSize(context.Context) (int64, error) {
|
||||
return 0, errors.New("unimplemented")
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func (d *DB) Migrate(ctx context.Context) error {
|
||||
|
||||
if version.IsVersionGreaterThan(version.GetSchemaVersion(currentVersion), latestMigrationHistoryVersion) {
|
||||
minorVersionList := getMinorVersionList()
|
||||
// backup the raw database file before migration
|
||||
// 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")
|
||||
@ -94,7 +94,7 @@ func (d *DB) Migrate(ctx context.Context) error {
|
||||
}
|
||||
println("end migrate")
|
||||
|
||||
// remove the created backup db file after migrate succeed
|
||||
// Remove the created backup db file after migrate succeed.
|
||||
if err := os.Remove(backupDBFilePath); err != nil {
|
||||
println(fmt.Sprintf("Failed to remove temp database file, err %v", err))
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"modernc.org/sqlite"
|
||||
|
||||
// Import the SQLite driver.
|
||||
_ "modernc.org/sqlite"
|
||||
|
||||
"github.com/usememos/memos/server/profile"
|
||||
"github.com/usememos/memos/store"
|
||||
@ -103,43 +105,6 @@ func vacuumImpl(ctx context.Context, tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DB) BackupTo(ctx context.Context, filename string) error {
|
||||
conn, err := d.db.Conn(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fail to open new connection")
|
||||
}
|
||||
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 errors.New("db connection is not a sqlite backuper")
|
||||
}
|
||||
|
||||
bck, err := backupConn.NewBackup(filename)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fail to create sqlite backup")
|
||||
}
|
||||
|
||||
for more := true; more; {
|
||||
more, err = bck.Step(-1)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fail to execute sqlite backup")
|
||||
}
|
||||
}
|
||||
|
||||
return bck.Finish()
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fail to backup")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DB) GetCurrentDBSize(context.Context) (int64, error) {
|
||||
fi, err := os.Stat(d.profile.DSN)
|
||||
if err != nil {
|
||||
|
@ -15,7 +15,6 @@ type Driver interface {
|
||||
|
||||
Migrate(ctx context.Context) error
|
||||
Vacuum(ctx context.Context) error
|
||||
BackupTo(ctx context.Context, filename string) error
|
||||
|
||||
// current file is driver
|
||||
GetCurrentDBSize(ctx context.Context) (int64, error)
|
||||
|
@ -25,10 +25,6 @@ func New(driver Driver, profile *profile.Profile) *Store {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) BackupTo(ctx context.Context, filename string) error {
|
||||
return s.driver.BackupTo(ctx, filename)
|
||||
}
|
||||
|
||||
func (s *Store) Vacuum(ctx context.Context) error {
|
||||
return s.driver.Vacuum(ctx)
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
// mysql driver.
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
// sqlite driver.
|
||||
_ "modernc.org/sqlite"
|
||||
|
||||
|
@ -20,7 +20,6 @@ interface State {
|
||||
additionalStyle: string;
|
||||
additionalScript: string;
|
||||
maxUploadSizeMiB: number;
|
||||
autoBackupInterval: number;
|
||||
memoDisplayWithUpdatedTs: boolean;
|
||||
}
|
||||
|
||||
@ -36,7 +35,6 @@ const SystemSection = () => {
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
maxUploadSizeMiB: systemStatus.maxUploadSizeMiB,
|
||||
autoBackupInterval: systemStatus.autoBackupInterval,
|
||||
memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs,
|
||||
});
|
||||
const [telegramBotToken, setTelegramBotToken] = useState<string>("");
|
||||
@ -69,7 +67,6 @@ const SystemSection = () => {
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
maxUploadSizeMiB: systemStatus.maxUploadSizeMiB,
|
||||
autoBackupInterval: systemStatus.autoBackupInterval,
|
||||
memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs,
|
||||
});
|
||||
}, [systemStatus]);
|
||||
@ -246,30 +243,6 @@ const SystemSection = () => {
|
||||
event.target.select();
|
||||
};
|
||||
|
||||
const handleAutoBackupIntervalChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
// fixes cursor skipping position on mobile
|
||||
event.target.selectionEnd = event.target.value.length;
|
||||
|
||||
let num = parseInt(event.target.value);
|
||||
if (Number.isNaN(num)) {
|
||||
num = 0;
|
||||
}
|
||||
setState({
|
||||
...state,
|
||||
autoBackupInterval: num,
|
||||
});
|
||||
event.target.value = num.toString();
|
||||
globalStore.setSystemStatus({ autoBackupInterval: num });
|
||||
await api.upsertSystemSetting({
|
||||
name: "auto-backup-interval",
|
||||
value: JSON.stringify(num),
|
||||
});
|
||||
};
|
||||
|
||||
const handleAutoBackupIntervalFocus = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
event.target.select();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container system-section-container">
|
||||
<p className="title-text">{t("common.basic")}</p>
|
||||
@ -319,23 +292,6 @@ const SystemSection = () => {
|
||||
onChange={handleMaxUploadSizeChanged}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="flex flex-row items-center">
|
||||
<span className="text-sm mr-1">{t("setting.system-section.auto-backup-interval")}</span>
|
||||
<Tooltip title={t("setting.system-section.auto-backup-interval-hint")} placement="top">
|
||||
<Icon.HelpCircle className="w-4 h-auto" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Input
|
||||
className="w-16"
|
||||
sx={{
|
||||
fontFamily: "monospace",
|
||||
}}
|
||||
defaultValue={state.autoBackupInterval}
|
||||
onFocus={handleAutoBackupIntervalFocus}
|
||||
onChange={handleAutoBackupIntervalChanged}
|
||||
/>
|
||||
</div>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
<div className="flex flex-row items-center">
|
||||
|
@ -2,7 +2,7 @@
|
||||
@apply relative flex flex-col justify-start items-start w-full p-4 pt-3 mb-2 bg-white dark:bg-zinc-700 rounded-lg border border-white dark:border-zinc-600 hover:border-gray-200 dark:hover:border-zinc-600;
|
||||
|
||||
&.pinned {
|
||||
@apply border-gray-200 border-2 dark:border-zinc-600;
|
||||
@apply border-gray-200 border dark:border-zinc-600;
|
||||
}
|
||||
|
||||
> .memo-top-wrapper {
|
||||
|
@ -327,8 +327,6 @@
|
||||
"additional-style": "Zusätzlicher Stil",
|
||||
"additional-style-placeholder": "Zusätzliches CSS",
|
||||
"allow-user-signup": "Erlaube Registrierung neuer Mitglieder",
|
||||
"auto-backup-interval": "Intervall für automatische Sicherung (Sekunden)",
|
||||
"auto-backup-interval-hint": "Setze den Wert auf 0, um die automatische Sicherung zu deaktivieren. Nach Änderung dieses Wertes ist ein Neustart erforderlich.",
|
||||
"customize-server": {
|
||||
"appearance": "Erscheinungsbild",
|
||||
"default": "Standard: memos",
|
||||
|
@ -255,8 +255,6 @@
|
||||
"disable-public-memos": "Disable public memos",
|
||||
"max-upload-size": "Maximum upload size (MiB)",
|
||||
"max-upload-size-hint": "Recommended value is 32 MiB.",
|
||||
"auto-backup-interval": "Auto backup interval (seconds)",
|
||||
"auto-backup-interval-hint": "Set 0 to disable auto backup. Reboot is required after changing this value.",
|
||||
"additional-style": "Additional style",
|
||||
"additional-script": "Additional script",
|
||||
"additional-style-placeholder": "Additional CSS code",
|
||||
|
@ -335,8 +335,6 @@
|
||||
"additional-style": "Style supplémentaire",
|
||||
"additional-style-placeholder": "Codes CSS supplémentaires",
|
||||
"allow-user-signup": "Autoriser l'inscription des utilisateurs",
|
||||
"auto-backup-interval": "Intervalle de sauvegarde automatique (secondes)",
|
||||
"auto-backup-interval-hint": "La valeur 0 désactive la sauvegarde automatique. Un redémarrage est nécessaire après avoir modifié cette valeur.",
|
||||
"customize-server": {
|
||||
"appearance": "Apparence du Serveur",
|
||||
"default": "Par défaut memos",
|
||||
|
@ -335,8 +335,6 @@
|
||||
"additional-style": "Dodatni stil",
|
||||
"additional-style-placeholder": "Dodatni CSS kod",
|
||||
"allow-user-signup": "Dopusti registraciju drugih korisnika",
|
||||
"auto-backup-interval": "Interval u kojem će se izvršavati automatski backup (u sekundama)",
|
||||
"auto-backup-interval-hint": "Unesi 0 kako bi onemogućio automatski backup. Nakon mijenjanja ove vrijednosti potreban je reboot.",
|
||||
"customize-server": {
|
||||
"appearance": "Izgled Servera",
|
||||
"default": "Osnovno je memoi",
|
||||
|
@ -320,8 +320,6 @@
|
||||
"additional-style": "Stile aggiuntivo",
|
||||
"additional-style-placeholder": "Codice CSS aggiuntivo",
|
||||
"allow-user-signup": "Consenti registrazione utente",
|
||||
"auto-backup-interval": "Intervallo auto backup (secondi)",
|
||||
"auto-backup-interval-hint": "Inserire 0 per disattivare backup automatici. È richiesto il riavvio per salvare l'impostazione.",
|
||||
"customize-server": {
|
||||
"appearance": "Aspetto server",
|
||||
"default": "Preferinito è Memos",
|
||||
|
@ -318,8 +318,6 @@
|
||||
"additional-style": "追加CSS",
|
||||
"additional-style-placeholder": "CSSのコードを追加してください。",
|
||||
"allow-user-signup": "ユーザー登録を有効にする",
|
||||
"auto-backup-interval": "自動バックアップの間隔(秒)",
|
||||
"auto-backup-interval-hint": "自動バックアップを無効にするには0を設定してください。この値を変更した後、再起動が必要です。",
|
||||
"customize-server": {
|
||||
"appearance": "サーバーの外観",
|
||||
"default": "デフォルトではmemosです",
|
||||
|
@ -331,8 +331,6 @@
|
||||
"additional-style": "추가적인 스타일",
|
||||
"additional-style-placeholder": "추가적인 CSS 코드",
|
||||
"allow-user-signup": "회원등록 허용",
|
||||
"auto-backup-interval": "자동 백업 주기 (초)",
|
||||
"auto-backup-interval-hint": "0으로 설정하면 자동 백업을 비활성화합니다. 이 설정을 바꾼 뒤에는 재시작이 필요합니다.",
|
||||
"customize-server": {
|
||||
"appearance": "서버 테마",
|
||||
"default": "기본값은 memos",
|
||||
|
@ -182,8 +182,6 @@
|
||||
"disable-public-memos": "Openbare memos uitzetten",
|
||||
"max-upload-size": "Maximum uploadgrootte (MiB)",
|
||||
"max-upload-size-hint": "32 MiB wordt aangeraden.",
|
||||
"auto-backup-interval": "Automatische backupinterval (seconden)",
|
||||
"auto-backup-interval-hint": "Kies 0 om de automatische backup uit te zetten. Herstart van memos is nodig na deze aanpassing.",
|
||||
"display-with-updated-time": "Laten zien met bewerkte tijd",
|
||||
"telegram-bot-token": "Telegram bot token",
|
||||
"telegram-bot-token-description": "Telegram bot token of API proxy zoals `http://.../bot<token>`",
|
||||
|
@ -335,8 +335,6 @@
|
||||
"additional-style": "Estilo adicional",
|
||||
"additional-style-placeholder": "Código CSS adicional",
|
||||
"allow-user-signup": "Permitir registro de usuário",
|
||||
"auto-backup-interval": "Intervalo para backup automático (segundos)",
|
||||
"auto-backup-interval-hint": "Defina como 0 para desabilitar o backup automático. É necessário reiniciar após alterar esse valor.",
|
||||
"customize-server": {
|
||||
"appearance": "Aparência do servidor",
|
||||
"default": "O padrão é memos",
|
||||
|
@ -331,8 +331,6 @@
|
||||
"additional-style": "自定义样式",
|
||||
"additional-style-placeholder": "自定义 CSS 代码",
|
||||
"allow-user-signup": "允许用户注册",
|
||||
"auto-backup-interval": "自动备份间隔(单位:秒)",
|
||||
"auto-backup-interval-hint": "设置为 0 禁止自动备份,重启后生效。",
|
||||
"customize-server": {
|
||||
"appearance": "服务器外观",
|
||||
"default": "默认为 memos",
|
||||
|
@ -335,8 +335,6 @@
|
||||
"additional-style": "自訂樣式",
|
||||
"additional-style-placeholder": "自訂 CSS 代碼",
|
||||
"allow-user-signup": "允許使用者註冊",
|
||||
"auto-backup-interval": "自動備份間隔(單位:秒)",
|
||||
"auto-backup-interval-hint": "設定為 0 則禁止自動備份,需重新啟動後生效。",
|
||||
"customize-server": {
|
||||
"appearance": "伺服器外觀",
|
||||
"default": "預設為 memos",
|
||||
|
@ -16,7 +16,6 @@ export const initialGlobalState = async () => {
|
||||
disablePasswordLogin: false,
|
||||
disablePublicMemos: false,
|
||||
maxUploadSizeMiB: 0,
|
||||
autoBackupInterval: 0,
|
||||
additionalStyle: "",
|
||||
additionalScript: "",
|
||||
memoDisplayWithUpdatedTs: false,
|
||||
|
1
web/src/types/modules/system.d.ts
vendored
1
web/src/types/modules/system.d.ts
vendored
@ -21,7 +21,6 @@ interface SystemStatus {
|
||||
disablePasswordLogin: boolean;
|
||||
disablePublicMemos: boolean;
|
||||
maxUploadSizeMiB: number;
|
||||
autoBackupInterval: number;
|
||||
additionalStyle: string;
|
||||
additionalScript: string;
|
||||
customizedProfile: CustomizedProfile;
|
||||
|
Loading…
Reference in New Issue
Block a user