Skip to content

Commit e39d6b3

Browse files
committed
update migration code for latest surrealdb
1 parent 9dc38a0 commit e39d6b3

File tree

3 files changed

+85
-63
lines changed

3 files changed

+85
-63
lines changed

database/surrealdb/examples/migrations/33_create_table.up.surql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ DEFINE FIELD lastName ON TABLE user TYPE string
1010
ASSERT $value != NONE;
1111
DEFINE FIELD email ON TABLE user TYPE string
1212
ASSERT $value != NONE AND string::is::email($value);
13-
DEFINE INDEX userEmailIndex ON TABLE user COLUMNS email UNIQUE;
1413

1514
COMMIT;

database/surrealdb/surrealdb.go

Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package surrealdb
22

33
import (
4+
"context"
45
"fmt"
56
"io"
67
nurl "net/url"
@@ -11,6 +12,7 @@ import (
1112
"github.com/golang-migrate/migrate/v4/database"
1213
"github.com/hashicorp/go-multierror"
1314
"github.com/surrealdb/surrealdb.go"
15+
"github.com/surrealdb/surrealdb.go/pkg/models"
1416
)
1517

1618
func init() {
@@ -42,35 +44,19 @@ type SurrealDB struct {
4244
config *Config
4345
}
4446

45-
type DBInfo struct {
46-
DL map[string]string `json:"dl"`
47-
DT map[string]string `json:"dt"`
48-
FC map[string]string `json:"fc"`
49-
PA map[string]string `json:"pa"`
50-
SC map[string]string `json:"sc"`
51-
TB map[string]string `json:"tb"`
52-
}
53-
5447
type VersionInfo struct {
5548
ID string `json:"id,omitempty"`
5649
Version int `json:"version,omitempty"`
5750
Dirty bool `json:"dirty,omitempty"`
5851
}
5952

60-
type LockDoc struct {
61-
ID string `json:"id,omitempty"`
62-
Pid int `json:"pid,omitempty"`
63-
Hostname string `json:"hostname,omitempty"`
64-
CreatedAt string `json:"created_at,omitempty"`
65-
}
66-
6753
func WithInstance(instance *surrealdb.DB, config *Config) (database.Driver, error) {
6854
if config == nil {
6955
return nil, ErrNilConfig
7056
}
7157

72-
if _, err := instance.Info(); err != nil {
73-
return nil, err
58+
if instance == nil {
59+
return nil, fmt.Errorf("instance is nil")
7460
}
7561

7662
if len(config.MigrationsTable) == 0 {
@@ -115,6 +101,7 @@ func (m *SurrealDB) ensureVersionTable() (err error) {
115101
}
116102

117103
func (m *SurrealDB) Open(url string) (database.Driver, error) {
104+
ctx := context.Background()
118105
purl, err := nurl.Parse(url)
119106
if err != nil {
120107
return nil, err
@@ -154,20 +141,20 @@ func (m *SurrealDB) Open(url string) (database.Driver, error) {
154141

155142
connUrl := fmt.Sprintf("%s://%s/rpc", scheme, host)
156143

157-
db, err := surrealdb.New(connUrl)
144+
db, err := surrealdb.FromEndpointURLString(ctx, connUrl)
158145
if err != nil {
159146
return nil, err
160147
}
161148

162-
_, err = db.Signin(map[string]interface{}{
163-
"user": username,
164-
"pass": password,
149+
_, err = db.SignIn(ctx, &surrealdb.Auth{
150+
Username: username,
151+
Password: password,
165152
})
166153
if err != nil {
167154
return nil, err
168155
}
169156

170-
_, err = db.Use(namespace, database_name)
157+
err = db.Use(ctx, namespace, database_name)
171158
if err != nil {
172159
return nil, err
173160
}
@@ -185,22 +172,29 @@ func (m *SurrealDB) Open(url string) (database.Driver, error) {
185172
}
186173

187174
func (m *SurrealDB) Close() error {
188-
m.db.Close()
175+
m.db.Close(context.Background())
189176
return nil
190177
}
191178

192179
func (m *SurrealDB) Drop() (err error) {
193180
query := `INFO FOR DB;`
194-
result, err := surrealdb.SmartUnmarshal[DBInfo](m.db.Query(query, map[string]interface{}{}))
181+
results, err := surrealdb.Query[map[string]any](context.Background(), m.db, query, map[string]any{})
195182
if err != nil {
196183
return err
197184
}
198185

199-
for tableName := range result.TB {
200-
query := fmt.Sprintf(`REMOVE TABLE %s;`, tableName)
201-
_, err := m.db.Query(query, map[string]interface{}{})
202-
if err != nil {
203-
return err
186+
if results == nil || len(*results) == 0 {
187+
return nil
188+
}
189+
result := (*results)[0].Result
190+
191+
if tables, ok := result["tb"].(map[string]any); ok {
192+
for tableName := range tables {
193+
query := fmt.Sprintf(`REMOVE TABLE %s;`, tableName)
194+
_, err := surrealdb.Query[any](context.Background(), m.db, query, map[string]any{})
195+
if err != nil {
196+
return err
197+
}
204198
}
205199
}
206200

@@ -215,17 +209,25 @@ func (m *SurrealDB) Lock() error {
215209
}
216210

217211
lock_doc_id := m.config.GetLockDocumentId()
212+
parsed_id, err := models.ParseRecordID(lock_doc_id)
213+
if err != nil {
214+
return err
215+
}
216+
218217
query := `BEGIN; CREATE $lock_doc_id SET pid = $pid, hostname = $hostname, created_at = $created_at; RETURN AFTER; COMMIT;`
219218

220-
// using m.db.Query looks to prevent a race condition that can occur when using m.db.Create
221-
// if you use m.db.Create its possible for a second lock call shortly after first to not error as it should
222-
_, err = surrealdb.SmartUnmarshal[[]LockDoc](
223-
m.db.Query(query, map[string]interface{}{
224-
"lock_doc_id": lock_doc_id,
219+
// using surrealdb.Query looks to prevent a race condition that can occur when using surrealdb.Create
220+
// if you use surrealdb.Create its possible for a second lock call shortly after first to not error as it should
221+
_, err = surrealdb.Query[any](
222+
context.Background(),
223+
m.db,
224+
query,
225+
map[string]any{
226+
"lock_doc_id": parsed_id,
225227
"pid": pid,
226228
"hostname": hostname,
227229
"created_at": time.Now().Format(time.RFC3339),
228-
}),
230+
},
229231
)
230232
if err != nil {
231233
return err
@@ -236,10 +238,15 @@ func (m *SurrealDB) Lock() error {
236238

237239
func (m *SurrealDB) Unlock() error {
238240
lock_doc_id := m.config.GetLockDocumentId()
241+
parsed_id, err := models.ParseRecordID(lock_doc_id)
242+
if err != nil {
243+
return err
244+
}
245+
239246
query := `BEGIN; LET $lock = SELECT * FROM $lock_doc_id; DELETE $lock; COMMIT;`
240247

241248
// Delete will error if lock_doc_id does not exist because $lock ends up as NONE
242-
_, err := m.db.Query(query, map[string]interface{}{"lock_doc_id": lock_doc_id})
249+
_, err = surrealdb.Query[any](context.Background(), m.db, query, map[string]any{"lock_doc_id": parsed_id})
243250
return err
244251
}
245252

@@ -250,21 +257,26 @@ func (m *SurrealDB) Run(migration io.Reader) error {
250257
}
251258

252259
query := string(mig[:])
253-
_, err = m.db.Query(query, map[string]interface{}{})
260+
_, err = surrealdb.Query[any](context.Background(), m.db, query, map[string]any{})
254261
return err
255262
}
256263

257264
func (m *SurrealDB) SetVersion(version int, dirty bool) error {
258265
version_document_id := m.config.GetVersionDocumentId()
259-
params := map[string]interface{}{"version_document_id": version_document_id}
266+
parsed_id, err := models.ParseRecordID(version_document_id)
267+
if err != nil {
268+
return err
269+
}
270+
271+
params := map[string]any{"version_document_id": parsed_id}
260272
query := `BEGIN; DELETE $version_document_id; `
261273

262274
// Also re-write the schema version for nil dirty versions to prevent
263275
// empty schema version for failed down migration on the first migration
264276
// See: https://github.com/golang-migrate/migrate/issues/330
265277
if version >= 0 || (version == database.NilVersion && dirty) {
266-
params = map[string]interface{}{
267-
"version_document_id": version_document_id,
278+
params = map[string]any{
279+
"version_document_id": parsed_id,
268280
"version": version,
269281
"dirty": dirty,
270282
}
@@ -276,7 +288,7 @@ func (m *SurrealDB) SetVersion(version int, dirty bool) error {
276288

277289
query += `COMMIT;`
278290

279-
_, err := m.db.Query(query, params)
291+
_, err = surrealdb.Query[any](context.Background(), m.db, query, params)
280292
if err != nil {
281293
return err
282294
}
@@ -286,12 +298,23 @@ func (m *SurrealDB) SetVersion(version int, dirty bool) error {
286298

287299
func (m *SurrealDB) Version() (version int, dirty bool, err error) {
288300
version_document_id := m.config.GetVersionDocumentId()
301+
parsed_id, err := models.ParseRecordID(version_document_id)
302+
if err != nil {
303+
return database.NilVersion, false, err
304+
}
289305

290-
query := fmt.Sprintf("SELECT * FROM %s;", version_document_id)
291-
versionInfo, err := surrealdb.SmartUnmarshal[[]VersionInfo](m.db.Query(query, map[string]interface{}{}))
306+
query := "SELECT * FROM $version_document_id;"
307+
results, err := surrealdb.Query[[]VersionInfo](context.Background(), m.db, query, map[string]any{"version_document_id": parsed_id})
292308
if err != nil {
293309
return database.NilVersion, false, err
294-
} else if len(versionInfo) == 0 {
310+
}
311+
312+
if results == nil || len(*results) == 0 {
313+
return database.NilVersion, false, nil
314+
}
315+
versionInfo := (*results)[0].Result
316+
317+
if len(versionInfo) == 0 {
295318
return database.NilVersion, false, nil
296319
}
297320

database/surrealdb/surrealdb_test.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ func TestErrorParsing(t *testing.T) {
128128
}
129129

130130
badQuery := "DEFINE TABLEE user SCHEMALESS;"
131-
wantErr := `sending request failed for method 'query': There was a problem with the database: Parse error: Failed to parse query at line 1 column 8 expected query to end`
131+
wantErr := `There was a problem with the database: Parse error:`
132132
if err := d.Run(strings.NewReader(badQuery)); err == nil {
133133
t.Fatal("expected err but got nil")
134-
} else if !strings.HasPrefix(err.Error(), wantErr) {
135-
t.Fatalf("expected '%s' to start with '%s'", err.Error(), wantErr)
134+
} else if !strings.Contains(err.Error(), wantErr) {
135+
t.Fatalf("expected '%s' to contain '%s'", err.Error(), wantErr)
136136
} else if !strings.Contains(err.Error(), badQuery) {
137137
t.Fatalf("expected err to contain %s", badQuery)
138138
}
@@ -189,26 +189,26 @@ func TestMigrationTable(t *testing.T) {
189189
t.Fatal(err)
190190
}
191191

192-
db, err := surrealdb.New(connInfo.getUrl())
192+
db, err := surrealdb.FromEndpointURLString(t.Context(), connInfo.getUrl())
193193
if err != nil {
194194
t.Fatal(err)
195195
}
196-
defer db.Close()
196+
defer db.Close(t.Context())
197197

198-
_, err = db.Signin(map[string]interface{}{
199-
"user": connInfo.User,
200-
"pass": connInfo.Pass,
198+
_, err = db.SignIn(t.Context(), &surrealdb.Auth{
199+
Username: "user",
200+
Password: "pass",
201201
})
202202
if err != nil {
203203
t.Fatal(err)
204204
}
205205

206-
_, err = db.Use(connInfo.NS, connInfo.DB)
206+
err = db.Use(t.Context(), connInfo.NS, connInfo.DB)
207207
if err != nil {
208208
t.Fatal(err)
209209
}
210210

211-
_, err = db.Query("SELECT * FROM schema_migrations:version", map[string]interface{}{})
211+
_, err = surrealdb.Query[[]any](t.Context(), db, "SELECT * FROM schema_migrations:version", map[string]any{})
212212
if err != nil {
213213
t.Fatal(err)
214214
}
@@ -343,25 +343,25 @@ func isReady(ctx context.Context, c dktest.ContainerInfo) bool {
343343
}
344344

345345
connInfo := getConnInfo(ip, port)
346-
db, err := surrealdb.New(connInfo.getUrl())
346+
db, err := surrealdb.FromEndpointURLString(ctx, connInfo.getUrl())
347347
if err != nil {
348348
return false
349349
}
350-
defer db.Close()
350+
defer db.Close(ctx)
351351

352-
_, err = db.Signin(map[string]interface{}{
353-
"user": connInfo.User,
354-
"pass": connInfo.Pass,
352+
_, err = db.SignIn(ctx, &surrealdb.Auth{
353+
Username: "user",
354+
Password: "pass",
355355
})
356356
if err != nil {
357357
return false
358358
}
359359

360-
_, err = db.Use(connInfo.NS, connInfo.DB)
360+
err = db.Use(ctx, connInfo.NS, connInfo.DB)
361361
if err != nil {
362362
return false
363363
}
364364

365-
_, err = db.Query(`SELECT * FROM 1;`, map[string]interface{}{})
365+
_, err = surrealdb.Query[[]any](ctx, db, `SELECT * FROM 1;`, map[string]interface{}{})
366366
return err == nil
367367
}

0 commit comments

Comments
 (0)