Skip to content

Commit

Permalink
feat(contrib/drivers/pgsql): add InsertIgnore support (gogf#3855)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwfeng authored Oct 15, 2024
1 parent 5288b70 commit c18339b
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 8 deletions.
9 changes: 8 additions & 1 deletion contrib/drivers/pgsql/pgsql_do_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ package pgsql
import (
"context"
"fmt"

"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
)

// DoFilter deals with the sql string before commits it to underlying sql driver.
Expand Down Expand Up @@ -45,6 +45,13 @@ func (d *Driver) DoFilter(
if err != nil {
return "", nil, err
}

// Add support for pgsql INSERT OR IGNORE.
if gstr.HasPrefix(newSql, gdb.InsertOperationIgnore) {
newSql = "INSERT" + newSql[len(gdb.InsertOperationIgnore):] + " ON CONFLICT DO NOTHING"
}

newArgs = args

return d.Core.DoFilter(ctx, link, newSql, newArgs)
}
7 changes: 0 additions & 7 deletions contrib/drivers/pgsql/pgsql_do_insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package pgsql
import (
"context"
"database/sql"

"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
Expand All @@ -24,12 +23,6 @@ func (d *Driver) DoInsert(ctx context.Context, link gdb.Link, table string, list
`Replace operation is not supported by pgsql driver`,
)

case gdb.InsertOptionIgnore:
return nil, gerror.NewCode(
gcode.CodeNotSupported,
`Insert ignore operation is not supported by pgsql driver`,
)

case gdb.InsertOptionDefault:
tableFields, err := d.GetCore().GetDB().TableFields(ctx, table)
if err == nil {
Expand Down
112 changes: 112 additions & 0 deletions contrib/drivers/pgsql/pgsql_z_unit_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,115 @@ int_col INT);`
})

}

func Test_DB_InsertIgnore(t *testing.T) {
table := createTable()
defer dropTable(table)

// Insert test record
gtest.C(t, func(t *gtest.T) {
_, err := db.Insert(ctx, table, g.Map{
"id": 1,
"passport": "t1",
"password": "25d55ad283aa400af464c76d713c07ad",
"nickname": "T1",
"create_time": gtime.Now().String(),
})
t.AssertNil(err)

answer, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1)
t.AssertNil(err)
t.Assert(len(answer), 1)
t.Assert(answer[0]["passport"], "t1")
t.Assert(answer[0]["password"], "25d55ad283aa400af464c76d713c07ad")
t.Assert(answer[0]["nickname"], "T1")

// Ignore Duplicate record
result, err := db.InsertIgnore(ctx, table, g.Map{
"id": 1,
"passport": "t1_duplicate",
"password": "duplicate_password",
"nickname": "Duplicate",
"create_time": gtime.Now().String(),
})
t.AssertNil(err)

n, _ := result.RowsAffected()
t.Assert(n, 0)

answer, err = db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1)
t.AssertNil(err)
t.Assert(len(answer), 1)
t.Assert(answer[0]["passport"], "t1")
t.Assert(answer[0]["password"], "25d55ad283aa400af464c76d713c07ad")
t.Assert(answer[0]["nickname"], "T1")

// Insert Correct Record
result, err = db.Insert(ctx, table, g.Map{
"id": 2,
"passport": "t2",
"password": "25d55ad283aa400af464c76d713c07ad",
"nickname": "name_2",
"create_time": gtime.Now().String(),
})
t.AssertNil(err)
n, _ = result.RowsAffected()
t.Assert(n, 1)

answer, err = db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 2)
t.AssertNil(err)
t.Assert(len(answer), 1)
t.Assert(answer[0]["passport"], "t2")
t.Assert(answer[0]["password"], "25d55ad283aa400af464c76d713c07ad")
t.Assert(answer[0]["nickname"], "name_2")

// Insert Multiple Records Using g.Map Array
data := g.List{
{
"id": 3,
"passport": "t3",
"password": "25d55ad283aa400af464c76d713c07ad",
"nickname": "name_3",
"create_time": gtime.Now().String(),
},
{
"id": 4,
"passport": "t4",
"password": "25d55ad283aa400af464c76d713c07ad",
"nickname": "name_4",
"create_time": gtime.Now().String(),
},
{
"id": 1,
"passport": "t1_conflict",
"password": "conflict_password",
"nickname": "conflict_name",
"create_time": gtime.Now().String(),
},
{
"id": 2,
"passport": "t2_conflict",
"password": "conflict_password",
"nickname": "conflict_name",
"create_time": gtime.Now().String(),
},
}

// Insert Multiple Records with Ignore
result, err = db.InsertIgnore(ctx, table, data)
t.AssertNil(err)

n, _ = result.RowsAffected()
t.Assert(n, 2)

answer, err = db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s", table))
t.AssertNil(err)
t.Assert(len(answer), 4)
// Should have four records in total (ID 1, 2, 3, 4)

t.Assert(answer[0]["passport"], "t1")
t.Assert(answer[1]["passport"], "t2")
t.Assert(answer[2]["passport"], "t3")
t.Assert(answer[3]["passport"], "t4")
})
}

0 comments on commit c18339b

Please sign in to comment.