Skip to content

Instantly share code, notes, and snippets.

/.phonebookrc Secret

Created May 28, 2015 12:31
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save anonymous/00331198b25ce71cb2c1 to your computer and use it in GitHub Desktop.
Save anonymous/00331198b25ce71cb2c1 to your computer and use it in GitHub Desktop.
REST API
host = "127.0.0.1"
port = "5432"
sslmode="disable"
dbname = "mydb"
user = "admin"
pass = "qwerty"
package main
import (
"database/sql"
)
func insert(name, phone string) (sql.Result, error) {
return db.Exec("INSERT INTO phonebook VALUES (default, $1, $2)",
name, phone)
}
func remove(id int) (sql.Result, error) {
return db.Exec("DELETE FROM phonebook WHERE id=$1", id)
}
func update(id int, name, phone string) (sql.Result, error) {
return db.Exec("UPDATE phonebook SET name = $1, phone = $2 WHERE id=$3",
name, phone, id)
}
func readOne(id int) (Record, error) {
var rec Record
row := db.QueryRow("SELECT * FROM phonebook WHERE id=$1 ORDER BY id", id)
return rec, row.Scan(&rec.Id, &rec.Name, &rec.Phone)
}
func read(str string) ([]Record, error) {
var rows *sql.Rows
var err error
if str != "" {
rows, err = db.Query("SELECT * FROM phonebook WHERE name LIKE $1 ORDER BY id",
"%"+str+"%")
} else {
rows, err = db.Query("SELECT * FROM phonebook ORDER BY id")
}
if err != nil {
return nil, err
}
defer rows.Close()
var rs = make([]Record, 0)
var rec Record
for rows.Next() {
if err = rows.Scan(&rec.Id, &rec.Name, &rec.Phone); err != nil {
return nil, err
}
rs = append(rs, rec)
}
if err = rows.Err(); err != nil {
return nil, err
}
return rs, nil
}
package main
import (
"database/sql"
"encoding/json"
"net/http"
"strconv"
"github.com/julienschmidt/httprouter"
)
type Record struct {
Id int `json:"id"`
Name string `json:"name"`
Phone string `json:"phone"`
}
func getID(w http.ResponseWriter, ps httprouter.Params) (int, bool) {
id, err := strconv.Atoi(ps.ByName("id"))
if err != nil {
w.WriteHeader(400)
return 0, false
}
return id, true
}
func getRecords(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var str string
if len(r.URL.RawQuery) > 0 {
str = r.URL.Query().Get("name")
if str == "" {
w.WriteHeader(400)
return
}
}
recs, err := read(str)
if err != nil {
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(recs); err != nil {
w.WriteHeader(500)
}
}
func getRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id, ok := getID(w, ps)
if !ok {
return
}
rec, err := readOne(id)
if err != nil {
if err == sql.ErrNoRows {
w.WriteHeader(404)
return
}
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(rec); err != nil {
w.WriteHeader(500)
}
}
func addRecord(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var rec Record
err := json.NewDecoder(r.Body).Decode(&rec)
if err != nil || rec.Name == "" || rec.Phone == "" {
w.WriteHeader(400)
return
}
if _, err := insert(rec.Name, rec.Phone); err != nil {
w.WriteHeader(500)
return
}
w.WriteHeader(201)
}
func updateRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id, ok := getID(w, ps)
if !ok {
return
}
var rec Record
err := json.NewDecoder(r.Body).Decode(&rec)
if err != nil || rec.Name == "" || rec.Phone == "" {
w.WriteHeader(400)
return
}
res, err := update(id, rec.Name, rec.Phone)
if err != nil {
w.WriteHeader(500)
return
}
n, _ := res.RowsAffected()
if n == 0 {
w.WriteHeader(404)
return
}
w.WriteHeader(204)
}
func deleteRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id, ok := getID(w, ps)
if !ok {
return
}
if _, err := remove(id); err != nil {
w.WriteHeader(500)
}
w.WriteHeader(204)
}
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"os/user"
"github.com/FogCreek/mini"
"github.com/julienschmidt/httprouter"
_ "github.com/lib/pq"
)
func fatal(err error) {
if err != nil {
log.Fatal(err)
}
}
func params() string {
u, err := user.Current()
fatal(err)
cfg, err := mini.LoadConfiguration(u.HomeDir + "/.phonebookrc")
fatal(err)
info := fmt.Sprintf("host=%s port=%s dbname=%s "+
"sslmode=%s user=%s password=%s ",
cfg.String("host", "127.0.0.1"),
cfg.String("port", "5432"),
cfg.String("dbname", u.Username),
cfg.String("sslmode", "disable"),
cfg.String("user", u.Username),
cfg.String("pass", ""),
)
return info
}
var db *sql.DB
func main() {
var err error
db, err = sql.Open("postgres", params())
fatal(err)
defer db.Close()
_, err = db.Exec("CREATE TABLE IF NOT EXISTS " +
`phonebook("id" SERIAL PRIMARY KEY,` +
`"name" varchar(50), "phone" varchar(100))`)
fatal(err)
router := httprouter.New()
router.GET("/api/v1/records", getRecords)
router.GET("/api/v1/records/:id", getRecord)
router.POST("/api/v1/records", addRecord)
router.PUT("/api/v1/records/:id", updateRecord)
router.DELETE("/api/v1/records/:id", deleteRecord)
http.ListenAndServe(":8080", router)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment