Skip to content

Commit

Permalink
replace select with find and findOne
Browse files Browse the repository at this point in the history
  • Loading branch information
NoBypass committed Mar 10, 2024
1 parent b6eafae commit aa1e90e
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 35 deletions.
22 changes: 16 additions & 6 deletions actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@ import (
"github.com/surrealdb/surrealdb.go"
)

func (dbm *DBModel[T]) Select(obj *T, options ...OptsFunc) error {
func (dbm *DBModel[T]) FindOne(obj *T, options ...OptsFunc) error {
options = append(options, Only())
data, err := surrealdb.SmartUnmarshal[T](dbm.selectConstructor(options...))
scanStruct(&obj, data)
return err
}

func (dbm *DBModel[T]) Find(obj *[]T, options ...OptsFunc) error {
data, err := surrealdb.SmartUnmarshal[[]T](dbm.selectConstructor(options...))
scanSlice(obj, data)
return err
}

func (dbm *DBModel[T]) selectConstructor(options ...OptsFunc) (any, error) {
var opts Opts
for _, option := range options {
option(&opts)
Expand All @@ -27,10 +40,7 @@ func (dbm *DBModel[T]) Select(obj *T, options ...OptsFunc) error {
parallel(opts.parallel),
)

res, err := dbm.db.Query(query)
data, err := surrealdb.SmartUnmarshal[T](res, err)
scan(&obj, data)
return err
return dbm.db.Query(query)
}

// TODO: support for ID field
Expand Down Expand Up @@ -58,7 +68,7 @@ func (dbm *DBModel[T]) Create(record *T, options ...OptsFunc) error {
return err
}

scan(&record, data)
scanStruct(&record, data)
return nil
}

Expand Down
143 changes: 115 additions & 28 deletions actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,88 +86,175 @@ func TestDBModel_Create(t *testing.T) {
})
}

func TestDBModel_Select(t *testing.T) {
t.Run("With a minimal select query", func(t *testing.T) {
func TestDBModel_FindOne(t *testing.T) {
t.Run("With a minimal find query", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test)
err := testModel.FindOne(&test)
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With an id", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, ID("123"))
err := testModel.FindOne(&test, ID("123"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model:123;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model:123;", testModel.db.(*DBMock).query)
})
t.Run("With a ranged id", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, ID([2]any{SampleID{123}, SampleID{456}}))
err := testModel.FindOne(&test, ID([2]any{SampleID{123}, SampleID{456}}))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model:[123]..[456];", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model:[123]..[456];", testModel.db.(*DBMock).query)
})
t.Run("With fields", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Fields("id", "name"))
err := testModel.FindOne(&test, Fields("id", "name"))
assert.NoError(t, err)
assert.Equal(t, "SELECT id, name FROM sample_model;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT id, name FROM ONLY sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With omit", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Omit("id", "name"))
err := testModel.FindOne(&test, Omit("id", "name"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * OMIT id, name FROM sample_model;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * OMIT id, name FROM ONLY sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With only", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Only())
err := testModel.FindOne(&test, Only())
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM ONLY sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With where", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Where(`name = "foo"`))
err := testModel.FindOne(&test, Where(`name = "foo"`))
assert.NoError(t, err)
assert.Equal(t, `SELECT * FROM sample_model WHERE name = "foo";`, testModel.db.(*DBMock).query)
assert.Equal(t, `SELECT * FROM ONLY sample_model WHERE name = "foo";`, testModel.db.(*DBMock).query)
})
t.Run("With group by", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, GroupBy("name", "age"))
err := testModel.FindOne(&test, GroupBy("name", "age"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model GROUP BY name, age;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model GROUP BY name, age;", testModel.db.(*DBMock).query)
})
t.Run("With order by", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, OrderBy(Asc("name"), Desc("age")))
err := testModel.FindOne(&test, OrderBy(Asc("name"), Desc("age")))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model ORDER BY name ASC, age DESC;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model ORDER BY name ASC, age DESC;", testModel.db.(*DBMock).query)
})
t.Run("With limit", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Limit(10))
err := testModel.FindOne(&test, Limit(10))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model LIMIT 10;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model LIMIT 10;", testModel.db.(*DBMock).query)
})
t.Run("With start", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Start(10))
err := testModel.FindOne(&test, Start(10))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model START 10;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model START 10;", testModel.db.(*DBMock).query)
})
t.Run("With fetch", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Fetch("group.sub"))
err := testModel.FindOne(&test, Fetch("group.sub"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model FETCH group.sub;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model FETCH group.sub;", testModel.db.(*DBMock).query)
})
t.Run("With timeout", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Timeout(10*time.Second))
err := testModel.FindOne(&test, Timeout(10*time.Second))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model TIMEOUT 10000ms;", testModel.db.(*DBMock).query)
assert.Equal(t, "SELECT * FROM ONLY sample_model TIMEOUT 10000ms;", testModel.db.(*DBMock).query)
})
t.Run("With parallel", func(t *testing.T) {
test := SampleModel{}
err := testModel.Select(&test, Parallel())
err := testModel.FindOne(&test, Parallel())
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM ONLY sample_model PARALLEL;", testModel.db.(*DBMock).query)
})
}

func TestDBModel_Find(t *testing.T) {
t.Run("With a minimal find query", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test)
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With an id", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, ID("123"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model:123;", testModel.db.(*DBMock).query)
})
t.Run("With a ranged id", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, ID([2]any{SampleID{123}, SampleID{456}}))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model:[123]..[456];", testModel.db.(*DBMock).query)
})
t.Run("With fields", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Fields("id", "name"))
assert.NoError(t, err)
assert.Equal(t, "SELECT id, name FROM sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With omit", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Omit("id", "name"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * OMIT id, name FROM sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With only", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Only())
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM ONLY sample_model;", testModel.db.(*DBMock).query)
})
t.Run("With where", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Where(`name = "foo"`))
assert.NoError(t, err)
assert.Equal(t, `SELECT * FROM sample_model WHERE name = "foo";`, testModel.db.(*DBMock).query)
})
t.Run("With group by", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, GroupBy("name", "age"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model GROUP BY name, age;", testModel.db.(*DBMock).query)
})
t.Run("With order by", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, OrderBy(Asc("name"), Desc("age")))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model ORDER BY name ASC, age DESC;", testModel.db.(*DBMock).query)
})
t.Run("With limit", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Limit(10))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model LIMIT 10;", testModel.db.(*DBMock).query)
})
t.Run("With start", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Start(10))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model START 10;", testModel.db.(*DBMock).query)
})
t.Run("With fetch", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Fetch("group.sub"))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model FETCH group.sub;", testModel.db.(*DBMock).query)
})
t.Run("With timeout", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Timeout(10*time.Second))
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model TIMEOUT 10000ms;", testModel.db.(*DBMock).query)
})
t.Run("With parallel", func(t *testing.T) {
var test []SampleModel
err := testModel.Find(&test, Parallel())
assert.NoError(t, err)
assert.Equal(t, "SELECT * FROM sample_model PARALLEL;", testModel.db.(*DBMock).query)
})
Expand Down
7 changes: 6 additions & 1 deletion internals.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ func (db *DB) Query(query string) (interface{}, error) {
return db.db.Query(query, nil)
}

func scan[T any](scan **T, content T) {
func scanStruct[T any](scan **T, content T) {
*scan = &content
}

func scanSlice[T any](scan *[]T, content []T) {
*scan = make([]T, len(content))
copy(*scan, content)
}

func fields(fields []string) string {
if len(fields) == 0 {
return "*"
Expand Down

0 comments on commit aa1e90e

Please sign in to comment.