Example #1
0
package store

import "github.com/manishrjain/gocrud/x"

var log = x.Log("store")

type Store interface {
	Init(dbtype string, tablename string)
	Commit(tablePrefix string, its []*x.Instruction) error
	IsNew(tablePrefix string, subject string) bool
	GetEntity(tablePrefix string, subject string) ([]x.Instruction, error)
}
Example #2
0
package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"time"

	"github.com/manishrjain/gocrud/api"
	"github.com/manishrjain/gocrud/helper"
	"github.com/manishrjain/gocrud/req"
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("server")
var c *req.Context

func read(w http.ResponseWriter, r *http.Request) {
	id, ok := x.ParseIdFromUrl(r, "/read/")
	if !ok {
		return
	}

	// API usage to read data.
	q := api.NewQuery("hack", id).UptoDepth(10)
	result, err := q.Run(c)
	if err != nil {
		x.SetStatus(w, x.E_ERROR, err.Error())
		return
	}
Example #3
0
	_ "github.com/go-sql-driver/mysql"
	"github.com/gocql/gocql"
	_ "github.com/lib/pq"
	"github.com/manishrjain/gocrud/api"
	"github.com/manishrjain/gocrud/req"
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var storeType = flag.String("store", "leveldb",
	"Available stores are cass for cassandra, "+
		"sql for MySQL, leveldb for LevelDB, "+
		"datastore for Google Datastore. "+
		"LevelDB is the default.")

var log = x.Log("social")
var c *req.Context

type Like struct {
	Id string `json:"id,omitempty"`
}

type Comment struct {
	Id      string    `json:"id,omitempty"`
	Comment []Comment `json:"Comment,omitempty"`
	Like    []Like    `json:"Like,omitempty"`
}

type Post struct {
	Id      string    `json:"id,omitempty"`
	Comment []Comment `json:"Comment,omitempty"`
Example #4
0
// This package is the initialization point for the api.
// In particular, in your init (/main) function, the flow
// is to create a req.Context and fill in required options.
// Setting table prefix, length for unique strings generated
// to assign to new entities, and setting the storage system.
package req

import "github.com/manishrjain/gocrud/x"

var log = x.Log("req")

type Context struct {
	NumCharsUnique int // 62^num unique strings
	Updates        chan x.Entity
	HasIndexer     bool
}

func NewContext(numChars int) *Context {
	ctx := new(Context)
	ctx.NumCharsUnique = numChars
	ctx.HasIndexer = false
	ctx.Updates = nil
	return ctx
}

func NewContextWithUpdates(numChars, buffer int) *Context {
	ctx := new(Context)
	ctx.NumCharsUnique = numChars
	ctx.Updates = make(chan x.Entity, buffer)
	ctx.HasIndexer = true
	return ctx
Example #5
0
// Package search provides a way to index entities and run relatively
// complicated search queries, best served outside of data stores, and
// by specialized search engines like ElasticSearch or Solr etc.
//
// This tackles the limitations caused by gocrud in terms of filtering
// and sort operations which would otherwise would need to be done at
// application level.
package search

import "github.com/manishrjain/gocrud/x"

var log = x.Log("search")

// All the search operations are run via this Search interface.
// Implement this interface to add support for a search engine.
// Note that the term Entity is being used interchangeably with
// the term Subject. An Entity has a kind, and has an id.

// Query interface provides the search api encapsulator, responsible for
// generating the right query for the engine, and then running it.
type Query interface {
	// NewAndFilter would return a filter which would run AND operation
	// among individual filter queries.
	NewAndFilter() FilterQuery

	// NewOrFilter would return a filter which would run OR operation
	// among individual filter queries.
	NewOrFilter() FilterQuery

	// From would set the offset from the first result. Use it along
	// with Limit(int) to do pagination.
Example #6
0
// To test this mongodb integration, run mongodb in docker
// docker run -d --name mongo -p 27017:27017 mongo:latest
// If on Mac, find the IP address of the docker host
// $ boot2docker ip
// 192.168.59.103
// For linux it's 127.0.0.1.

import (
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var log = x.Log("mongodb")

// MongoDB store backed by MongoDB
type MongoDB struct {
	session    *mgo.Session
	database   string
	collection string
}

// Init setup a new collection using the name provided
func (mdb *MongoDB) Init(args ...string) {
	if len(args) != 3 {
		log.WithField("args", args).Fatal("Invalid arguments")
		return
	}
Example #7
0
package memsearch

import (
	"errors"
	"fmt"
	"reflect"
	"regexp"
	"sort"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/manishrjain/gocrud/search"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("memsearch")

type MemSearch struct {
	docs map[string]x.Doc
}

type MemQuery struct {
	kind       string
	Docs       []x.Doc
	filter     *MemFilter
	filterType int // 0 = no filter, 1 = AND, 2 = OR
	from       int
	limit      int
	order      string
}
Example #8
0
import (
	"fmt"
	"io/ioutil"
	"time"

	_ "github.com/manishrjain/gocrud/drivers/leveldb"
	_ "github.com/manishrjain/gocrud/drivers/memsearch"
	"github.com/manishrjain/gocrud/indexer"
	"github.com/manishrjain/gocrud/req"
	"github.com/manishrjain/gocrud/search"
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("usage")

func ExampleStore() {
	path, err := ioutil.TempDir("", "gocrudldb_")
	if err != nil {
		x.LogErr(log, err).Fatal("Opening file")
		return
	}
	store.Get().Init(path) // leveldb

	// Update some data.
	c := req.NewContext(10) // 62^10 permutations
	err = store.NewUpdate("Root", "bigbang").SetSource("author").
		Set("when", "13.8 billion years ago").Set("explosive", true).Execute(c)
	if err != nil {
		x.LogErr(log, err).Fatal("Commiting update")
Example #9
0
package sqlstore

import (
	"database/sql"
	"fmt"

	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("sqlstore")

type Sql struct {
	db *sql.DB
}

var sqlInsert *sql.Stmt
var sqlIsNew, sqlSelect string

func (s *Sql) Init(args ...string) {
	if len(args) != 3 {
		log.WithField("args", args).Fatal("Invalid arguments")
		return
	}

	dbtype := args[0]
	source := args[1]
	tablename := args[2]

	var err error
	s.db, err = sql.Open(dbtype, source)
Example #10
0
package elasticsearch

import (
	"errors"
	"reflect"

	"github.com/manishrjain/gocrud/search"
	"github.com/manishrjain/gocrud/x"
	"gopkg.in/olivere/elastic.v2"
)

var log = x.Log("elasticsearch")

// Elastic encapsulates elastic search client, and implements methods declared
// by search.Engine.
type Elastic struct {
	client *elastic.Client
}

// ElasticQuery implements methods declared by search.Query.
type ElasticQuery struct {
	client     *elastic.Client
	sort       string
	from       int
	limit      int
	kind       string
	filter     *ElasticFilter
	filterType int // 0 = no filter, 1 = AND, 2 = OR
}

type ElasticFilter struct {
Example #11
0
// Cassandra driver can now be imported, and initialized in social.go,
// or any other client.
// import _ "github.com/manishrjain/gocrud/drivers/cassandra"
// Initialize in main():
// store.Get().Init("cassone", "crudtest", "instructions")
package cassandra

import (
	"fmt"

	"github.com/gocql/gocql"
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("cassandra")

type Cassandra struct {
	session *gocql.Session
}

var kIsNew, kInsert, kSelect, kScan string

func (cs *Cassandra) SetSession(session *gocql.Session) {
	cs.session = session
}

func (cs *Cassandra) Init(args ...string) {
	if len(args) != 3 && len(args) != 5 {
		log.WithField("args", args).Fatal("Invalid arguments")
		return
Example #12
0
package indexer

import (
	"sort"
	"sync"

	"github.com/manishrjain/gocrud/req"
	"github.com/manishrjain/gocrud/search"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("indexer")

// Indexer functions are called automatically by store operations.
// These functions are used to determine which entities need updating,
// and then re-generate their corresponding documents, which then get
// re-indexed into search engine, overwriting past
// (using versioning, if available) documents.
type Indexer interface {
	// OnUpdate is called when an entity is updated due to a Commit
	// on either itself, or it's direct children. Note that each
	// child entity would also be called with OnUpdate. This function
	// should return the Entity Ids, which need regeneration.
	OnUpdate(x.Entity) []x.Entity

	// Regenerate would be called on entities which need to be reprocessed
	// due to a change. The workflow is:
	// store.Commit -> search.OnUpdate -> Regenerate
	Regenerate(x.Entity) x.Doc
}
Example #13
0
package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/manishrjain/gocrud/req"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("api")

type Node struct {
	kind      string
	id        string
	source    string
	children  []*Node
	parent    *Node
	edges     map[string]interface{}
	Timestamp int64
}

func Get(kind, id string) *Node {
	log.WithFields(logrus.Fields{
		"func": "GetNode",
		"kind": kind,
		"id":   id,
	}).Debug("Called Get")
Example #14
0
// If on Mac, find the IP address of the docker host
// $ boot2docker ip
// 192.168.59.103
// For linux it's 127.0.0.1.
// Now you can go to 192.168.59.103:8080 (or 127.0.0.1:8080) and create
// table 'instructions'. Once created, create an index by going to
// 'Data Explorer', and running this:
// r.db('test').table('instructions').indexCreate('SubjectId')

import (
	r "github.com/dancannon/gorethink"
	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
)

var log = x.Log("rethinkdb")

type RethinkDB struct {
	session *r.Session
	table   string
}

func (rdb *RethinkDB) SetSession(session *r.Session) {
	rdb.session = session
}

func (rdb *RethinkDB) Init(args ...string) {
	if len(args) != 3 {
		log.WithField("args", args).Fatal("Invalid arguments")
		return
	}
Example #15
0
package leveldb

import (
	"errors"
	"fmt"

	"github.com/manishrjain/gocrud/store"
	"github.com/manishrjain/gocrud/x"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/filter"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"github.com/syndtr/goleveldb/leveldb/util"
)

var log = x.Log("leveldb")

type Leveldb struct {
	db  *leveldb.DB
	opt *opt.Options
}

func (l *Leveldb) SetBloomFilter(bits int) {
	l.opt = &opt.Options{
		Filter: filter.NewBloomFilter(bits),
	}
}

func (l *Leveldb) Init(args ...string) {
	if len(args) != 1 {
		log.WithField("args", args).Fatal("Invalid arguments")
		return