Skip to content

Commit c878342

Browse files
authored
Merge pull request #6 from pupizoid/3-include-desired-fields-to-query
implemented selected columns
2 parents d7fb5ac + a906896 commit c878342

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

ormlite.go

+29-3
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ type Options struct {
9292
OrderBy *OrderBy `json:"order_by"`
9393
RelationDepth int `json:"relation_depth"`
9494
RelatedTo []IModel `json:"related"`
95-
joins []string
95+
// Columns contains map with string keys of columns to include to the query
96+
// instead of querying all model fields
97+
Columns map[string]struct{} `json:"columns"`
98+
joins []string
9699
}
97100

98101
// DefaultOptions returns default options for query
@@ -150,7 +153,7 @@ type columnInfo struct {
150153
}
151154

152155
func isExportedField(f reflect.StructField) bool {
153-
return strings.ToLower(string([]rune(f.Name)[0])) != string([]rune(f.Name)[0])
156+
return f.IsExported()
154157
}
155158

156159
func lookForSettingWithSep(s, setting, sep string) string {
@@ -637,6 +640,18 @@ func QueryStructContext(ctx context.Context, db *sql.DB, opts *Options, out Mode
637640
continue
638641
}
639642

643+
if opts != nil && opts.Columns != nil {
644+
var colName string
645+
if exp, ok := model.Field(i).Interface().(Expression); ok {
646+
colName = exp.Column()
647+
} else {
648+
colName = getFieldColumnName(model.Type().Field(i))
649+
}
650+
if _, ok := opts.Columns[colName]; !ok && !strings.Contains(tag, "primary") {
651+
continue
652+
}
653+
}
654+
640655
if ri := extractRelationInfo(model.Type().Field(i)); ri != nil {
641656
if ri.Type == hasOne {
642657
columns = append(columns, getFieldColumnName(model.Type().Field(i)))
@@ -727,6 +742,16 @@ func QuerySliceCountContext(ctx context.Context, db *sql.DB, opts *Options, out
727742
return fmt.Errorf("failed to get column info for type: %v", modelType)
728743
}
729744

745+
if opts != nil && opts.Columns != nil {
746+
var selected []columnInfo
747+
for _, ci := range colInfo {
748+
if _, ok := opts.Columns[ci.Name]; ok || ci.Primary {
749+
selected = append(selected, ci)
750+
}
751+
}
752+
colInfo = selected
753+
}
754+
730755
for _, ci := range colInfo {
731756
if ci.RelationInfo.Type == noRelation || ci.RelationInfo.Type == hasOne {
732757
if ci.Primary {
@@ -899,7 +924,7 @@ func addWhereClause(options *Options, s string, value reflect.Value) {
899924
}
900925
}
901926

902-
// Delete removes model object from database by it's primary key
927+
// Delete removes model object from database by its primary key
903928
func Delete(db *sql.DB, m Model) (sql.Result, error) {
904929
modelValue := reflect.ValueOf(m).Elem()
905930

@@ -950,6 +975,7 @@ type pkFieldInfo struct {
950975
field reflect.Value
951976
}
952977

978+
// Count models in database with search options
953979
func Count(db *sql.DB, m Model, opts *Options) (count int64, err error) {
954980
mInfo, err := getModelInfo(m)
955981
if err != nil {

ormlite_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -1237,5 +1237,85 @@ func TestQuerySliceCount(t *testing.T) {
12371237
if assert.NoError(t, QuerySliceCount(db, &Options{Where: Where{"attr": 1}}, &m, &count)) {
12381238
assert.Len(t, m, 4)
12391239
assert.EqualValues(t, 4, count)
1240+
assert.EqualValues(t, 4, m[3].ID)
12401241
}
12411242
}
1243+
1244+
type SelectedColumnsSuite struct {
1245+
suite.Suite
1246+
db *sql.DB
1247+
}
1248+
1249+
type BigModel struct {
1250+
ID int `ormlite:"primary"`
1251+
Attr1 int `ormlite:"col=attr1"`
1252+
Attr2 int `ormlite:"col=attr2"`
1253+
Attr3 string `ormlite:"col=attr3"`
1254+
Attr4 float64 `ormlite:"col=attr4"`
1255+
Related *relatedModel `ormlite:"has_one,col=rel_id"`
1256+
}
1257+
1258+
func (b BigModel) Table() string { return "big_model" }
1259+
1260+
func (s *SelectedColumnsSuite) SetupSuite() {
1261+
db, err := sql.Open("sqlite3", ":memory:")
1262+
require.NoError(s.T(), err)
1263+
1264+
_, err = db.Exec("create table big_model(id integer primary key, attr1 int, attr2 int, attr3 string, attr4 float, rel_id int);" +
1265+
"create table related_model(id integer primary key, field text);")
1266+
require.NoError(s.T(), err)
1267+
s.db = db
1268+
1269+
require.NoError(s.T(), Insert(db, &BigModel{Attr1: 1, Attr2: 2, Attr3: "first", Attr4: 1.0}))
1270+
require.NoError(s.T(), Insert(db, &BigModel{Attr1: 3, Attr2: 4, Attr3: "second", Attr4: 2.0}))
1271+
require.NoError(s.T(), Insert(db, &BigModel{Attr1: 5, Attr2: 6, Attr3: "third", Attr4: 3.0}))
1272+
require.NoError(s.T(), Insert(db, &BigModel{Attr1: 7, Attr2: 8, Attr3: "forth", Attr4: 4.0}))
1273+
require.NoError(s.T(), Insert(db, &BigModel{Attr1: 9, Attr2: 10, Attr3: "fifth", Attr4: 5.0}))
1274+
1275+
require.NoError(s.T(), Upsert(db, &BigModel{
1276+
Attr1: 11,
1277+
Attr2: 11,
1278+
Attr3: "11",
1279+
Attr4: 11,
1280+
Related: &relatedModel{Field: "Hello"},
1281+
}))
1282+
}
1283+
1284+
func (s *SelectedColumnsSuite) TearDownSuite() {
1285+
require.NoError(s.T(), s.db.Close())
1286+
}
1287+
1288+
func (s *SelectedColumnsSuite) TestQueryStruct() {
1289+
var m BigModel
1290+
require.NoError(s.T(), QueryStruct(s.db, &Options{Columns: map[string]struct{}{
1291+
"attr1": {},
1292+
"attr3": {},
1293+
}, Where: Where{"id": 1}}, &m))
1294+
1295+
assert.EqualValues(s.T(), 1, m.ID)
1296+
assert.EqualValues(s.T(), 1, m.Attr1)
1297+
assert.EqualValues(s.T(), 0, m.Attr2)
1298+
assert.EqualValues(s.T(), "first", m.Attr3)
1299+
assert.EqualValues(s.T(), 0.0, m.Attr4)
1300+
}
1301+
1302+
func (s *SelectedColumnsSuite) TestQuerySlice() {
1303+
var mm []*BigModel
1304+
require.NoError(s.T(), QuerySlice(s.db, &Options{Columns: map[string]struct{}{
1305+
"attr2": {},
1306+
"attr4": {},
1307+
}}, &mm))
1308+
1309+
if assert.NotNil(s.T(), mm) {
1310+
assert.Len(s.T(), mm, 6)
1311+
assert.EqualValues(s.T(), 6, mm[2].Attr2)
1312+
assert.EqualValues(s.T(), "", mm[2].Attr3)
1313+
assert.EqualValues(s.T(), 3.0, mm[2].Attr4)
1314+
assert.EqualValues(s.T(), (*relatedModel)(nil), mm[5].Related)
1315+
}
1316+
1317+
}
1318+
1319+
func TestSelectedColumns(t *testing.T) {
1320+
suite.Run(t, new(SelectedColumnsSuite))
1321+
}

0 commit comments

Comments
 (0)