Skip to content

Commit d30ff0e

Browse files
committed
fix: update the table building
This fixes some misconfiguration that resulted in some empty tables, it also cleans up the calling mechanism to build the database
1 parent b877ad9 commit d30ff0e

14 files changed

+197
-203
lines changed

cmd/deltadb/main.go

+20-54
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,19 @@ package main
22

33
import (
44
"context"
5-
"database/sql"
65
"flag"
76
"fmt"
87
"log"
9-
"net/url"
108
"os"
119
"time"
1210

1311
"github.com/GeoNet/delta"
14-
"github.com/GeoNet/delta/meta/sqlite"
15-
"github.com/GeoNet/delta/resp"
16-
17-
_ "modernc.org/sqlite"
1812
)
1913

2014
type Settings struct {
21-
debug bool // output more operational info
22-
2315
base string // base directory of delta files on disk
2416
resp string // base directory of resp files on disk
25-
26-
db string // name of the database file
27-
response string // name of the database response table
28-
29-
init bool // should the database be updated
17+
path string // name of the database file
3018
}
3119

3220
func main() {
@@ -35,7 +23,7 @@ func main() {
3523

3624
flag.Usage = func() {
3725
fmt.Fprintf(os.Stderr, "\n")
38-
fmt.Fprintf(os.Stderr, "Build a DELTA Sqlite DB file\n")
26+
fmt.Fprintf(os.Stderr, "Build and initialise a DELTA Sqlite database\n")
3927
fmt.Fprintf(os.Stderr, "\n")
4028
fmt.Fprintf(os.Stderr, "Usage:\n")
4129
fmt.Fprintf(os.Stderr, "\n")
@@ -47,12 +35,9 @@ func main() {
4735
fmt.Fprintf(os.Stderr, "\n")
4836
}
4937

50-
flag.BoolVar(&settings.debug, "debug", false, "add extra operational info")
51-
flag.BoolVar(&settings.init, "init", false, "initialise the database if a file on disk")
52-
flag.StringVar(&settings.base, "base", "", "base directory of delta files on disk")
53-
flag.StringVar(&settings.resp, "resp", "", "base directory of resp files on disk")
54-
flag.StringVar(&settings.db, "db", "", "name of the database file on disk")
55-
flag.StringVar(&settings.response, "response", "Response", "optional database response table name to use")
38+
flag.StringVar(&settings.base, "base", "", "base directory of delta files on disk, default uses embedded files")
39+
flag.StringVar(&settings.resp, "resp", "", "base directory of resp files on disk, default uses embedded files")
40+
flag.StringVar(&settings.path, "path", "", "name of the database file on disk, default is to use memory only")
5641

5742
flag.Parse()
5843

@@ -64,49 +49,30 @@ func main() {
6449
log.Fatal(err)
6550
}
6651

67-
// resp recovers the response files
68-
files, err := resp.ListBase(settings.resp)
52+
// recover any response files
53+
files, err := delta.NewResp(settings.resp)
6954
if err != nil {
7055
log.Fatal(err)
7156
}
7257

73-
values := make(map[string]string)
74-
for _, f := range files {
75-
lookup, err := resp.LookupBase(settings.resp, f)
76-
if err != nil {
77-
log.Fatal(err)
78-
}
79-
values[f] = string(lookup)
80-
}
81-
82-
path := ":memory:"
83-
if settings.db != "" {
84-
path = settings.db
85-
}
86-
87-
opts := url.Values{}
88-
opts.Set("_time_format", "sqlite")
89-
opts.Set("_foreign_keys", "on")
90-
if settings.db != "" && !settings.init {
91-
opts.Set("mode", "ro")
92-
}
93-
94-
db, err := sql.Open("sqlite", fmt.Sprintf("file:%s?%s", path, url.QueryEscape(opts.Encode())))
58+
// open the database file handle
59+
db, err := delta.NewDB(settings.path)
9560
if err != nil {
96-
log.Fatalf("unable to open database %s: %v", path, err)
61+
log.Fatalf("unable to open database %q: %v", settings.path, err)
9762
}
9863
defer db.Close()
9964

100-
if settings.db == "" || settings.init {
65+
start := time.Now()
10166

102-
// insert extra response files
103-
extra := set.KeyValue(settings.response, "Response", "XML", values)
67+
// initialise the database
68+
if err := db.Init(ctx, set, files...); err != nil {
69+
log.Fatalf("unable to init database: %v", err)
70+
}
10471

105-
log.Println("initialise database")
106-
start := time.Now()
107-
if err := sqlite.New(db).Init(ctx, set.TableList(extra)); err != nil {
108-
log.Fatalf("unable to run database exec: %v", err)
109-
}
110-
log.Printf("database initialised in %s", time.Since(start).String())
72+
switch {
73+
case settings.path != "":
74+
log.Printf("successfully initialised %q in %s", settings.path, time.Since(start).Truncate(time.Millisecond).String())
75+
default:
76+
log.Printf("successfully initialised memory in %s", time.Since(start).Truncate(time.Millisecond).String())
11177
}
11278
}

delta.go

+63
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
package delta
22

33
import (
4+
"context"
5+
"database/sql"
46
"embed"
7+
"fmt"
58
"io/fs"
9+
"net/url"
610
"os"
711
"sync"
812

13+
_ "modernc.org/sqlite"
14+
915
"github.com/GeoNet/delta/meta"
16+
"github.com/GeoNet/delta/meta/sqlite"
17+
"github.com/GeoNet/delta/resp"
1018
)
1119

20+
const ResponseName = "Response"
21+
1222
//go:embed assets/*.csv
1323
//go:embed install/*.csv
1424
//go:embed network/*.csv
@@ -51,3 +61,56 @@ func NewBase(base string) (*meta.Set, error) {
5161
}
5262
return New()
5363
}
64+
65+
// NewResp returns a slice of response file names.
66+
func NewResp(base string) ([]string, error) {
67+
return resp.ListBase(base)
68+
}
69+
70+
// DB is a wrapper for an SQL DB pointer.
71+
type DB struct {
72+
*sql.DB
73+
}
74+
75+
// NewDB returns a DB pointer, a non-empty path is used as a file name, otherwise the database is generated in memory.
76+
func NewDB(path ...string) (*DB, error) {
77+
78+
file := ":memory:"
79+
for _, p := range path {
80+
file = p
81+
}
82+
83+
opts := url.Values{}
84+
opts.Set("_time_format", "sqlite")
85+
opts.Set("_foreign_keys", "on")
86+
87+
db, err := sql.Open("sqlite", fmt.Sprintf("file:%s?%s", file, url.QueryEscape(opts.Encode())))
88+
if err != nil {
89+
return nil, err
90+
}
91+
92+
return &DB{DB: db}, nil
93+
}
94+
95+
// Init updates the contents of the given database with contents from the given delta base and response paths.
96+
// If these are empty then the default compiled in versions will be used.
97+
func (db *DB) Init(ctx context.Context, set *meta.Set, files ...string) error {
98+
99+
values := make(map[string]string)
100+
for _, file := range files {
101+
lookup, err := resp.Lookup(file)
102+
if err != nil {
103+
return err
104+
}
105+
values[file] = string(lookup)
106+
}
107+
108+
// insert any extra response files
109+
extra := set.KeyValue(ResponseName, "Response", "XML", values)
110+
111+
if err := sqlite.New(db.DB).Init(ctx, set.TableList(extra)); err != nil {
112+
return err
113+
}
114+
115+
return nil
116+
}

delta_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package delta
22

33
import (
4+
"context"
45
"testing"
56
)
67

@@ -9,3 +10,26 @@ func TestDelta(t *testing.T) {
910
t.Fatal(err)
1011
}
1112
}
13+
14+
func TestDB(t *testing.T) {
15+
16+
set, err := NewBase("")
17+
if err != nil {
18+
t.Fatal(err)
19+
}
20+
21+
files, err := NewResp("")
22+
if err != nil {
23+
t.Fatal(err)
24+
}
25+
26+
db, err := NewDB()
27+
if err != nil {
28+
t.Fatal(err)
29+
}
30+
defer db.Close()
31+
32+
if err := db.Init(context.Background(), set, files...); err != nil {
33+
t.Fatal(err)
34+
}
35+
}

0 commit comments

Comments
 (0)