Skip to content

Commit 3247f27

Browse files
committed
add export for pmg 2.1
1 parent 3c0d75f commit 3247f27

File tree

15 files changed

+933
-4
lines changed

15 files changed

+933
-4
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
## [0.3] - 2025-03-10
4+
5+
### Added
6+
7+
- Export method for Papermerge DMS 2.1 for postgres and sqlite3

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ Tool for migrating Papermerge DMS data between different versions.
55
Basically you export data from one (older) version as tar.gz archive and import it
66
into the 3.4 (latest).
77

8-
For PMDump version 0.2 `export` command works for following Papermerge DMS versions/databases
8+
For PMDump version 0.3 `export` command works for following Papermerge DMS versions/databases
99

1010
| db/pmg version | 2.0 | 2.1 | 3.2 | 3.3 |
1111
|------------------|------|-------|-------------|-----|
12-
| SQLite || 🚧 |||
13-
| PostgreSQL || 🚧 |||
12+
| SQLite || |||
13+
| PostgreSQL || |||
1414

1515
Currently `import` command works to import only into 3.4 either SQLite or PostgreSQL database.
1616

1717
- ✅ - means: it works
1818
- ❌ - means: no plans to implement this part yet. If you need this to be implemented, please
1919
[open a ticket](https://github.com/ciur/papermerge/issues) and provide docker compose with your setup.
20-
- 🚧 - means: work in progress. Will be available soon.
20+
2121

2222
## Get It
2323

commands/exp/app_v2_1/api.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package exporter_app_v2_1
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/google/uuid"
8+
"github.com/papermerge/pmdump/config"
9+
"github.com/papermerge/pmdump/database"
10+
"github.com/papermerge/pmdump/exporter"
11+
models "github.com/papermerge/pmdump/models/app_v3_3"
12+
"github.com/papermerge/pmdump/types"
13+
)
14+
15+
func PerformExport(
16+
settings config.Config,
17+
targetFile,
18+
exportYaml string,
19+
) []types.FilePath {
20+
var filePaths []types.FilePath
21+
22+
db, err := database.Open(settings.DatabaseURL, types.AppVersion(settings.AppVersion))
23+
if err != nil {
24+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
25+
os.Exit(1)
26+
}
27+
defer db.DB.Close()
28+
29+
results, err := database.GetUsers(db)
30+
if err != nil {
31+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
32+
os.Exit(1)
33+
}
34+
35+
users := results.([]models.User)
36+
37+
for i := 0; i < len(users); i++ {
38+
39+
database.GetUserNodes(db, &users[i])
40+
models.ForEachDocument(
41+
db,
42+
users[i].Home,
43+
database.InsertDocVersionsAndPages,
44+
)
45+
models.ForEachDocument(
46+
db,
47+
users[i].Inbox,
48+
database.InsertDocVersionsAndPages,
49+
)
50+
}
51+
52+
for i := 0; i < len(users); i++ {
53+
var allDocs []models.Node
54+
55+
inbox := users[i].Inbox.GetUserDocuments()
56+
home := users[i].Home.GetUserDocuments()
57+
allDocs = append(allDocs, inbox...)
58+
allDocs = append(allDocs, home...)
59+
userFilePaths, err := GetFilePaths(allDocs, users[i].ID, settings.MediaRoot)
60+
61+
if err != nil {
62+
fmt.Fprintf(os.Stderr, "error getting file paths: %v\n", err)
63+
}
64+
65+
filePaths = append(filePaths, userFilePaths...)
66+
}
67+
68+
payload := models.Data{
69+
Users: users,
70+
}
71+
72+
err = exporter.CreateYAML(
73+
exportYaml,
74+
payload,
75+
types.V3_2,
76+
)
77+
if err != nil {
78+
fmt.Fprintf(os.Stderr, "Error writing to file: %v", err)
79+
os.Exit(1)
80+
}
81+
82+
return filePaths
83+
}
84+
85+
func GetFilePaths(docs []models.Node, user_id uuid.UUID, mediaRoot string) ([]types.FilePath, error) {
86+
var paths []types.FilePath
87+
88+
for _, doc := range docs {
89+
for _, docVer := range doc.Versions {
90+
var source string
91+
92+
uid := docVer.ID.String()
93+
94+
source = fmt.Sprintf(
95+
"%s/docs/user_%s/document_%s/v%d/%s",
96+
mediaRoot,
97+
user_id.String(),
98+
doc.ID.String(),
99+
docVer.Number,
100+
docVer.FileName,
101+
)
102+
103+
dest := fmt.Sprintf("docvers/%s/%s/%s/%s", uid[0:2], uid[2:4], uid, docVer.FileName)
104+
path := types.FilePath{
105+
Source: source,
106+
Dest: dest,
107+
}
108+
paths = append(paths, path)
109+
}
110+
}
111+
112+
return paths, nil
113+
}

