diff --git a/internal/structs/structs.go b/internal/structs/structs.go index f7c275d..2022453 100644 --- a/internal/structs/structs.go +++ b/internal/structs/structs.go @@ -233,6 +233,11 @@ func getTagNames(t reflect.Type) (StructInfo, error) { byName: map[string]*FieldInfo{}, } for i := 0; i < t.NumField(); i++ { + // If this field is private: + if t.Field(i).PkgPath != "" { + return StructInfo{}, fmt.Errorf("all fields using the ksql tags must be exported, but %v is unexported", t) + } + name := t.Field(i).Tag.Get("ksql") if name == "" { continue diff --git a/test_adapters.go b/test_adapters.go index 1de4261..fa3b4ae 100644 --- a/test_adapters.go +++ b/test_adapters.go @@ -607,11 +607,11 @@ func QueryOneTest( c := newTestDB(db, driver) var row struct { - CountAttr int `ksql:"myCount"` + Count int `ksql:"myCount"` } err = c.QueryOne(ctx, &row, `SELECT count(*) as myCount FROM users WHERE name='Count Olivia'`) tt.AssertNoErr(t, err) - tt.AssertEqual(t, row.CountAttr, 1) + tt.AssertEqual(t, row.Count, 1) }) }) } @@ -672,6 +672,23 @@ func QueryOneTest( err := c.QueryOne(ctx, &row, `SELECT * FROM users u JOIN posts p ON u.id = p.user_id LIMIT 1`) tt.AssertErrContains(t, err, "nested struct", "feature") }) + + t.Run("should report error if a private field has a ksql tag", func(t *testing.T) { + db, closer := newDBAdapter(t) + defer closer.Close() + + ctx := context.Background() + _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Olivia', 0, '{"country":"US"}')`) + tt.AssertNoErr(t, err) + + c := newTestDB(db, driver) + + var row struct { + count int `ksql:"my_count"` + } + err = c.QueryOne(ctx, &row, `SELECT count(*) as my_count FROM users`) + tt.AssertErrContains(t, err, "unexported", "my_count") + }) }) }