Files
nib-v1/cmd/export.go
T
lerko 2152baeb4f feat: add export and backup commands
- nib export: dump all entities to JSON (stdout or --output file)
- nib backup: atomic SQLite backup via VACUUM INTO (WAL-safe)
- Store.Backup() method on db layer
- Tests for both commands
2026-05-20 20:54:44 -04:00

114 lines
2.7 KiB
Go

package cmd
import (
"encoding/json"
"fmt"
"os"
"github.com/lerko/nib/internal/db"
"github.com/spf13/cobra"
)
var exportOutput string
var exportCmd = &cobra.Command{
Use: "export",
Short: "dump all entities to JSON",
RunE: runExport,
}
func init() {
exportCmd.Flags().StringVarP(&exportOutput, "output", "o", "", "write to file instead of stdout")
rootCmd.AddCommand(exportCmd)
}
type exportEntity struct {
ID string `json:"id"`
CreatedAt string `json:"created_at"`
ModifiedAt string `json:"modified_at"`
Body string `json:"body"`
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
Glyph string `json:"glyph"`
TimeAnchor *string `json:"time_anchor,omitempty"`
CompletedAt *string `json:"completed_at,omitempty"`
Pinned bool `json:"pinned"`
DeletedAt *string `json:"deleted_at,omitempty"`
Tags []string `json:"tags"`
CardType *string `json:"card_type,omitempty"`
CardData *string `json:"card_data,omitempty"`
UseCount int `json:"use_count"`
LastUsedAt *string `json:"last_used_at,omitempty"`
}
func runExport(cmd *cobra.Command, _ []string) error {
store, err := openStore()
if err != nil {
return err
}
defer store.Close()
ctx := cmd.Context()
p := db.DefaultListParams()
p.IncludeDeleted = true
p.Limit = 10000
entities, err := store.List(ctx, p)
if err != nil {
return err
}
out := make([]exportEntity, len(entities))
for i, e := range entities {
out[i] = exportEntity{
ID: e.ID,
CreatedAt: e.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
ModifiedAt: e.ModifiedAt.Format("2006-01-02T15:04:05Z07:00"),
Body: e.Body,
Title: e.Title,
Glyph: string(e.Glyph),
TimeAnchor: e.TimeAnchor,
Pinned: e.Pinned,
Tags: e.Tags,
CardData: e.CardData,
UseCount: e.UseCount,
}
if e.Description != nil {
out[i].Description = e.Description
}
if e.CompletedAt != nil {
s := e.CompletedAt.Format("2006-01-02T15:04:05Z07:00")
out[i].CompletedAt = &s
}
if e.DeletedAt != nil {
s := e.DeletedAt.Format("2006-01-02T15:04:05Z07:00")
out[i].DeletedAt = &s
}
if e.CardType != nil {
s := string(*e.CardType)
out[i].CardType = &s
}
if e.LastUsedAt != nil {
s := e.LastUsedAt.Format("2006-01-02T15:04:05Z07:00")
out[i].LastUsedAt = &s
}
}
data, err := json.MarshalIndent(out, "", " ")
if err != nil {
return err
}
if exportOutput != "" {
if err := os.WriteFile(exportOutput, data, 0o600); err != nil {
return err
}
fmt.Fprintf(cmd.ErrOrStderr(), "exported %d entities to %s\n", len(out), exportOutput)
return nil
}
fmt.Println(string(data))
return nil
}