Skip to content

Commit

Permalink
dev: first release ever (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysiar authored May 19, 2024
1 parent 1bd2832 commit f081169
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
# Go workspace file
go.work

/test.db
/tests/test.db
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
get::
# go get -modfile=go_test.mod
go get -modfile=go.mod
# cp go_test.sum go.sum


tests::
rm -rf test.db
sqlite3 -batch test.db ""
#go test -v ./...
go test -modfile=go_test.mod ./... -v
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ for rows.Next() {
rec := Rows2Map(rows)
data = append(data, rec)
}

```

check also [go_sql_raw_test.go](go_sql_raw_test.go)

## TODO
* ...
* type converting from DB to go in function `update`

## Credits
* module inspired by https://gist.github.com/SchumacherFM/69a167bec7dea644a20e
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module github.com/mysiar-org/go-sql-raw

go 1.22.2

80 changes: 80 additions & 0 deletions go_sql_raw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package go_sql_raw

import (
"database/sql"
"fmt"
"log"
"strconv"
)

type RawSqlType map[string]interface{}

func Error(err error) {
if err != nil {
log.Fatal(err)
}
}

func Rows2Map(rows *sql.Rows) RawSqlType {
columns, err := rows.Columns()
columnTypes, err := rows.ColumnTypes()
Error(err)
rc := newMapRawSqlScan(columns, columnTypes)
err = rc.update(rows)
Error(err)
return rc.get()
}

type mapRawSqlScan struct {
cp []interface{}
row RawSqlType
colCount int
colNames []string
colTypes []*sql.ColumnType
}

func (s *mapRawSqlScan) update(rows *sql.Rows) error {
if err := rows.Scan(s.cp...); err != nil {
return err
}

for i := 0; i < s.colCount; i++ {
if rb, ok := s.cp[i].(*sql.RawBytes); ok {
val := string(*rb)
var parsed any
switch s.colTypes[i].DatabaseTypeName() {
case "DECIMAL":
parsed, _ = strconv.ParseFloat(val, 64)
case "INT":
parsed, _ = strconv.ParseInt(val, 10, 64)
default:
parsed = val
}
s.row[s.colNames[i]] = parsed
*rb = nil
} else {
return fmt.Errorf("Cannot convert index %d column %s to type *sql.RawBytes", i, s.colNames[i])
}
}

return nil
}

func (s *mapRawSqlScan) get() RawSqlType {
return s.row
}

func newMapRawSqlScan(columnNames []string, columnTypes []*sql.ColumnType) *mapRawSqlScan {
lenCN := len(columnNames)
s := &mapRawSqlScan{
cp: make([]interface{}, lenCN),
row: make(RawSqlType, lenCN),
colCount: lenCN,
colNames: columnNames,
colTypes: columnTypes,
}
for i := 0; i < lenCN; i++ {
s.cp[i] = new(sql.RawBytes)
}
return s
}
14 changes: 14 additions & 0 deletions go_test.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/mysiar-org/go-sql-raw

go 1.22.2

require (
github.com/mattn/go-sqlite3 v1.14.22
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 12 additions & 0 deletions go_test.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
72 changes: 72 additions & 0 deletions tests/go_sql_raw_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package tests

import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/mysiar-org/go-sql-raw"
"github.com/stretchr/testify/assert"
"strconv"
"testing"
)

func Test(t *testing.T) {
const file string = "test.db"
db, err := sql.Open("sqlite3", file)
chkError(err)
_, err = db.Exec(dropTable())
chkError(err)
_, err = db.Exec(createTable())
chkError(err)
_, err = db.Exec(insertData())
chkError(err)

var rows *sql.Rows
rows, err = db.Query("SELECT * FROM album ORDER BY id")

var data []go_sql_raw.RawSqlType
for rows.Next() {
rec := go_sql_raw.Rows2Map(rows)
data = append(data, rec)
}

var expectedIds = []int64{1, 2, 3, 4, 5}
var expectedPrices = []float64{56.99, 63.99, 17.99, 34.98, 80.99}
var expectedArtists = []string{"John Coltrane", "John Coltrane", "Gerry Mulligan", "Sarah Vaughan", "Schizma"}
var expectedTitle = []string{"Blue Train", "Giant Steps", "Jeru", "Sarah Vaughan", "Upadek"}

for idx, entry := range data {
id, _ := strconv.ParseInt(fmt.Sprintf("%v", entry["id"]), 10, 64)
assert.Equal(t, expectedIds[idx], id)
price, _ := strconv.ParseFloat(fmt.Sprintf("%v", entry["price"]), 64)
assert.Equal(t, expectedPrices[idx], price)
assert.Equal(t, expectedArtists[idx], entry["artist"])
assert.Equal(t, expectedTitle[idx], entry["title"])
}
}

func dropTable() string {
return "DROP TABLE IF EXISTS album"
}

func createTable() string {
return "CREATE TABLE album (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(128) NOT NULL, artist VARCHAR(255) NOT NULL, price DECIMAL(5,2) NOT NULL, PRIMARY KEY (`id`))"
}

func insertData() string {
return `
INSERT INTO album (id, title, artist, price)
VALUES
(1, 'Blue Train', 'John Coltrane', 56.99),
(2, 'Giant Steps', 'John Coltrane', 63.99),
(3, 'Jeru', 'Gerry Mulligan', 17.99),
(4, 'Sarah Vaughan', 'Sarah Vaughan', 34.98),
(5, 'Upadek', 'Schizma', 80.99)
`
}

func chkError(err error) {
if err != nil {
fmt.Println(err)
}
}

0 comments on commit f081169

Please sign in to comment.