diff --git a/admin/db.go b/admin/db.go new file mode 100644 index 0000000..3537e7f --- /dev/null +++ b/admin/db.go @@ -0,0 +1,96 @@ +package admin + +import ( + "reflect" + "fmt" + "zedshaw.games/webapp/data" + _ "github.com/mattn/go-sqlite3" + sq "github.com/Masterminds/squirrel" +) + +func SelectTable(table string, the_type reflect.Type, limit uint64, offset uint64) ([]reflect.Value, error) { + var results []reflect.Value + sql_query, args, err := sq.Select("*").Limit(limit).Offset(offset).From(table).ToSql() + if err != nil { return results, err } + + rows, err := data.DB.Queryx(sql_query, args...) + if err != nil { return results, err } + defer rows.Close() + + for rows.Next() { + the_data := reflect.New(the_type) + err = rows.StructScan(the_data.Interface()) + if err != nil { return results, err } + + results = append(results, the_data.Elem()) + } + + return results, rows.Err() +} + +func Get(table string, the_type reflect.Type, id int64) (reflect.Value, error) { + sql_query, args, err := sq.Select("*").From(table).Where(sq.Eq{"id": id}).ToSql() + if err != nil { return reflect.New(nil), err } + + the_data := reflect.New(the_type) + err = data.DB.Get(the_data.Interface(), sql_query, args...) + + // BUG: not sure if Elem or returning the reflect.New is better + return the_data.Elem(), err +} + +func Delete(table string, id int64) error { + sql_query, args, err := sq.Delete(table).Where(sq.Eq{"id": id}).ToSql() + if err != nil { return err } + + _, err = data.DB.Exec(sql_query, args...) + return err +} + +func Insert(table string, value reflect.Value) error { + type_of := value.Type() + field_num := value.NumField() + var columns []string + var values []interface{} + + for i := 0; i < field_num; i++ { + field := value.Field(i) + tag := type_of.Field(i).Tag.Get("db") + if tag == "id" { continue } + columns = append(columns, tag) + values = append(values, field.Interface()) + } + + builder := sq.Insert(table).Columns(columns...).Values(values...) + sql_query, args, err := builder.ToSql() + + _, err = data.DB.Exec(sql_query, args...) + + return err +} + +func Update(table string, value reflect.Value) error { + builder := sq.Update(table) + + type_of := value.Type() + field_num := value.NumField() + + for i := 0; i < field_num; i++ { + field := value.Field(i) + tag := type_of.Field(i).Tag.Get("db") + + // skip update of id to avoid replacing it + if tag == "id" { continue } + + builder = builder.Set(tag, field.Interface()) + } + + builder.Where(sq.Eq{"id": value.FieldByName("Id").Interface()}) + sql_query, args, err := builder.ToSql() + + fmt.Println("UPDATE QUERY", sql_query, args) + if err != nil { return err} + + _, err = data.DB.Exec(sql_query, args...) + return err +} diff --git a/api/handlers.go b/api/handlers.go index 6b97a64..159f2bf 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -39,7 +39,7 @@ func GetApiStream(c *fiber.Ctx) error { func GetApiStreamId(c *fiber.Ctx) error { sql, args, err := sq.Select("*"). - From("stream").Where("id=?", c.Params("id")).ToSql() + From("stream").Where(sq.Eq{"id": c.Params("id")}).ToSql() err = data.GetJson[data.Stream](c, err, sql, args...) return IfErrNil(err, c) @@ -48,7 +48,7 @@ func GetApiStreamId(c *fiber.Ctx) error { func GetApiStreamIdLinks(c *fiber.Ctx) error { sql, args, err := sq.Select("*"). From("stream_link"). - Where("stream_id=?", c.Params("id")).ToSql() + Where(sq.Eq{"stream_id": c.Params("id")}).ToSql() err = data.SelectJson[data.Link](c, err, sql, args...) diff --git a/tests/admin_test.go b/tests/admin_test.go index c3cc8bc..ea8aee6 100644 --- a/tests/admin_test.go +++ b/tests/admin_test.go @@ -4,98 +4,14 @@ import ( "testing" "fmt" "reflect" + "github.com/stretchr/testify/require" "zedshaw.games/webapp/data" - _ "github.com/mattn/go-sqlite3" + "zedshaw.games/webapp/admin" sq "github.com/Masterminds/squirrel" ) -func SelectTable(table string, the_type reflect.Type, limit uint64, offset uint64) ([]reflect.Value, error) { - var results []reflect.Value - sql_query, args, err := sq.Select("*").Limit(limit).Offset(offset).From(table).ToSql() - if err != nil { return results, err } - - rows, err := data.DB.Queryx(sql_query, args...) - if err != nil { return results, err } - defer rows.Close() - - for rows.Next() { - the_data := reflect.New(the_type) - err = rows.StructScan(the_data.Interface()) - if err != nil { return results, err } - - results = append(results, the_data.Elem()) - } - - return results, rows.Err() -} - -func Get(table string, the_type reflect.Type, id int64) (reflect.Value, error) { - sql_query, args, err := sq.Select("*").From(table).Where("id", id).ToSql() - if err != nil { return reflect.New(nil), err } - - the_data := reflect.New(the_type) - err = data.DB.Get(the_data.Interface(), sql_query, args...) - - // BUG: not sure if Elem or returning the reflect.New is better - return the_data.Elem(), err -} - -func Delete(table string, id int64) error { - sql_query, args, err := sq.Delete(table).Where("id", id).ToSql() - if err != nil { return err } - - _, err = data.DB.Exec(sql_query, args...) - return err -} - -func Insert(table string, value reflect.Value) error { - type_of := value.Type() - field_num := value.NumField() - var columns []string - var values []interface{} - - for i := 0; i < field_num; i++ { - field := value.Field(i) - tag := type_of.Field(i).Tag.Get("db") - if tag == "id" { continue } - columns = append(columns, tag) - values = append(values, field.Interface()) - } - - builder := sq.Insert(table).Columns(columns...).Values(values...) - sql_query, args, err := builder.ToSql() - - _, err = data.DB.Exec(sql_query, args...) - - return err -} - -func Update(table string, value reflect.Value) error { - builder := sq.Update(table) - - type_of := value.Type() - field_num := value.NumField() - - for i := 0; i < field_num; i++ { - field := value.Field(i) - tag := type_of.Field(i).Tag.Get("db") - - // skip update of id to avoid replacing it - if tag == "id" { continue } - - builder = builder.Set(tag, field.Interface()) - } - - builder.Where("id", value.FieldByName("Id").Interface()) - - sql_query, args, err := builder.ToSql() - - _, err = data.DB.Exec(sql_query, args...) - - return err -} - func TestAdminIndexPage(t *testing.T) { + assert := require.New(t) models := data.Models() table := "user" model := models[table] @@ -111,41 +27,42 @@ func TestAdminIndexPage(t *testing.T) { val := reflect.New(model).Elem() email := fmt.Sprintf("test%d@test.com", i) val.FieldByName("Email").SetString(email) - val.FieldByName("Username").SetString(fmt.Sprintf("zed%d@zed.com", i)) + val.FieldByName("Username").SetString(fmt.Sprintf("zed%d", i)) val.FieldByName("Password").SetString("garbage") - sql_query, args, err := sq.Delete(table).Where("email", email).ToSql() - data.DB.Exec(sql_query, args...) + sql_query, args, err := sq.Delete(table).Where(sq.Eq{"email": email}).ToSql() + assert.NoError(err) + + _, err = data.DB.Exec(sql_query, args...) + assert.NoError(err) - err = Insert(table, val) - if err != nil { fmt.Println("INSERT", err) } + err = admin.Insert(table, val) + assert.NoError(err, email) } - all_rows, err := SelectTable(table, model, 20, 20 * 3) - for i, row := range all_rows { fmt.Println("row", i, row) } + all_rows, err := admin.SelectTable(table, model, 20, 20 * 3) + assert.NoError(err) - if err != nil { fmt.Println("ERROR", err) } + for i, row := range all_rows { fmt.Println("row", i, row) } + assert.Equal(20, len(all_rows)) first_row := all_rows[0] - result, err := Get(table, model, first_row.FieldByName("Id").Int()) + result, err := admin.Get(table, model, first_row.FieldByName("Id").Int()) if err != nil { fmt.Println("ERROR", err) } fmt.Println("TABLE: ", result) id := result.FieldByName("Id") - result, err = Get(table, model, id.Int()) - if err != nil { fmt.Println("ERROR", err) } - fmt.Println("GET: ", result) + result, err = admin.Get(table, model, id.Int()) + assert.NoError(err) - username := result.FieldByName("Username") + fmt.Println("BEFORE: ", result) + result.FieldByName("Username").SetString("joeblow") + result.FieldByName("Email").SetString("what@what.com") + fmt.Println("AFTER: ", result) - username.SetString("joeblow") - err = Update(table, result) - if err != nil { fmt.Println("ERROR", err) } - - username.SetString("zedshaw") - err = Update(table, result) - if err != nil { fmt.Println("ERROR", err) } + err = admin.Update(table, result) + assert.NoError(err, ) - // err = Delete(table, id.Int()) - // if err != nil { fmt.Println("ERROR", err) } + err = admin.Delete(table, id.Int()) + assert.NoError(err) }