mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
104 lines
2.2 KiB
Go
104 lines
2.2 KiB
Go
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
|
|
}
|