parent
6bcec26be1
commit
28a2c991a2
@ -0,0 +1,174 @@ |
||||
package features_admin |
||||
|
||||
import ( |
||||
"reflect" |
||||
"fmt" |
||||
"errors" |
||||
"MY/webapp/data" |
||||
_ "github.com/mattn/go-sqlite3" |
||||
sq "github.com/Masterminds/squirrel" |
||||
) |
||||
|
||||
func Schema(table string) ([]string, error) { |
||||
the_type, ok := data.Models()[table] |
||||
if !ok { return nil, errors.New("Invalid table") } |
||||
|
||||
field_num := the_type.NumField() |
||||
|
||||
fields := make([]string, 0, field_num) |
||||
|
||||
for i := 0; i < field_num; i++ { |
||||
tag := the_type.Field(i).Name |
||||
fields = append(fields, tag) |
||||
} |
||||
|
||||
return fields, nil |
||||
} |
||||
|
||||
func SearchTable(search string, table string, limit uint64, page uint64) ([]any, error) { |
||||
var results []any |
||||
|
||||
the_type := data.Models()[table] |
||||
like := fmt.Sprint("%", search, "%") |
||||
|
||||
builder := sq.Select("*"). |
||||
Limit(limit). |
||||
Offset(limit * page). |
||||
From(table) |
||||
|
||||
field_num := the_type.NumField() |
||||
var or_clause sq.Or |
||||
|
||||
for i := 0; i < field_num; i++ { |
||||
tag := the_type.Field(i).Tag.Get("db") |
||||
or_clause = append(or_clause, sq.Like{tag: like}) |
||||
} |
||||
|
||||
builder = builder.Where(or_clause) |
||||
sql_query, args, err := builder.ToSql() |
||||
|
||||
if err != nil { return results, err } |
||||
|
||||
// BUG: refactor this to share a common func with SelectTable
|
||||
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).Interface() |
||||
err = rows.StructScan(the_data) |
||||
if err != nil { return results, err } |
||||
|
||||
results = append(results, the_data) |
||||
} |
||||
|
||||
return results, rows.Err() |
||||
} |
||||
|
||||
func SelectTable(table string, limit uint64, page uint64) ([]any, error) { |
||||
var results []any |
||||
the_type := data.Models()[table] |
||||
|
||||
sql_query, args, err := sq.Select("*"). |
||||
Limit(limit). |
||||
Offset(limit * page). |
||||
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).Interface() |
||||
err = rows.StructScan(the_data) |
||||
if err != nil { return results, err } |
||||
|
||||
results = append(results, the_data) |
||||
} |
||||
|
||||
return results, rows.Err() |
||||
} |
||||
|
||||
func Get(table string, id int64) (reflect.Value, error) { |
||||
the_type := data.Models()[table] |
||||
|
||||
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) (int64, int64, error) { |
||||
type_of := value.Type() |
||||
field_num := value.NumField() |
||||
var columns []string |
||||
var values []any |
||||
|
||||
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() |
||||
if err != nil { return -1, -1, err } |
||||
|
||||
result, err := data.DB.Exec(sql_query, args...) |
||||
if err != nil { return -1, -1, err } |
||||
|
||||
id, err := result.LastInsertId() |
||||
if err != nil { return -1, -1, err } |
||||
|
||||
count, err := result.RowsAffected() |
||||
if err != nil { return id, -1, err } |
||||
|
||||
return id, count, err |
||||
} |
||||
|
||||
func Update(table string, value reflect.Value) (int64, error) { |
||||
builder := sq.Update(table) |
||||
orig_id := value.FieldByName("Id").Int() |
||||
|
||||
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 = builder.Where(sq.Eq{"id": orig_id}) |
||||
sql_query, args, err := builder.ToSql() |
||||
if err != nil { return -1, err } |
||||
|
||||
fmt.Println("UPDATE QUERY", sql_query, args) |
||||
if err != nil { return -1, err} |
||||
|
||||
_, err = data.DB.Exec(sql_query, args...) |
||||
if err != nil { return -1, err } |
||||
|
||||
return orig_id, err |
||||
} |
||||
@ -0,0 +1,46 @@ |
||||
package features_auth |
||||
|
||||
import ( |
||||
"golang.org/x/crypto/bcrypt" |
||||
|
||||
"github.com/gofiber/fiber/v2" |
||||
_ "github.com/mattn/go-sqlite3" |
||||
sq "github.com/Masterminds/squirrel" |
||||
|
||||
"MY/webapp/data" |
||||
"MY/webapp/common" |
||||
) |
||||
|
||||
func SetUserPassword(user *data.User) error { |
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12) |
||||
if err != nil { return err } |
||||
|
||||
user.Password = string(hashed) |
||||
return nil |
||||
} |
||||
|
||||
func LogoutUser(c *fiber.Ctx) error { |
||||
sess, err := common.STORE.Get(c) |
||||
if err != nil { return err } |
||||
|
||||
err = sess.Destroy() |
||||
if err != nil { return err } |
||||
|
||||
err = sess.Save() |
||||
return err |
||||
} |
||||
|
||||
func LoginUser(result *data.User, login *data.Login) (bool, error) { |
||||
sql, args, err := sq.Select("username, password"). |
||||
From("user").Where("username=?", login.Username).ToSql() |
||||
|
||||
if err != nil { return false, err } |
||||
|
||||
err = data.DB.Get(result, sql, args...) |
||||
if err != nil { return false, err } |
||||
|
||||
pass_good := bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(login.Password)) |
||||
if pass_good != nil { return false, pass_good } |
||||
|
||||
return login.Username == result.Username && pass_good == nil, nil |
||||
} |
||||
@ -0,0 +1,9 @@ |
||||
package features_email |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
@ -0,0 +1,9 @@ |
||||
package features_fakepay |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
@ -0,0 +1,9 @@ |
||||
package features_paypal |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
@ -0,0 +1,9 @@ |
||||
package features_shopping |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
@ -0,0 +1,9 @@ |
||||
package features_survey |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
@ -0,0 +1,9 @@ |
||||
package features_{{ .Name }} |
||||
|
||||
import ( |
||||
// "MY/webapp/data"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
// sq "github.com/Masterminds/squirrel"
|
||||
) |
||||
|
||||
|
||||
Loading…
Reference in new issue