Skip to content

Commit

Permalink
Merge pull request #10 from hipeople/replace-into
Browse files Browse the repository at this point in the history
add support for REPLACE INTO
  • Loading branch information
sentriz authored Oct 4, 2023
2 parents ab2f6c6 + edfe3b2 commit 56c9c80
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 15 deletions.
54 changes: 45 additions & 9 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,11 @@ import (
)

func createAndGetResult(exec ExecFn, record interface{}) (stdsql.Result, error) {
row, err := NewRow(record)
row, columns, values, err := valuesForRecord(record)
if err != nil {
return nil, err
}

columns := []string{}
values := []interface{}{}

for c, v := range row.SQLValues() {
columns = append(columns, c)
values = append(values, v)
}

return exec(sql.InsertQuery(row.SQLTableName, columns), values...)
}

Expand All @@ -35,6 +27,50 @@ func createAndRead(exec ExecFn, query QueryFn, record interface{}) error {
return err
}

return readLastInsert(query, record, result)
}

func replaceAndGetResult(exec ExecFn, record interface{}) (stdsql.Result, error) {
row, columns, values, err := valuesForRecord(record)
if err != nil {
return nil, err
}

return exec(sql.ReplaceQuery(row.SQLTableName, columns), values...)
}

func replace(exec ExecFn, record interface{}) error {
_, err := replaceAndGetResult(exec, record)
return err
}

func replaceAndRead(exec ExecFn, query QueryFn, record interface{}) error {
result, err := replaceAndGetResult(exec, record)
if err != nil {
return err
}

return readLastInsert(query, record, result)
}

func valuesForRecord(record interface{}) (*Row, []string, []interface{}, error) {
row, err := NewRow(record)
if err != nil {
return nil, nil, nil, err
}

columns := []string{}
values := []interface{}{}

for c, v := range row.SQLValues() {
columns = append(columns, c)
values = append(values, v)
}

return row, columns, values, nil
}

func readLastInsert(query QueryFn, record interface{}, result stdsql.Result) error {
id, err := result.LastInsertId()
if err != nil {
return err
Expand Down
14 changes: 14 additions & 0 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ func (db *DB) CreateAndRead(record interface{}) error {
return createAndRead(db.Exec, db.Query, record)
}

// Replaces given record into the database, generating a replace query for it.
func (db *DB) Replace(record interface{}) error {
return replace(db.Exec, record)
}

func (db *DB) ReplaceAndGetResult(record interface{}) (stdsql.Result, error) {
return replaceAndGetResult(db.Exec, record)
}

// Replaces given record and scans the replaceed row back to the given row.
func (db *DB) ReplaceAndRead(record interface{}) error {
return replaceAndRead(db.Exec, db.Query, record)
}

// Runs given SQL query and scans the result rows into the given target interface. The target
// interface could be both a single record or a slice of records.
//
Expand Down
25 changes: 19 additions & 6 deletions sql/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,19 @@ func ShowTablesLikeQuery(name string) string {
}

func InsertQuery(tableName string, columnNames []string) string {
var questionMarks string

if len(columnNames) > 0 {
questionMarks = strings.Repeat("?,", len(columnNames))
questionMarks = questionMarks[:len(questionMarks)-1]
}
questionMarks := repeatComma(len(columnNames), "?")

return fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
tableName, strings.Join(quoteColumnNames(columnNames), ","), questionMarks)
}

func ReplaceQuery(tableName string, columnNames []string) string {
questionMarks := repeatComma(len(columnNames), "?")

return fmt.Sprintf("REPLACE INTO %s (%s) VALUES (%s)",
tableName, strings.Join(quoteColumnNames(columnNames), ","), questionMarks)
}

func SelectQuery(tableName string, columnNames []string) string {
columns := strings.Join(columnNames, ",")
if columns == "" {
Expand Down Expand Up @@ -150,3 +152,14 @@ func quoteColumnNames(columns []string) []string {

return quoted
}

func repeatComma(num int, char string) string {
var out string

if num > 0 {
out = strings.Repeat(char+",", num)
out = out[:len(out)-1]
}

return out
}
10 changes: 10 additions & 0 deletions transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ func (tx *Tx) CreateAndRead(record interface{}) error {
return createAndRead(tx.Exec, tx.Query, record)
}

// Replace given record to the database.
func (tx *Tx) Replace(record interface{}) error {
return replace(tx.Exec, record)
}

// Replaces given record and scans the replaceed row back to the given row.
func (tx *Tx) ReplaceAndRead(record interface{}) error {
return replaceAndRead(tx.Exec, tx.Query, record)
}

// Run a select query on the databaase (w/ given parameters optionally) and scan the result(s) to the
// target interface specified as the first parameter.
//
Expand Down

0 comments on commit 56c9c80

Please sign in to comment.