tml-mongo

TML mongo support

npm install tml-mongo
3 downloads in the last week
12 downloads in the last month

tml-mongo(3) -- Mongo support

SYNOPSIS

tml-mongo mongo support.

OPTIONS

SYNTAX

ENVIRONMENT

RETURN VALUES

STANDARDS

SECURITY CONSIDERATIONS

BUGS

HISTORY

AUTHOR

SEE ALSO

IMPLEMENTATION


Mongo

    @purpose Wrapper for mongo;
    @author Erin Phillips;
    @version 0.0.2-9;
    @history 2013-04-30 EMP [0.0.2-1] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-2] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-3] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-4] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-5] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-6] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-7] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-8] add-tml-build;
    @history 2013-04-30 EMP [0.0.2-9] add-tml-build;

resources

    CON = console
    MDB = mongodb
    CORE = tml-core [Core]
    NET = tml-network
    CACHE = tml-cache

locals

    mdbClient = MDB::MongoClient
        @purpose make a connection;

notes

    @need N index values by location;
    @need N insert, update, inc, dec, delete;

messages

    ERR-DB.100 {*} Invalid database URL [{1} {2}];
    ERR-DB.101 {*} Database error [{1} {2}];

    ERR-TBL.100 {*} Table error [{1} {2}];

code

-- PATTERNS --;

pattern patCacheMaker :t :cache

    <<<
    ##anvil make:t $ -> %:t
        b = :cache.get(a)
        ifnot b
          b = new :t(a)
          :cache.set(b);;
    >>>

-- STATICS --;

var dbCache = new CACHE::Store('Db',10,12)

render patCacheMaker Db dbCache;

var tableCache = new CACHE::Store('Tbl',80,100)

render patCacheMaker Table tableCache;

-- TYPES --;

type Db(@name$)

    uses CORE::Hash
    initial state NEW -> OPEN;
    state OPEN -> NEW;

method getName -> $

    =@name;

method getUrl -> $

    =@url;

method open conn? cb&1 -> this

    if ami OPEN
        cb(@me)
    else

        case-if conn
          $
            @url=conn
          %NET::Connection
            @url=con 'mongodb://' conn.getAddr() ':' conn.getPort() '/' @name '?';
        ;
        mdbClient.connect(@url,@getHash(),
          func e? mdbDb% 
            enforce nullval e ERR-DB.100(@url,e)
            @mdbDb = mdbDb
            iam OPEN
            cb(@me)
          ;);;

method withTable $ &2 -> this

  enforce ami OPEN ERR-DB.100(@name,'not open')
  @mdbDb.collection(a,b);

type Table(@name$)

  initial state NEW -> OPEN;
  state OPEN ->;

method getName -> $

    =@name;

method open %Db &1 -> this

    if ami OPEN
        b(@me)
    else
        a.withTable(@name,
          func e? mdbColl%
            enforce nullval e ERR-TBL.100(@name,e)
            @mdbColl = mdbColl
            iam OPEN
            b(@me)
          ;);;

method insert %Record &2

  enforce ami OPEN ERR-TBL.100(@name,'not open')
  @mdbColl.insert(a.getHash(),{w:1},b)
;

method upsert %Record &2

  enforce ami OPEN ERR-TBL.100(@name,'not open')
  @mdbColl.save(a.getHash(),{w:1},b)
;

method update %QuerySpec %UpdateSpec &2

  enforce ami OPEN ERR-TBL.100(@name,'not open')
  if b.options
    @mdbColl.update(a.getHash(),b.updateConfig,b.options,c)
  else
    @mdbColl.update(a.getHash(),b.updateConfig,c)
  ;
;

method remove %DeleteSpec &2

  enforce ami OPEN ERR-TBL.100(@name,'not open')
  if b.options
    @mdbColl.remove(a.getHash(),a.options,b)
  else
    @mdbColl.remove(a.getHash(),b)
  ;
;

type DeleteSpec(values%={})

    uses CORE::Hash(values)

method setJustOne ! -> this (coalesce= @options {}).justOne=a;

