pivot

package module
v2.5.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2018 License: LGPL-2.1 Imports: 27 Imported by: 6

README

Pivot GoDoc TravisCI

Pivot is a library used to access, query, and aggregate data across a variety of database systems, written in Golang.

Where: Packages and Usage

Pivot is organized into multiple sub-packages that perform various functions:

Package What it does...
pivot Entry point for the package. Connect to a database from here.
pivot/dal Data Abstraction Layer; provides a database-agnostic view of collections (i.e: tables), records (i.e.: rows), and the fields that make up those records (i.e.: columns).
pivot/filter A database-agnostic representation of queries that return some subset of the data from a collection.
pivot/mapper A more user-friendly data mapping layer that provides more traditional ODM/ORM semantics for working with collections.
pivot/backends Where all the database and search index adapters live.
pivot/utils Utilities largely used within the rest of this library.

Supported Backends

Below is a table describing which data systems are currently supported. For systems with Backend support, Pivot can create and delete collections, and create/retrieve/update/delete records by their primary key / ID. If a system has Indexer support, Pivot can perform arbitrary queries against collections using a standard filter syntax, and return the results as a set of standard Record objects.

Product Backend Indexer
MySQL / MariaDB X X
PostgreSQL X X
SQLite 3.x X X
Filesystem X X
MongoDB X X
Amazon DynamoDB X
Elasticsearch X

How: Examples

Example 1: Basic CRUD operations using the mapper.Mapper interface

Here is a simple example for connecting to a SQLite database, creating a table; and inserting, retrieving, and deleting a record.

package main

import (
    "fmt"
    "time"

    "github.com/ghetzel/pivot"
    "github.com/ghetzel/pivot/dal"
    "github.com/ghetzel/pivot/mapper"
)

var Widgets mapper.Mapper

var WidgetsSchema = &dal.Collection{
    Name:                   `widgets`,
    IdentityFieldType:      dal.StringType,
    IdentityFieldFormatter: dal.GenerateUUID,
    Fields: []dal.Field{
        {
            Name:        `type`,
            Description: `The type of widget.`,
            Type:        dal.StringType,
            Validator:   dal.ValidateIsOneOf(`foo`, `bar`, `baz`),
            Required:    true,
        }, {
            Name:        `usage`,
            Description: `Short description on how to use this widget.`,
            Type:        dal.StringType,
        }, {
            Name:        `created_at`,
            Description: `When the widget was created.`,
            Type:        dal.TimeType,
            Formatter:   dal.CurrentTimeIfUnset,
        }, {
            Name:        `updated_at`,
            Description: `Last time the widget was updated.`,
            Type:        dal.TimeType,
            Formatter:   dal.CurrentTime,
        },
    },
}

type Widget struct {
    ID        string    `pivot:"id,identity"`
    Type      string    `pivot:"type"`
    Usage     string    `pivot:"usage"`
    CreatedAt time.Time `pivot:"created_at"`
    UpdatedAt time.Time `pivot:"updated_at"`
}

func main() {
    // setup a new backend instance based on the supplied connection string
    if backend, err := pivot.NewDatabase(`sqlite:///./test.db`); err == nil {

        // initialize the backend (connect to/open it)
        if err := backend.Initialize(); err == nil {

            // register models to this database backend
            Widgets = mapper.NewModel(backend, WidgetsSchema)

            // create the model tables if they don't exist
            if err := Widgets.Migrate(); err != nil {
                fmt.Printf("failed to create widget table: %v\n", err)
                return
            }

            // make a new Widget instance, containing the data we want to see
            // the ID field will be populated after creation with the auto-
            // generated UUID.
            newWidget := Widget{
                Type:  `foo`,
                Usage: `A fooable widget.`,
            }

            // insert a widget (ID will be auto-generated because of dal.GenerateUUID)
            if err := Widgets.Create(&newWidget); err != nil {
                fmt.Printf("failed to insert widget: %v\n", err)
                return
            }

            // retrieve the widget using the ID we just got back
            var gotWidget Widget

            if err := Widgets.Get(newWidget.ID, &gotWidget); err != nil {
                fmt.Printf("failed to retrieve widget: %v\n", err)
                return
            }

            fmt.Printf("Got Widget: %#+v", gotWidget)

            // delete the widget
            if err := Widgets.Delete(newWidget.ID); err != nil {
                fmt.Printf("failed to delete widget: %v\n", err)
                return
            }
        } else {
            fmt.Printf("failed to initialize backend: %v\n", err)
            return
        }
    } else {
        fmt.Printf("failed to create backend: %v\n", err)
        return
    }

}

Why: Why Use This?

The ability to mix and match persistent structured data storage and retrieval mechanisms with various indexing strategies is a powerful one. The idea here is to provide a common interface for systems to integrate with in a way that doesn't tightly couple those systems to specific databases, query languages, and infrastructures. It's an attempt to deliver on the promises of traditional ORM/ODM libraries in a platform- and language-agnostic way.

Documentation

Index

Constants

View Source
const ApplicationName = `pivot`
View Source
const ApplicationSummary = `an extensible database abstraction service`
View Source
const ApplicationVersion = `2.5.0`

Variables

View Source
var DefaultAddress = `127.0.0.1`
View Source
var DefaultPort = 29029
View Source
var DefaultResultLimit = 25
View Source
var DefaultUiDirectory = `embedded`
View Source
var MonitorCheckInterval = time.Duration(10) * time.Second
View Source
var NetrcFile = ``

Functions

func Dir

func Dir(useLocal bool, name string) http.FileSystem

Dir returns a http.Filesystem for the embedded assets on a given prefix dir. If useLocal is true, the filesystem's contents are instead used.

func FS

func FS(useLocal bool) http.FileSystem

FS returns a http.Filesystem for the embedded assets. If useLocal is true, the filesystem's contents are instead used.

func FSByte

func FSByte(useLocal bool, name string) ([]byte, error)

FSByte returns the named file from the embedded assets. If useLocal is true, the filesystem's contents are instead used.

func FSMustByte

func FSMustByte(useLocal bool, name string) []byte

FSMustByte is the same as FSByte, but panics if name is not present.

func FSMustString

func FSMustString(useLocal bool, name string) string

FSMustString is the string version of FSMustByte.

func FSString

func FSString(useLocal bool, name string) (string, error)

FSString is the string version of FSByte.

func LoadSchemataFromFile

func LoadSchemataFromFile(filename string) ([]*dal.Collection, error)

func NewDatabase

func NewDatabase(connection string) (backends.Backend, error)

func NewDatabaseWithOptions

func NewDatabaseWithOptions(connection string, options backends.ConnectOptions) (backends.Backend, error)

Types

type Configuration

type Configuration struct {
	Backend      string                   `json:"backend"`
	Indexer      string                   `json:"indexer"`
	Environments map[string]Configuration `json:"environments"`
}

func LoadConfigFile

func LoadConfigFile(path string) (Configuration, error)

func (*Configuration) ForEnv

func (self *Configuration) ForEnv(env string) Configuration

type Server

type Server struct {
	Address          string
	ConnectionString string
	ConnectOptions   backends.ConnectOptions
	UiDirectory      string
	// contains filtered or unexported fields
}

func NewServer

func NewServer(connectionString ...string) *Server

func (*Server) AddSchemaDefinition

func (self *Server) AddSchemaDefinition(filename string)

func (*Server) ListenAndServe

func (self *Server) ListenAndServe() error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL