Documentation ¶
Overview ¶
Package sql is a REST Layer resource storage handler for databases supported via drivers for database/sql. It implements the Storer interface defined in rest-layer/resource/storage.go.
Example ¶
package main import ( "database/sql" "log" "net/http" "os" "github.com/jxstanford/rest-layer-sqlite3" _ "github.com/mattn/go-sqlite3" "github.com/rs/cors" "github.com/rs/rest-layer/resource" "github.com/rs/rest-layer/rest" "github.com/rs/rest-layer/schema" ) const ( DB_DRIVER = "sqlite3" DB_FILE = "./example.db" USER_TABLE = "users" POST_TABLE = "posts" ENABLE_FK = "PRAGMA foreign_keys = ON;" USERS_UP_DDL = "CREATE TABLE `" + USER_TABLE + "` (`id` VARCHAR(128) PRIMARY KEY,`etag` VARCHAR(128),`updated` VARCHAR(128),`created` VARCHAR(128), `name` VARCHAR(150));" POSTS_UP_DDL = "CREATE TABLE `" + POST_TABLE + "` (`id` VARCHAR(128) PRIMARY KEY,`etag` VARCHAR(128),`updated` VARCHAR(128), `created` VARCHAR(128), `user` VARCHAR(128) REFERENCES users(id) ON DELETE CASCADE, `public` INTEGER, `title` VARCHAR(150), `body` VARCHAR(100000));" USERS_DN_DDL = "DROP TABLE `" + USER_TABLE + "`;" POSTS_DN_DDL = "DROP TABLE `" + POST_TABLE + "`;" ) var ( user = schema.Schema{ "id": schema.IDField, "created": schema.CreatedField, "updated": schema.UpdatedField, "name": schema.Field{ Required: true, Filterable: true, Sortable: true, Validator: &schema.String{ MaxLen: 150, }, }, } // Define a post resource schema post = schema.Schema{ "id": schema.IDField, "created": schema.CreatedField, "updated": schema.UpdatedField, "user": schema.Field{ Required: true, Filterable: true, Validator: &schema.Reference{ Path: "users", }, }, "public": schema.Field{ Filterable: true, Validator: &schema.Bool{}, }, "title": schema.Field{ Required: true, Validator: &schema.String{ MaxLen: 150, }, }, "body": schema.Field{ Validator: &schema.String{ MaxLen: 100000, }, }, } ) // handler returns a new handler with the database and table information, // or an error. func main() { dbDn() // get a database connection and set up the tables. db, err := sql.Open(DB_DRIVER, DB_FILE) if err != nil { log.Fatal(err) } dbUp(db) //defer dbDn(db) index := resource.NewIndex() users := index.Bind("users", resource.New(user, sqlite3.NewHandler(db, USER_TABLE), resource.Conf{ AllowedModes: resource.ReadWrite, })) users.Bind("posts", "user", resource.New(post, sqlite3.NewHandler(db, POST_TABLE), resource.Conf{ AllowedModes: resource.ReadWrite, })) api, err := rest.NewHandler(index) if err != nil { log.Fatalf("Invalid API configuration: %s", err) } http.Handle("/", cors.New(cors.Options{OptionsPassthrough: true}).Handler(api)) log.Print("Serving API on http://localhost:8080") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } } func dbDn() { err := os.Remove(DB_FILE) if err != nil { //log.Warn(err) } } func dbUp(db *sql.DB) { var err error _, err = db.Exec(ENABLE_FK) if err != nil { log.Fatal(err) } _, err = db.Exec(USERS_UP_DDL) if err != nil { log.Fatal(err) } _, err = db.Exec(POSTS_UP_DDL) if err != nil { log.Fatal(err) } }
Output:
Index ¶
- Constants
- type Handler
- func (h *Handler) Clear(ctx context.Context, lookup *resource.Lookup) (int, error)
- func (h *Handler) Delete(ctx context.Context, item *resource.Item) error
- func (h *Handler) Find(ctx context.Context, lookup *resource.Lookup, page, perPage int) (*resource.ItemList, error)
- func (h *Handler) Insert(ctx context.Context, items []*resource.Item) error
- func (h *Handler) Update(ctx context.Context, item *resource.Item, original *resource.Item) error
Examples ¶
Constants ¶
const (
SQL_NOTFOUND_ERR = "sql: no rows in result set"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler contains the session and table information for a SQL DB.
func NewHandler ¶
NewHandler creates an new SQL DB session handler.
func (*Handler) Clear ¶
Clear removes all items matching the lookup and returns the number of items removed as the first value. If a query operation is not implemented by the storage handler, a resource.ErrNotImplemented is returned.
func (*Handler) Delete ¶
Delete deletes the provided item by its ID. The Etag of the item stored in the backend store must match the Etag of the provided item or a resource.ErrConflict must be returned. This check should be performed atomically.
If the provided item were not present in the backend store, a resource.ErrNotFound must be returned.
If the removal of the data is not immediate, the method must listen for cancellation on the passed ctx. If the operation is stopped due to context cancellation, the function must return the result of the ctx.Err() method.
func (*Handler) Find ¶
func (h *Handler) Find(ctx context.Context, lookup *resource.Lookup, page, perPage int) (*resource.ItemList, error)
Find searches for items in the backend store matching the lookup argument. If no items are found, an empty list is returned with no error. If a query operation is not implemented, a resource.ErrNotImplemented is returned.
func (*Handler) Insert ¶
Insert stores new items in the backend store. If any of the items already exist, no item should be inserted and a resource.ErrConflict must be returned. The insertion of the items is performed atomically.