Skip to content

Commit

Permalink
doc: StmtExecutor (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
keroxp authored Feb 3, 2023
1 parent ca7bbab commit 2b45ce9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 27 deletions.
60 changes: 39 additions & 21 deletions changelogs/v2.0.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
Exql v2 Release Note
---
# exql v2 Release Note

2022-01-23
2022-02-03
Yusuke SAKURAI
Software Engineer at LoiLo Inc.

## Table of contents

- [Exql v2 Release Note](#exql-v2-release-note)
- [Table of contents](#table-of-contents)
- [New methods of Saver](#new-methods-of-saver)
- [Delete/DeleteContext](#deletedeletecontext)
- [Query Executors](#query-executors)
- [Query maker for bulk insertion](#query-maker-for-bulk-insertion)
- [Finder interface](#finder-interface)
- [Interface Updates](#interface-updates)
- [New interfaces](#new-interfaces)
- [Removed interfaces](#removed-interfaces)
- [Changes in generated codes](#changes-in-generated-codes)
- [exql/query package](#exqlquery-package)
- [query.Condition](#querycondition)
- [query.Builder](#querybuilder)
## Introduction

exql@v2 is the first major update from the release in 2020. Through the real development experience of 3 years, we met many DRY issues and learned many practices from them. All new features and improvementns included v2 are an actual resolutions for them. We hope that exql gets more pragmatic and essential tool that lets Gophers go far.

## New methods of Saver

Expand Down Expand Up @@ -65,6 +50,7 @@ result, err := db.Exec(q)
// INSERT INTO users (age,name) VALUES (?,?),(?,?)
// [20, go, 30, lang]"
```

## Finder interface

A new interface, `Finder` was intoroduced. This is integrated interface of quering records and maping rows into models. In former verison, a typical SELECT query and code were like this:
Expand Down Expand Up @@ -95,6 +81,31 @@ log.Printf("%d", user.Id) // -> 1

`Mapper` has been deprecated and is going te be removed in the next major version. Faster refactoring is recommended.

## StmtExecutor

`StmtExecutor` is the `Executor` that caches queries as `sql.Stmt`. This is designed for the repeated executon of same query. It prevents the potential lack of connection pool caused by too many prepared satatemts

```go
stmtExecer := exql.NewStmtExecutor(tx.Tx())
defer stmtExecer.Close()
stmtSaver := exql.NewSaver(stmtExecer)
stmtSaver.Insert(&model.Users{Name: "user1"})
stmtSaver.Insert(&model.Users{Name: "user2"})
```

The code above is equivalent to SQL below:

```sql
PREPARE stmt FROM "INSERT INTO `users` (`name`) VALUES (?)";
SET @name = "user1";
EXECUTE stmt USING @name;
SET @name = "user2";
EXECUTE stmt USING @name;
DEALLOCATE PREPARE stmt;
```

This has the advantage on the concurrent execution of same queries because it holds a single underlying connection for the statement. Without preparation, even if they are identical, different connection is assigned to each query.

## Interface Updates

### New interfaces
Expand All @@ -108,6 +119,8 @@ type Executor interface {
QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
QueryRow(query string, args ...any) *sql.Row
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
Prepare(stmt string) (*sql.Stmt, error)
PrepareContext(ctx context.Context, stmt string) (*sql.Stmt, error)
}

type Model interface {
Expand All @@ -133,6 +146,7 @@ Two interfaces were removed.
Codes that generated by `Generator` changed partially. It was simplified for presenting model's table name.

Old:

```go
type usersTable struct {}
var UsersTable = &usersTable{}
Expand All @@ -142,11 +156,11 @@ func (u *usersTable) Name() string {
```

New:

```go
const UsersTableName = "users"
```


## exql/query package

`query` package is the biggest new feature in exql v2. It is an independent framework for building SQL query. In exql v1, except for insert/update queries, you must write a raw SQL down.
Expand Down Expand Up @@ -182,11 +196,14 @@ You noticed an unfamiliar symbol `:?`, that is the new designated placeholder of
What is the functionality of `query.V()`?

The code below:

```go
ids := []int{1,2}
db.Query(query.New("select * from users where id in (:?)", query.V(ids...)))
```

...is the same as:

```go
db.DB().Query("select * from users where id in (?,?)", 1, 2)
```
Expand Down Expand Up @@ -217,4 +234,5 @@ qb.Sprintf("SELECT * FROM %s", "users")
qb.Query("WHERE id IN (:?) AND age >= ?", query.V(1,2), 20)
// SELECT * FROM users WHERE id IN (?,?) AND age >= ?
// [1,2,20]
rows, err := db.Query(qb.Build())```
rows, err := db.Query(qb.Build())
```
19 changes: 13 additions & 6 deletions stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,21 @@ func (e *stmtExecutor) QueryRowContext(ctx context.Context, query string, args .
return e.ex.QueryRowContext(ctx, query, args...)
}

// StmtExecutor is the Executor that caches same queries as *sql.Stmt,
// and uses it again for the next time. They will be holded utnil Close() is called.
// This is useful for the case that execute the same query repeatedly in the for-loop.
// It prevents the error caused by the db's connection pool.
// StmtExecutor is the Executor that caches queries as *sql.Stmt.
// It uses the cached Stmt for the next execution if query is identical.
// They are held until Close() is called. This is useful for the case
// of executing the same query repeatedly in the for-loop.
// It may prevent errors caused by the db's connection pool.
//
// Example:
//
// stmtExecer := exql.NewStmtExecutor(tx.Tx())
// defer stmtExecer.Close()
// stmtSaver := exql.NewSaver(stmtExecer)
type StmtExecutor interface {
Executor
// Close calls all retained *sql.Stmt structs and clears the buffer.
// DONT'T forget to call this on the use.
// Close calls all retained *sql.Stmt and clears the buffer.
// DON'T forget to call this on the manual use.
Close() error
}

Expand Down

0 comments on commit 2b45ce9

Please sign in to comment.