type QuerySpec(values%={})

    uses CORE::Hash(values)

type Record(values%={})

    uses CORE::Hash(values)

type UpdateSpec(values%={},@verb$='$set')

    uses CORE::Hash(values)
    @updateConfig={}
    @updateConfig[@verb]=@config;

method setMulti ! -> this

    (coalesce= @options {}).multi=a;

type IncrementSpec(values%={})

    extends UpdateSpec(values,'$inc')

-- TESTS --;

test DB

    vars netConn=new NET::Connection('localhost',27017);

    dbName='testdb'
    o=makeDb(dbName)

test-eq : should return database name

    o.getName() vs dbName

test-async : should open the database

    o.open(netConn,func db%Db done(););

    ;

test TABLE_INSERT

    vars netConn=new NET::Connection('localhost',27017)
        dbName='testdb'
        numberItems=100
        tableName='testTableInsert';

test-async : should insert into a table

    makeDb(dbName)
    .open(netConn,
      func db%Db
        enforce eq$ o.getUrl() db.getUrl() 'URL mismatch'
        makeTable(tableName)
          .open(db,
            func table%Table
              table.remove(new DeleteSpec(),
                func e3? opt ?
                  vars recList=[];
                  enforce nullval e3 (con 'Table ' table.getName() ' delete failed.')
                  count 1 to numberItems as i push recList new Record({_id:(con 'myId-' i)});;
                  parallel-each recList as rec batch 10
                    table.insert(rec,
                      func e3? opt ?
                        enforce nullval e3 (con 'Insert ' rec.getParam('_id') ' failed.')
                        next()
                      ;)
                  finally
                    done()
                  ;
                ;)
            ;)
      ;);

    ;

test TABLE_DELETE

    vars netConn=new NET::Connection('localhost',27017)
         dbName='testdb'
         numberItems=100
         tableName='testTableDelete';

test-async : should delete from table

    makeDb(dbName)
    .open(netConn,
      func db%Db
        enforce eq$ o.getUrl() db.getUrl() 'URL mismatch'
        makeTable(tableName)
          .open(db,
            func table%Table
              vars recList=[];
              count 1 to numberItems as i push recList new Record({_id:(con 'myId-' i)});;
              parallel-each recList as rec batch 10
                table.upsert(rec,
                  func e3? opt ?
                    enforce nullval e3 (con 'Upsert ' rec.getParam('_id') ' failed.')
                    table.remove(new DeleteSpec(rec.config),
                      func e4? opt ?
                        enforce nullval e4 (con 'Delete ' rec.getParam('_id') ' failed.')
                        next()
                      )
                  ;)
              finally
                done()
              ;
            ;)
      ;);

    ;

test TABLE_INCREMENT

    vars netConn=new NET::Connection('localhost',27017)
        dbName='testdb'
        incSpec=new IncrementSpec({counter:2})
        numberItems=100
        tableName='testTableIncrement';

test-async : should increment a table value

    makeDb(dbName)
    .open(netConn,
      func db%Db
        enforce eq$ o.getUrl() db.getUrl() 'URL mismatch'
        makeTable(tableName)
          .open(db,
            func table%Table
              table.remove(new DeleteSpec(),
                func e3? ?
                  vars queryList=[];
                  enforce nullval e3 (con 'Table ' table.getName() ' delete failed.')
                  count 1 to numberItems as i
                    push queryList new QuerySpec({_id:(con 'myId-' i)});;
                  parallel-each queryList as query batch 10
                    table.insert(new Record(query.getHash()),
                      func e4? opt ?
                        enforce nullval e4 (con 'Table ' table.getName() ' insert failed.')
                        table.update(query,incSpec,
                          func e5? opt ?
                            enforce nullval e3 (con 'Update ' query.getValue('_id') ' failed.')
                            table.update(query,incSpec,
                              func e6? opt ?
                                enforce nullval e3 (con 'Update ' query.getValue('_id') ' failed.')
                                next()
                              ;)
                          ;)
                      ;)
                  finally
                    done()
                  ;
              ;)
          ;)
      ;);

    ;
npm loves you