github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/model/model.go (about)

     1  // Package model implements convenience methods for
     2  // managing indexes on top of the Store.
     3  // See this doc for the general idea https://github.com/m3o/dev/blob/feature/storeindex/design/auto-indexes.md
     4  // Prior art/Inspirations from github.com/gocassa/gocassa, which
     5  // is a similar package on top an other KV store (Cassandra/gocql)
     6  package model
     7  
     8  import (
     9  	"context"
    10  	"errors"
    11  
    12  	"github.com/tickoalcantara12/micro/v3/service/store"
    13  )
    14  
    15  var (
    16  	ErrorNilInterface         = errors.New("interface is nil")
    17  	ErrorNotFound             = errors.New("not found")
    18  	ErrorMultipleRecordsFound = errors.New("multiple records found")
    19  )
    20  
    21  type OrderType string
    22  
    23  const (
    24  	OrderTypeUnordered = OrderType("unordered")
    25  	OrderTypeAsc       = OrderType("ascending")
    26  	OrderTypeDesc      = OrderType("descending")
    27  )
    28  
    29  const (
    30  	queryTypeEq  = "eq"
    31  	indexTypeEq  = "eq"
    32  	queryTypeAll = "all"
    33  	indexTypeAll = "all"
    34  )
    35  
    36  var (
    37  	// DefaultKey is the default field for indexing
    38  	DefaultKey = "ID"
    39  
    40  	// DefaultIndex is the ID index
    41  	DefaultIndex = newIndex("ID")
    42  
    43  	// DefaultModel is the default model
    44  	DefaultModel = NewModel()
    45  )
    46  
    47  // Model represents a place where data can be saved to and
    48  // queried from.
    49  type Model interface {
    50  	// Context sets the context for the model returning a new copy
    51  	Context(ctx context.Context) Model
    52  	// Register a new model eg. User struct, Order struct
    53  	Register(v interface{}) error
    54  	// Create a new object. (Maintains indexes set up)
    55  	Create(v interface{}) error
    56  	// Update will take an existing object and update it.
    57  	// TODO: Make use of "sync" interface to lock, read, write, unlock
    58  	Update(v interface{}) error
    59  	// Read accepts a pointer to a value and expects to fine one or more
    60  	// elements. Read throws an error if a value is not found or we can't
    61  	// find a matching index for a slice based query.
    62  	Read(query Query, resultPointer interface{}) error
    63  	// Deletes a record. Delete only support Equals("id", value) for now.
    64  	// @todo Delete only supports string keys for now.
    65  	Delete(query Query) error
    66  }
    67  
    68  type Options struct {
    69  	// Database sets the default database
    70  	Database string
    71  	// Table sets the default table
    72  	Table string
    73  	// Enable debug logging
    74  	Debug bool
    75  	// The indexes to use for queries
    76  	Indexes []Index
    77  	// Namespace to scope to
    78  	Namespace string
    79  	// Store is the storage engine
    80  	Store store.Store
    81  	// Context is the context for all model queries
    82  	Context context.Context
    83  	// Key is the fiel name of the primary key
    84  	Key string
    85  }
    86  
    87  type Option func(*Options)
    88  
    89  // WithDatabase sets the default database for queries
    90  func WithDatabase(db string) Option {
    91  	return func(o *Options) {
    92  		o.Database = db
    93  	}
    94  }
    95  
    96  // WithTable sets the default table for queries
    97  func WithTable(t string) Option {
    98  	return func(o *Options) {
    99  		o.Table = t
   100  	}
   101  }
   102  
   103  // WithContext sets the context for all queries
   104  func WithContext(ctx context.Context) Option {
   105  	return func(o *Options) {
   106  		o.Context = ctx
   107  	}
   108  }
   109  
   110  // WithIndexes creates an option with the given indexes
   111  func WithIndexes(idx ...Index) Option {
   112  	return func(o *Options) {
   113  		o.Indexes = idx
   114  	}
   115  }
   116  
   117  // WithStore create an option for setting the store
   118  func WithStore(s store.Store) Option {
   119  	return func(o *Options) {
   120  		o.Store = s
   121  	}
   122  }
   123  
   124  // WithDebug enables debug logging
   125  func WithDebug(d bool) Option {
   126  	return func(o *Options) {
   127  		o.Debug = d
   128  	}
   129  }
   130  
   131  // WithNamespace sets the namespace to scope to
   132  func WithNamespace(ns string) Option {
   133  	return func(o *Options) {
   134  		o.Namespace = ns
   135  	}
   136  }
   137  
   138  // WithKey sets the Key
   139  func WithKey(idField string) Option {
   140  	return func(o *Options) {
   141  		o.Key = idField
   142  	}
   143  }