commands/exp/exp.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
exporter_app_v2_0 "github.com/papermerge/pmdump/commands/exp/app_v2_0"
11+
exporter_app_v2_1 "github.com/papermerge/pmdump/commands/exp/app_v2_1"
1112
exporter_app_v3_2 "github.com/papermerge/pmdump/commands/exp/app_v3_2"
1213
exporter_app_v3_3 "github.com/papermerge/pmdump/commands/exp/app_v3_3"
1314
"github.com/papermerge/pmdump/config"
@@ -28,6 +29,8 @@ func PerformExport(settings config.Config, targetFile, exportYaml string) {
2829
filePaths = exporter_app_v2_0.PerformExport(settings, targetFile, exportYaml)
2930
case string(types.V3_3):
3031
filePaths = exporter_app_v3_3.PerformExport(settings, targetFile, exportYaml)
32+
case string(types.V2_1):
33+
filePaths = exporter_app_v2_1.PerformExport(settings, targetFile, exportYaml)
3134
case string(types.V3_2):
3235
filePaths = exporter_app_v3_2.PerformExport(settings, targetFile, exportYaml)
3336
default:

database/api.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
database_app_v2_0 "github.com/papermerge/pmdump/database/app_v2_0"
7+
database_app_v2_1 "github.com/papermerge/pmdump/database/app_v2_1"
78
database_app_v3_2 "github.com/papermerge/pmdump/database/app_v3_2"
89
database_app_v3_3 "github.com/papermerge/pmdump/database/app_v3_3"
910
database_app_v3_4 "github.com/papermerge/pmdump/database/app_v3_4"
@@ -15,6 +16,8 @@ func Open(dburl string, appVer types.AppVersion) (*types.DBConn, error) {
1516
switch appVer {
1617
case types.V2_0:
1718
return database_app_v2_0.Open(dburl, appVer)
19+
case types.V2_1:
20+
return database_app_v2_1.Open(dburl, appVer)
1821
case types.V3_3, types.V3_4:
1922
return database_app_v3_3.Open(dburl, appVer)
2023
case types.V3_2:
@@ -32,6 +35,8 @@ func GetUsers(db *types.DBConn) (any, error) {
3235
return database_app_v3_3.GetUsers(db.DB)
3336
case types.V3_2:
3437
return database_app_v3_2.GetUsers(db.DB)
38+
case types.V2_1:
39+
return database_app_v2_1.GetUsers(db.DB)
3540
}
3641

3742
return nil, fmt.Errorf("database GetUsers: app version %q not supported", db.AppVersion)
@@ -144,6 +149,8 @@ func GetHomeFlatNodes(db *types.DBConn, user_id interface{}) (interface{}, error
144149
return database_app_v3_3.GetHomeFlatNodes(db, user_id)
145150
case types.V3_2:
146151
return database_app_v3_2.GetHomeFlatNodes(db, user_id)
152+
case types.V2_1:
153+
return database_app_v2_1.GetHomeFlatNodes(db, user_id)
147154
}
148155

149156
return nil, fmt.Errorf("database GetHomeFlatNodes: app version %q not supported", db.AppVersion)
@@ -157,6 +164,8 @@ func GetInboxFlatNodes(db *types.DBConn, user_id interface{}) (interface{}, erro
157164
return database_app_v3_3.GetInboxFlatNodes(db, user_id)
158165
case types.V3_2:
159166
return database_app_v3_2.GetInboxFlatNodes(db, user_id)
167+
case types.V2_1:
168+
return database_app_v2_1.GetInboxFlatNodes(db, user_id)
160169
}
161170

162171
return nil, fmt.Errorf("database GetInboxFlatNodes: app version %q not supported", db.AppVersion)
@@ -170,6 +179,8 @@ func GetUserNodes(db *types.DBConn, user interface{}) error {
170179
return database_app_v3_3.GetUserNodes(db, &user)
171180
case types.V3_2:
172181
return database_app_v3_2.GetUserNodes(db, &user)
182+
case types.V2_1:
183+
return database_app_v2_1.GetUserNodes(db, &user)
173184
}
174185

175186
return fmt.Errorf("database GetUserNodes: app version %q not supported", db.AppVersion)
@@ -197,6 +208,8 @@ func InsertDocVersionsAndPages(db *types.DBConn, node any) error {
197208
database_app_v3_3.InsertDocVersionsAndPages(db, node)
198209
case types.V3_2:
199210
database_app_v3_2.InsertDocVersionsAndPages(db, node)
211+
case types.V2_1:
212+
database_app_v2_1.InsertDocVersionsAndPages(db, node)
200213
}
201214

202215
return fmt.Errorf("database InsertDocVersionsAndPages: app version %q not supported", db.AppVersion)

database/app_v2_1/api.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package database_app_v2_1
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"strings"
7+
8+
postgres_db "github.com/papermerge/pmdump/database/app_v3_2/postgres"
9+
sqlite_db "github.com/papermerge/pmdump/database/app_v3_2/sqlite"
10+
11+
"github.com/papermerge/pmdump/types"
12+
)
13+
14+
func Open(dburl string, appVer types.AppVersion) (*types.DBConn, error) {
15+
parsedDBURL, err := url.Parse(dburl)
16+
17+
if err != nil {
18+
return nil, fmt.Errorf("Error parsing dburl %s: %v", dburl, err)
19+
}
20+
21+
if strings.HasPrefix(parsedDBURL.Scheme, "sqlite") {
22+
db, err := sqlite_db.Open(parsedDBURL.Path)
23+
if err != nil {
24+
return nil, err
25+
}
26+
dbconn := types.DBConn{
27+
AppVersion: appVer,
28+
DBType: types.SQLite,
29+
DB: db,
30+
}
31+
32+
return &dbconn, nil
33+
}
34+
35+
if strings.HasPrefix(parsedDBURL.Scheme, "postgres") {
36+
db, err := postgres_db.Open(dburl)
37+
if err != nil {
38+
return nil, err
39+
}
40+
dbconn := types.DBConn{
41+
AppVersion: appVer,
42+
DBType: types.Postgres,
43+
DB: db,
44+
}
45+
46+
return &dbconn, nil
47+
}
48+
49+
return nil, fmt.Errorf("database open: app version %q not supported", appVer)
50+
}
51+
52+
func GetHomeFlatNodes(db *types.DBConn, user_id interface{}) (interface{}, error) {
53+
switch db.DBType {
54+
case types.SQLite:
55+
return sqlite_db.GetHomeFlatNodes(db.DB, user_id)
56+
case types.Postgres:
57+
return postgres_db.GetHomeFlatNodes(db.DB, user_id)
58+
}
59+
60+
return nil, fmt.Errorf("database GetHomeFlatNodes: db type %q not supported", db.DBType)
61+
}
62+
63+
func GetInboxFlatNodes(db *types.DBConn, user_id interface{}) (interface{}, error) {
64+
switch db.DBType {
65+
case types.SQLite:
66+
return sqlite_db.GetInboxFlatNodes(db.DB, user_id)
67+
case types.Postgres:
68+
return postgres_db.GetInboxFlatNodes(db.DB, user_id)
69+
}
70+
71+
err := fmt.Errorf(
72+
"database GetInboxFlatNodes: db type %q not supported",
73+
db.DBType,
74+
)
75+
76+
return nil, err
77+
}
78+
79+
func GetUserNodes(db *types.DBConn, user *interface{}) error {
80+
switch db.DBType {
81+
case types.SQLite:
82+
return sqlite_db.GetUserNodes(db.DB, user)
83+
case types.Postgres:
84+
return postgres_db.GetUserNodes(db.DB, user)
85+
}
86+
87+
return fmt.Errorf(
88+
"database GetUserNodes: db type %q not supported",
89+
db.DBType,
90+
)
91+
}
92+
93+
func InsertDocVersionsAndPages(db *types.DBConn, node any) error {
94+
switch db.DBType {
95+
case types.SQLite:
96+
sqlite_db.InsertDocVersionsAndPages(db.DB, node)
97+
case types.Postgres:
98+
postgres_db.InsertDocVersionsAndPages(db.DB, node)
99+
}
100+
101+
return fmt.Errorf(
102+
"database GetDocumentPageRows: db type %q not supported",
103+
db.DBType,
104+
)
105+
106+
}

0 commit comments

Comments
 (0)