Skip to content

Commit

Permalink
Support round-tripping bytes (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude authored Dec 31, 2020
1 parent f8135d4 commit 8a9f1d5
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 48 deletions.
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ module github.com/babashka/pod-babashka-sqlite3
go 1.15

require (
github.com/babashka/pod-babashka-fswatcher v0.0.2
github.com/fsnotify/fsnotify v1.4.9
github.com/jackpal/bencode-go v1.0.0
github.com/mattn/go-sqlite3 v1.14.6
github.com/pborman/uuid v1.2.1 // indirect
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 // indirect
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d // indirect
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
github.com/shopspring/decimal v1.2.0 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ github.com/babashka/pod-babashka-fswatcher v0.0.2 h1:Voo/lIO7awMwL2X7YHjpcJQa76E
github.com/babashka/pod-babashka-fswatcher v0.0.2/go.mod h1:fsiTVpGHCNNGkz5Y3ZjwT4gzH7eu1jc6i4uFPva4HkI=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackpal/bencode-go v1.0.0 h1:lzbSPPqqSfWQnqVNe/BBY1NXdDpncArxShL10+fmFus=
github.com/jackpal/bencode-go v1.0.0/go.mod h1:5FSBQ74yhCl5oQ+QxRPYzWMONFnxbL68/23eezsBI5c=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d h1:A926QrjwToaPS7giC4UOBjHhdukq9l1Y15r3qkXYwCY=
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d/go.mod h1:Cpq811GTlHevuU6BZxk3ObOdK8AY5gHu9QGmDak0DT4=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a h1:yVNJFSzkEG8smsvd9udiQcMJA0MIsFvlG7ba314cu+s=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a/go.mod h1:TPq+fcJOdGrkpZpXF4UVmFjYxH0gGqnxdgZ+OzAmvJk=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
11 changes: 7 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package main

import (
"encoding/json"

"bytes"
"github.com/babashka/pod-babashka-sqlite3/babashka"
"github.com/babashka/pod-babashka-sqlite3/pod"
"github.com/russolsen/transit"
)

func main() {
Expand All @@ -27,10 +27,13 @@ func main() {
continue
}

if json, err := json.Marshal(res); err != nil {
buf := bytes.NewBufferString("")
encoder := transit.NewEncoder(buf, false)
if err := encoder.Encode(res); err != nil {
babashka.WriteErrorResponse(message, err)
} else {
babashka.WriteInvokeResponse(message, string(json))
//println("buf", buf.String())
babashka.WriteInvokeResponse(message, string(buf.String()))
}
}
}
11 changes: 11 additions & 0 deletions pod/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pod

import (

"fmt"
"os"
)

func Debug(v interface{}) {
fmt.Fprintf(os.Stderr, "debug: %+v\n", v)
}
90 changes: 53 additions & 37 deletions pod/main.go → pod/lib.go
Original file line number Diff line number Diff line change
@@ -1,84 +1,102 @@
package pod

import (
"container/list"
"database/sql"
"encoding/json"
"fmt"

"github.com/babashka/pod-babashka-sqlite3/babashka"
_ "github.com/mattn/go-sqlite3" // Import go-sqlite3 library
"github.com/russolsen/transit"
"strings"
_ "reflect"
)

type ExecResult struct {
RowsAffected int64 `json:"rows-affected"`
LastInsertedId int64 `json:"last-inserted-id"`
}

func JsonifyRows(rows *sql.Rows) ([]interface{}, error) {
columns, err := rows.Columns()
func encodeRows(rows *sql.Rows) ([]interface{}, error) {
cols, err := rows.Columns()
columns := make([]transit.Keyword, len(cols))
for i, col := range cols {
columns[i] = transit.Keyword(col)
}
if err != nil {
return nil, err
}

var data []interface{}

values := make([]interface{}, len(columns))
scanArgs := make([]interface{}, len(values))
for i := range values {
scanArgs[i] = &values[i]
}

c := 0
results := make(map[string]interface{})
var data []interface{}

for rows.Next() {
if c > 0 {
data = append(data, ",")
}

results := make(map[transit.Keyword]interface{})

if err = rows.Scan(scanArgs...); err != nil {
Debug(err)
return nil, err
}

for i, value := range values {
results[columns[i]] = value
for i, val := range values {
col := columns[i]
results[col] = val
}

// Debug(results)
// Debug(reflect.TypeOf(results))

data = append(data, results)
c++
}

return data, nil
}

func JsonifyResult(result sql.Result) (*ExecResult, error) {
type ExecResult = map[transit.Keyword]int64

func encodeResult(result sql.Result) (ExecResult, error) {
rowsAffected, err := result.RowsAffected()
lastInsertedId, err := result.LastInsertId()

if err != nil {
return nil, err
}

return &ExecResult{
RowsAffected: rowsAffected,
LastInsertedId: lastInsertedId,
}, nil
res := ExecResult{
transit.Keyword("rows-affected"): rowsAffected,
transit.Keyword("last-inserted-id"): lastInsertedId,
}
return res, nil
}

func listToSlice(l *list.List) []interface{} {
slice := make([]interface{}, l.Len())
cnt := 0
for e := l.Front(); e != nil; e = e.Next() {
slice[cnt] = e.Value
cnt++
}
return slice
}

func parseQuery(args string) (string, string, []interface{}, error) {
podArgs := []json.RawMessage{}
if err := json.Unmarshal([]byte(args), &podArgs); err != nil {
reader := strings.NewReader(args)
decoder := transit.NewDecoder(reader)
value, err := decoder.Decode()

if err != nil {
return "", "", nil, err
}
var theList *list.List
theList = value.(*list.List)
theSlice := listToSlice(theList)

var db string
if err := json.Unmarshal(podArgs[0], &db); err != nil {
return "", "", nil, err
}
db = theSlice[0].(string)
// println("db", db)

var queryArgs []interface{}
if err := json.Unmarshal(podArgs[1], &queryArgs); err != nil {
return "", "", nil, err
}
queryArgs = theSlice[1].([]interface{})

var query string
query = queryArgs[0].(string)
Expand All @@ -100,7 +118,7 @@ func ProcessMessage(message *babashka.Message) (interface{}, error) {
switch message.Op {
case "describe":
return &babashka.DescribeResponse{
Format: "json",
Format: "transit+json",
Namespaces: []babashka.Namespace{
{
Name: "pod.babashka.sqlite3",
Expand Down Expand Up @@ -128,16 +146,14 @@ func ProcessMessage(message *babashka.Message) (interface{}, error) {

defer conn.Close()

//args := makeArgs(query)

switch message.Var {
case "pod.babashka.sqlite3/execute!":
res, err := conn.Exec(query, args...)
if err != nil {
return nil, err
}

if json, err := JsonifyResult(res); err != nil {
if json, err := encodeResult(res); err != nil {
return nil, err
} else {
return json, nil
Expand All @@ -148,7 +164,7 @@ func ProcessMessage(message *babashka.Message) (interface{}, error) {
return nil, err
}

if json, err := JsonifyRows(res); err != nil {
if json, err := encodeRows(res); err != nil {
return nil, err
} else {
return json, nil
Expand Down
13 changes: 8 additions & 5 deletions test/script.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@
(def png (java.nio.file.Files/readAllBytes (.toPath (io/file "resources/babashka.png"))))

(prn (sqlite/execute! "/tmp/foo.db" ["insert into foo (the_text, the_int, the_real, the_blob) values (?,?,?,?)" "foo" 1 3.14 png]))
(prn (sqlite/execute! "/tmp/foo.db" ["insert into foo (the_text, the_int, the_real) values (?,?,?)" "foo" 2 1.5]))

(def results (sqlite/query! "/tmp/foo.db" ["select * from foo"]))
(def results (sqlite/query! "/tmp/foo.db" ["select * from foo order by the_int desc"]))

(def results-min-png (update results 0 #(dissoc % :the_blob)))
(def results-min-png (update results 1 #(dissoc % :the_blob)))
(prn results-min-png)

(deftest results-test
(is (= [{:the_int 1, :the_real 3.14, :the_text "foo"}] results-min-png)))
(is (= [{:the_int 2, :the_real 1.5, :the_blob nil, :the_text "foo"}
{:the_int 1, :the_real 3.14, :the_text "foo"}]
results-min-png)))

;; TODO:
(prn (count png) (count (get-in results [0 :the_blob])))
(deftest bytes-roundtrip
(is (= (count png) (count (get-in results [1 :the_blob])))))

(let [{:keys [:fail :error]} (t/run-tests)]
(System/exit (+ fail error)))

0 comments on commit 8a9f1d5

Please sign in to comment.