Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/taichi/kra
relational database access helper library
https://github.com/taichi/kra
antlr4 postgresql rdb sql
Last synced: 12 days ago
JSON representation
relational database access helper library
- Host: GitHub
- URL: https://github.com/taichi/kra
- Owner: taichi
- License: apache-2.0
- Created: 2021-05-01T09:59:28.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-09-13T00:48:12.000Z (about 2 months ago)
- Last Synced: 2024-10-13T01:41:45.947Z (26 days ago)
- Topics: antlr4, postgresql, rdb, sql
- Language: Go
- Homepage:
- Size: 541 KB
- Stars: 33
- Watchers: 4
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# kra
![](https://github.com/taichi/kra/actions/workflows/push.yml/badge.svg)
[![PkgGoDev](https://pkg.go.dev/badge/https://pkg.go.dev/github.comtaichi/kra)](https://pkg.go.dev/github.com/taichi/kra)
[![Go Report Card](https://goreportcard.com/badge/github.com/taichi/kra)](https://goreportcard.com/report/github.com/taichi/kra)**SQL is the best way to access database**.
kra is a relational database access helper library on top of go.
kra works with `database/sql`, so all of database with `database/sql` based driver is supported.
and kra also works with `pgx` native API. kra focuses on the convenient use of `CopyFrom`.# Features
- Named parameter support with dot notation
- IN statement variable expansion
- Rows to structure/map mapping
- Selectable base API. pgx or database/sql
- Highly configurable behavior
- Context is required for network access APIs
- All wrapper object has escape hatches# Getting Started
## Install
```
go get github.com/taichi/kra
```## Usage
### native pgx based API
```go
package mainimport (
"context"
"database/sql"
"fmt"
"time""github.com/jackc/pgtype"
"github.com/taichi/kra/pgx"
)type Film struct {
Code string
Title string
Did int
DateProd time.Time `db:"date_prod"`
Kind string
Len pgtype.Interval
}func main() {
ctx := context.Background()db, err := pgx.Open(ctx, "user=test password=test host=localhost port=5432 database=test sslmode=disable")
if err != nil {
fmt.Println("open", err)
return
}
defer db.Close()if _, err := db.Exec(ctx, `CREATE TABLE IF NOT EXISTS films (
code char(5) PRIMARY KEY,
title varchar(40) NOT NULL,
did integer NOT NULL,
date_prod date,
kind varchar(10),
len interval hour to minute
);`); err != nil {
fmt.Println("create", err)
return
}
defer func() {
if _, err := db.Exec(ctx, "DROP TABLE films"); err != nil {
fmt.Println(err)
}
}()testdata := []Film{
{"1111", "aaaa", 32, time.Now(), "CDR", pgtype.Interval{Microseconds: 5400000000, Status: pgtype.Present}},
{"2222", "bbbb", 34, time.Now(), "ZDE", pgtype.Interval{Microseconds: 9000000000, Status: pgtype.Present}},
{"3333", "cccc", 65, time.Now(), "IOM", pgtype.Interval{Microseconds: 5400000000, Status: pgtype.Present}},
{"4444", "dddd", 72, time.Now(), "ERW", pgtype.Interval{Microseconds: 7200000000, Status: pgtype.Present}},
}if _, err := db.CopyFrom(ctx, pgx.Identifier{"films"}, testdata); err != nil {
fmt.Println("CopyFrom", err)
return
}var films []Film
if err := db.FindAll(ctx, &films, "SELECT * FROM films WHERE kind IN (:kind)", sql.NamedArg{Name: "kind", Value: []string{"CDR", "ZDE"}}); err != nil {
fmt.Println("find", err)
return
}fmt.Printf("%v\n", films)
}
```### standard database/sql based API
```go
package mainimport (
"context"
"fmt"
"time""github.com/jackc/pgtype"
_ "github.com/jackc/pgx/v4/stdlib""github.com/taichi/kra"
"github.com/taichi/kra/sql"
)type Film struct {
Code string
Title string
Did int
DateProd time.Time `db:"date_prod"`
Kind string
Len pgtype.Interval
}func main() {
ctx := context.Background()db, err := sql.Open(kra.NewCore(kra.PostgreSQL), "pgx", "user=test password=test host=localhost port=5432 database=test sslmode=disable")
if err != nil {
fmt.Println("open", err)
return
}
defer db.Close()if _, err := db.Exec(ctx, `CREATE TABLE IF NOT EXISTS films (
code char(5) PRIMARY KEY,
title varchar(40) NOT NULL,
did integer NOT NULL,
date_prod date,
kind varchar(10),
len interval hour to minute
);`); err != nil {
fmt.Println("create", err)
return
}
defer func() {
if _, err := db.Exec(ctx, "DROP TABLE films"); err != nil {
fmt.Println(err)
}
}()if stmt, err := db.Prepare(ctx, "INSERT INTO films (code, title, did, date_prod, kind, len) VALUES (:code, :title, :did, :date_prod, :kind, :len)"); err != nil {
fmt.Println("prepare", err)
return
} else {
testdata := []Film{
{"1111", "aaaa", 32, time.Now(), "CDR", pgtype.Interval{Microseconds: 5400000000, Status: pgtype.Present}},
{"2222", "bbbb", 34, time.Now(), "ZDE", pgtype.Interval{Microseconds: 9000000000, Status: pgtype.Present}},
{"3333", "cccc", 65, time.Now(), "IOM", pgtype.Interval{Microseconds: 5400000000, Status: pgtype.Present}},
{"4444", "dddd", 72, time.Now(), "ERW", pgtype.Interval{Microseconds: 7200000000, Status: pgtype.Present}},
}
for _, data := range testdata {
if _, err := stmt.Exec(ctx, data); err != nil {
fmt.Println("insert", err)
return
}
}
if err := stmt.Close(); err != nil {
fmt.Println("close", err)
return
}
}
var films []Film
if err := db.FindAll(ctx, &films, "SELECT * FROM films WHERE kind IN (:kind)", kra.NamedArg{Name: "kind", Value: []string{"CDR", "ZDE"}}); err != nil {
fmt.Println("find", err)
return
}fmt.Printf("%v\n", films)
}
```# Related OSS
- [pgx](https://github.com/jackc/pgx)
- [scany](https://github.com/georgysavva/scany)
- [sqlx](https://github.com/jmoiron/sqlx)