mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Postgres Example (#490)
* creating postgres example - fixes #489 * postgres example glide fix * all the changes * use fn call * removing func.yaml * removing build.sh * test.sh cleanup
This commit is contained in:
committed by
Travis Reeder
parent
67af2757cd
commit
d565cc6afe
4
examples/postgres/.gitignore
vendored
Normal file
4
examples/postgres/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/func
|
||||
vendor
|
||||
|
||||
func.yaml
|
||||
25
examples/postgres/README.md
Normal file
25
examples/postgres/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Postgres INSERT/SELECT Function Image
|
||||
|
||||
This function executes an INSERT or SELECT against a table in a given postgres server.
|
||||
|
||||
```
|
||||
# Create your func.yaml file
|
||||
fn init <YOUR_DOCKERHUB_USERNAME>/func-postgres
|
||||
# Build the function
|
||||
fn build
|
||||
# Test it
|
||||
./test.sh
|
||||
# Push it to Docker Hub
|
||||
fn push
|
||||
# Create routes to this function on IronFunctions
|
||||
fn apps create <YOUR_APP> --config SERVER=<POSTGRES>
|
||||
fn routes create --config TABLE=<TABLE_NAME> --config COMMAND=INSERT <YOUR_APP> /<TABLE_NAME>/insert
|
||||
fn routes create --config TABLE=<TABLE_NAME> --config COMMAND=SELECT <YOUR_APP> /<TABLE_NAME>/select
|
||||
```
|
||||
|
||||
Now you can call your function on IronFunctions:
|
||||
|
||||
```
|
||||
echo <JSON_RECORD> | fn call /<YOUR_APP>/<TABLE_NAME>/insert
|
||||
echo <JSON_QUERY> | fn call /<YOUR_APP>/<TABLE_NAME>/select
|
||||
```
|
||||
103
examples/postgres/func.go
Normal file
103
examples/postgres/func.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
// command to execute, 'SELECT' or 'INSERT'
|
||||
command = os.Getenv("HEADER_COMMAND")
|
||||
// postgres host:port, e.g. 'postgres:5432'
|
||||
server = os.Getenv("HEADER_SERVER")
|
||||
// postgres table name
|
||||
table = os.Getenv("HEADER_TABLE")
|
||||
)
|
||||
|
||||
func main() {
|
||||
req, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrap(err, "failed to read stdin"))
|
||||
}
|
||||
|
||||
db, err := sql.Open("postgres", "postgres://postgres@" + server + "?sslmode=disable")
|
||||
if err != nil {
|
||||
log.Println("Failed to connect to postgres server")
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
switch command {
|
||||
case "SELECT":
|
||||
if resp, err := selectCommand(req, db); err != nil {
|
||||
log.Fatal(errors.Wrap(err, "select command failed"))
|
||||
} else {
|
||||
log.Println(resp)
|
||||
}
|
||||
case "INSERT":
|
||||
if err := insertCommand(req, db); err != nil {
|
||||
log.Fatal(errors.Wrap(err, "insert command failed"))
|
||||
}
|
||||
default:
|
||||
log.Fatalf("invalid command: %q", command)
|
||||
}
|
||||
}
|
||||
|
||||
func selectCommand(req []byte, db *sql.DB) (string, error) {
|
||||
// Parse request JSON
|
||||
var params map[string]interface{}
|
||||
if err := json.Unmarshal(req, ¶ms); err != nil {
|
||||
return "", errors.Wrap(err, "failed to parse json")
|
||||
}
|
||||
|
||||
// Build query and gather arguments
|
||||
var query bytes.Buffer
|
||||
var args []interface{}
|
||||
|
||||
query.WriteString("SELECT json_agg(t) FROM (SELECT * FROM ")
|
||||
query.WriteString(table)
|
||||
query.WriteString(" WHERE")
|
||||
first := true
|
||||
arg := 1
|
||||
for k, v := range params {
|
||||
args = append(args, v)
|
||||
|
||||
if !first {
|
||||
query.WriteString(" AND")
|
||||
}
|
||||
query.WriteString(" ")
|
||||
query.WriteString(k)
|
||||
query.WriteString("=$")
|
||||
query.WriteString(strconv.Itoa(arg))
|
||||
arg += 1
|
||||
first = false
|
||||
}
|
||||
query.WriteString(") AS t")
|
||||
|
||||
// Execute query
|
||||
r := db.QueryRow(query.String(), args...)
|
||||
var resp string
|
||||
if err := r.Scan(&resp); err != nil {
|
||||
return "", errors.Wrap(err, "failed to execute select query")
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func insertCommand(req []byte, db *sql.DB) error {
|
||||
q := "INSERT INTO " + table + " SELECT * FROM json_populate_record(null::" + table + ", $1)"
|
||||
_, err := db.Exec(q, req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to execute insert query")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
10
examples/postgres/glide.lock
generated
Normal file
10
examples/postgres/glide.lock
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
hash: 12ce0fe3e599891c7aeb6d5a99ff107b4f979e88ff5da7a6d5b1cf5cac8b1ad7
|
||||
updated: 2017-01-20T22:48:30.561728713Z
|
||||
imports:
|
||||
- name: github.com/lib/pq
|
||||
version: 67c3f2a8884c9b1aac5503c8d42ae4f73a93511c
|
||||
subpackages:
|
||||
- oid
|
||||
- name: github.com/pkg/errors
|
||||
version: 248dadf4e9068a0b3e79f02ed0a610d935de5302
|
||||
testImports: []
|
||||
4
examples/postgres/glide.yaml
Normal file
4
examples/postgres/glide.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
package: github.com/iron-io/functions/examples/postgres
|
||||
import:
|
||||
- package: github.com/lib/pq
|
||||
- package: github.com/pkg/errors
|
||||
39
examples/postgres/test.sh
Executable file
39
examples/postgres/test.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
docker stop test-postgres-func
|
||||
docker rm test-postgres-func
|
||||
|
||||
docker run -p 5432:5432 --name test-postgres-func -d postgres
|
||||
sleep 5s
|
||||
|
||||
docker run --rm -i --link test-postgres-func:postgres postgres psql -h postgres -U postgres -c 'CREATE TABLE people (first TEXT, last TEXT, age INTEGER);'
|
||||
|
||||
RECORD1='{
|
||||
"first": "John",
|
||||
"last": "Smith",
|
||||
"age": 30
|
||||
}'
|
||||
echo $RECORD1 | fn run -e SERVER=postgres:5432 -e COMMAND=INSERT -e TABLE=people --link test-postgres-func:postgres
|
||||
QUERY1='{
|
||||
"last": "Smith"
|
||||
}'
|
||||
echo $QUERY1 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
|
||||
|
||||
RECORD2='{
|
||||
"first": "Bob",
|
||||
"last": "Smith",
|
||||
"age": 43
|
||||
}'
|
||||
echo $RECORD2 | fn run -e SERVER=postgres:5432 -e COMMAND=INSERT -e TABLE=people --link test-postgres-func:postgres
|
||||
|
||||
echo $QUERY1 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
|
||||
|
||||
QUERY2='{
|
||||
"first": "John",
|
||||
"last": "Smith"
|
||||
}'
|
||||
echo $QUERY2 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
|
||||
|
||||
docker stop test-postgres-func
|
||||
docker rm test-postgres-func
|
||||
Reference in New Issue
Block a user