Add todo CLI app example of CRUD actions

scan-io
Jack Christensen 2014-07-17 09:16:13 -05:00
parent f7171f34e7
commit a2a828134c
4 changed files with 217 additions and 0 deletions

View File

@ -1,5 +1,6 @@
# Examples
* todo is a command line todo list that demonstrates basic CRUD actions.
* url_shortener contains a simple example of using pgx in a web context.
* (Tern)[https://github.com/jackc/tern] is a migration tool that uses pgx.
* (The Pithy Reader)[https://github.com/jackc/tpr] is a RSS aggregator that uses pgx.

72
examples/todo/README.md Normal file
View File

@ -0,0 +1,72 @@
# Description
This is a sample todo list implemented using pgx as the connector to a
PostgreSQL data store.
# Usage
Create a PostgreSQL database and run structure.sql into it to create the
necessary data schema.
Example:
createdb todo
psql todo < structure.sql
Build todo:
go build
## Connection configuration
The database connection is configured via enviroment variables.
* TODO_DB_HOST - defaults to localhost
* TODO_DB_USER - defaults to current OS user
* TODO_DB_PASSWORD - defaults to empty string
* TODO_DB_DATABASE - defaults to todo
You can either export them then run todo:
export TODO_DB_HOST=/private/tmp
./todo list
Or you can prefix the todo execution with the environment variables:
TODO_DB_HOST=/private/tmp ./todo list
## Add a todo item
./todo add 'Learn go'
## List tasks
./todo list
## Update a task
./todo add 1 'Learn more go'
## Delete a task
./todo remove 1
# Example Setup and Execution
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ createdb todo
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ psql todo < structure.sql
Expanded display is used automatically.
Timing is on.
CREATE TABLE
Time: 6.363 ms
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ go build
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ export TODO_DB_HOST=/private/tmp
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo list
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo add 'Learn Go'
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo list
1. Learn Go
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo update 1 'Learn more Go'
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo list
1. Learn more Go
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo remove 1
jack@hk-47~/dev/go/src/github.com/jackc/pgx/examples/todo$ ./todo list

140
examples/todo/main.go Normal file
View File

@ -0,0 +1,140 @@
package main
import (
"fmt"
"github.com/jackc/pgx"
"os"
"strconv"
)
var conn *pgx.Conn
func main() {
var err error
conn, err = pgx.Connect(extractConfig())
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to connection to database: %v\n", err)
os.Exit(1)
}
if len(os.Args) == 1 {
printHelp()
os.Exit(0)
}
switch os.Args[1] {
case "list":
err = listTasks()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to list tasks: %v\n", err)
os.Exit(1)
}
case "add":
err = addTask(os.Args[2])
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to add task: %v\n", err)
os.Exit(1)
}
case "update":
n, err := strconv.ParseInt(os.Args[2], 10, 32)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable convert task_num into int32: %v\n", err)
os.Exit(1)
}
err = updateTask(int32(n), os.Args[3])
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to update task: %v\n", err)
os.Exit(1)
}
case "remove":
n, err := strconv.ParseInt(os.Args[2], 10, 32)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable convert task_num into int32: %v\n", err)
os.Exit(1)
}
err = removeTask(int32(n))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to remove task: %v\n", err)
os.Exit(1)
}
default:
fmt.Fprintln(os.Stderr, "Invalid command")
printHelp()
os.Exit(1)
}
}
func listTasks() error {
rows, _ := conn.Query("select * from tasks")
for rows.Next() {
var id int32
var description string
err := rows.Scan(&id, &description)
if err != nil {
return err
}
fmt.Printf("%d. %s\n", id, description)
}
return rows.Err()
}
func addTask(description string) error {
_, err := conn.Exec("insert into tasks(description) values($1)", description)
return err
}
func updateTask(itemNum int32, description string) error {
_, err := conn.Exec("update tasks set description=$1 where id=$2", description, itemNum)
return err
}
func removeTask(itemNum int32) error {
_, err := conn.Exec("delete from tasks where id=$1", itemNum)
return err
}
func printHelp() {
fmt.Print(`Todo pgx demo
Usage:
todo list
todo add task
todo update task_num item
todo remove task_num
Example:
todo add 'Learn Go'
todo list
`)
}
func extractConfig() pgx.ConnConfig {
var config pgx.ConnConfig
config.Host = os.Getenv("TODO_DB_HOST")
if config.Host == "" {
config.Host = "localhost"
}
config.User = os.Getenv("TODO_DB_USER")
if config.User == "" {
config.User = os.Getenv("USER")
}
config.Password = os.Getenv("TODO_DB_PASSWORD")
config.Database = os.Getenv("TODO_DB_DATABASE")
if config.Database == "" {
config.Database = "todo"
}
return config
}

View File

@ -0,0 +1,4 @@
create table tasks (
id serial primary key,
description text not null
);