Example #1
0
    def save(self, cname, *jsarr, **kwargs):
        """ Save/update specified `dict` documents into collection `cname`.

        Samples:
        >>> ejdb.save('foo', {'foo' : 'bar'})
        >>> ejdb.save('foo', {_id : '511c72ae7922641d00000000', 'foo' : 'bar'}, {'foo' : 'bar2'}, merge=True)
        >>> ejdb.save('foo', *[{'foo' : 'bar'}, {'foo' : 'bar2'}, ...])

        If collection with `cname` does not exists it will be created.
        Each document may have unique identifier (OID) stored in the `_id` property.
        If a saved doc does not have `_id` it will be autogenerated,
            document `dict` object will be updated with this `_id`
            and new document record will be stored.
        To identify and update doc it should contains `_id` dict property.

        :Parameters:
            - `cname` Collection name
            - `*jsarr` Variable arg list with doc to be saved
            -  merge=False (optional) If `True` docs with `_id` will be merged with those stored in db,
               otherwise updated documents will be fully replaced by new instances.
        """
        for doc in jsarr:
            if doc is not None:
                _oid = self.__ejdb.save(cname, bson.serialize_to_bytes(doc), **kwargs)
                if "_id" not in doc:
                    doc["_id"] = _oid
Example #2
0
    def save(self, cname: str, *jsarr, **kwargs):
        """ Save/update specified `dict` documents into collection `cname`.

        Samples:
        >>> ejdb.save('foo', {'foo' : 'bar'})
        >>> ejdb.save('foo', {_id : '511c72ae7922641d00000000', 'foo' : 'bar'}, {'foo' : 'bar2'}, ..., merge=True)
        >>> ejdb.save('foo', *[{'foo' : 'bar'}, {'foo' : 'bar2'}, ...])

        If collection with `cname` does not exists it will be created.
        Each document may have unique identifier (OID) stored in the `_id` property.
        If a saved doc does not have `_id` it will be autogenerated,
            document `dict` object will be updated with this `_id`
            and new document record will be stored.
        To identify and update doc it should contains `_id` dict property.

        :Parameters:
            - `cname` Collection name
            - `*jsarr` Variable arg list with doc to be saved
            -  merge=False (optional) If `True` docs with `_id` will be merged with those stored in db,
               otherwise updated documents will be fully replaced by new instances.
        """
        for doc in jsarr:
            if doc is not None:
                _oid = self.__ejdb.save(cname, bson.serialize_to_bytes(doc),
                                        **kwargs)
                if "_id" not in doc:
                    doc["_id"] = _oid
Example #3
0
def test_mongo(collection_name):
    # client, db = None, None
    # host, port = 'localhost', 27017
    # client = MongoClient(host, port)
    # db = client['groundcontrol']
    # collection = db[collection_name]
    # l = list(collection.find({}))
    # o = convert_mongo_id(l[0])

    ejdb = pyejdb.EJDB("zoo.dat", pyejdb.DEFAULT_OPEN_MODE)
    # ejdb.save("test_collection", o)
    print(ejdb.dbmeta())
    with ejdb.find("test_collection", {}) as cur:
        print("found %s parrots" % len(cur))
        for p in cur:
            print('------------------')
            d2 = parse_bytes(serialize_to_bytes(p))
            print(d2)
            d2 = convert_mongo_id(d2)
            print(d2['_id'])

            # print(json.dumps(convert_mongo_id(d2), ensure_ascii=False, indent=4))
            # print(by.decode(encoding='utf-8'))
            # for k in p:
            #     print('{0}='.format(k), p[k])
                # print("%s likes toys!" % p["name"])

    ejdb.close()
Example #4
0
    def command(self, cmd):
        """ Executes ejdb database command.

          Supported commands:

           1) Exports database collections data. See ejdbexport() method.

             "export" : {
                   "path" : string,                    //Exports database collections data
                   "cnames" : [string array]|null,     //List of collection names to export
                   "mode" : int|null                   //Values: null|`JBJSONEXPORT` See ejdb.h#ejdbexport() method
             }

             Command response:
                {
                   "log" : string,        //Diagnostic log about executing this command
                   "error" : string|null, //ejdb error message
                   "errorCode" : int|0,   //ejdb error code
                }

           2) Imports previously exported collections data into ejdb.

             "import" : {
                   "path" : string                     //The directory path in which data resides
                   "cnames" : [string array]|null,     //List of collection names to import
                   "mode" : int|null                //Values: null| JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdb.h#ejdbimport() method
              }

              Command response:
                {
                   "log" : string,        //Diagnostic log about executing this command
                   "error" : string|null, //ejdb error message
                   "errorCode" : int|0,   //ejdb error code
                }

         :Parameters:
            - `cmd`  Command object dictionary

         :Returns:
            Command response object dictionary
        """
        bret = self.__ejdb.command(bson.serialize_to_bytes(cmd))
        if bret is not None:
            return bson.parse_bytes(bret)
        return None
Example #5
0
    def command(self, cmd):
        """ Executes ejdb database command.

          Supported commands:

           1) Exports database collections data. See ejdbexport() method.

             "export" : {
                   "path" : string,                    //Exports database collections data
                   "cnames" : [string array]|null,     //List of collection names to export
                   "mode" : int|null                   //Values: null|`JBJSONEXPORT` See ejdb.h#ejdbexport() method
             }

             Command response:
                {
                   "log" : string,        //Diagnostic log about executing this command
                   "error" : string|null, //ejdb error message
                   "errorCode" : int|0,   //ejdb error code
                }

           2) Imports previously exported collections data into ejdb.

             "import" : {
                   "path" : string                     //The directory path in which data resides
                   "cnames" : [string array]|null,     //List of collection names to import
                   "mode" : int|null                //Values: null| JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdb.h#ejdbimport() method
              }

              Command response:
                {
                   "log" : string,        //Diagnostic log about executing this command
                   "error" : string|null, //ejdb error message
                   "errorCode" : int|0,   //ejdb error code
                }

         :Parameters:
            - `cmd`  Command object dictionary

         :Returns:
            Command response object dictionary
        """
        bret = self.__ejdb.command(bson.serialize_to_bytes(cmd))
        if bret is not None:
            return bson.parse_bytes(bret)
        return None
Example #6
0
    def find(self, cname, qobj=None, *args, **kwargs):
        """ Execute query on collection.

        Sample:
        >>> # Fetch all elements from collection
        >>> ejdb.find("mycoll")
        >>> # Query document with 'foo==bar' condition, include in resulting doc 'foo' and '_id' fields only
        >>> ejdb.find("mycoll", {'foo' : 'bar'}, hints={$fields : {'foo' : 1, '_id' : 1}});

        General format:
            find(<collection name>, <query object>, <OR joined query objects>,..., hints=<Query Hints>)

        :Parameters:
           - `cname` Collection name
           - `qobj` Main query object
           - *args OR joined query object
           - hints={} (optional) Query hints. See explanations below.
           - log=StringIO (optional) StringIO buffer for ejdb query log (debugging mode)

        :Returns:
            Resultset cursor :class:`EJDBCursorWrapper`

        EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
        - Supported queries:
           - Simple matching of String OR Number OR Array value:
               -   {'fpath' : 'val', ...}
           - $not Negate operation.
               -   {'fpath' : {'$not' : val}} //Field not equal to val
               -   {'fpath' : {'$not' : {'$begin' : prefix}}} //Field not begins with val
           - $begin String starts with prefix
               -   {'fpath' : {'$begin' : prefix}}
           - $gt, $gte (>, >=) and $lt, $lte for number types:
               -   {'fpath' : {'$gt' : number}, ...}
           - $bt Between for number types:
               -   {'fpath' : {'$bt' : [num1, num2]}}
           - $in String OR Number OR Array val matches to value in specified array:
               -   {'fpath' : {'$in' : [val1, val2, val3]}}
           - $nin - Not IN
           - $strand String tokens OR String array val matches all tokens in specified array:
               -   {'fpath' : {'$strand' : [val1, val2, val3]}}
           - $stror String tokens OR String array val matches any token in specified array:
               -   {'fpath' : {'$stror' : [val1, val2, val3]}}
           - $exists Field existence matching:
               -   {'fpath' : {'$exists' : true|false}}
           - $icase Case insensitive string matching:
               -    {'fpath' : {'$icase' : 'val1'}} //icase matching
               icase matching with '$in' operation:
               -    {'name' : {'$icase' : {'$in' : ['tHéâtre - театр', 'heLLo WorlD']}}}
               For case insensitive matching you can create special type of string index.
           - $elemMatch The $elemMatch operator matches more than one component within an array element.
               -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
               Restriction: only one $elemMatch allowed in context of one array field.
           - $and, $or joining:
               -   {..., $and : [subq1, subq2, ...] }
               -   {..., $or  : [subq1, subq2, ...] }
              Example: {z : 33, $and : [ {$or : [{a : 1}, {b : 2}]}, {$or : [{c : 5}, {d : 7}]} ] }

        - Queries can be used to update records:

           - $set Field set operation.
               - {.., '$set' : {'field1' : val1, 'fieldN' : valN}}
           - $upsert Atomic upsert. If matching records are found it will be '$set' operation,
                     otherwise new record will be inserted with fields specified by argment object.
               - {.., '$upsert' : {'field1' : val1, 'fieldN' : valN}}
           - $inc Increment operation. Only number types are supported.
               - {.., '$inc' : {'field1' : number, ...,  'field1' : number}
           - $dropall In-place record removal operation.
               - {.., '$dropall' : True}
           - $addToSet Atomically adds value to the array only if its not in the array already.
                       If containing array is missing it will be created.
               - {.., '$addToSet' : {'fpath' : val1, 'fpathN' : valN, ...}}
           - $addToSetAll Batch version if $addToSet
               - {.., '$addToSetAll' : {'fpath' : [array of values to add], ...}}
           - $pull Atomically removes all occurrences of value from field, if field is an array.
               - {.., '$pull' : {'fpath' : val1, 'fpathN' : valN, ...}}
           - $pullAll Batch version of $pull
               - {.., '$pullAll' : {'fpath' : [array of values to remove], ...}}

        - Collection joins supported in the following form:
           - {..., $do : {fpath : {$join : 'collectionname'}} }
            Where 'fpath' value points to object's OIDs from 'collectionname'. Its value
            can be OID, string representation of OID or array of this pointers.

        .. NOTE:: It is better to execute update queries with `$onlycount=true` hint flag
               or use the special `update()` method to avoid unnecessarily data fetching.

        .. NOTE:: Negate operations: $not and $nin not using indexes
                 so they can be slow in comparison to other matching operations.

        .. NOTE:: Only one index can be used in search query operation.


        QUERY HINTS (specified by `hints=` argument):
           - $max Maximum number in the result set
           - $skip Number of skipped results in the result set
           - $orderby Sorting order of query fields.
           - $onlycount true|false If `true` only count of matching records will be returned
                                   without placing records in result set.
           - $fields Set subset of fetched fields.
               If field presented in $orderby clause it will be forced to include in resulting records.
               Example:
               hints:    {
                   "$orderby" : [ //ORDER BY field1 ASC, field2 DESC
                       ("field1", 1),
                       ("field2", -1)
                   ],
                   "$fields" : { //SELECT ONLY {_id, field1, field2}
                       "field1" : 1,
                       "field2" : 1
                   }
               }

        """
        if not qobj: qobj = {}
        qobj = bson.serialize_to_bytes(qobj)
        hints = bson.serialize_to_bytes(self.__preprocessQHints(kwargs.get("hints", {})))
        orarr = [bson.serialize_to_bytes(x) for x in args]
        qflags = kwargs.get("qflags", 0)
        log = kwargs.get("log")
        log = log if isinstance(log, StringIO) or isinstance(log, BytesIO) else None
        cursor = self.__ejdb.find(cname, qobj, orarr, hints, qflags, log)
        return cursor if isinstance(cursor, numbers.Number) else EJDBCursorWrapper(cursor)
Example #7
0
    def find(self, cname: str, qobj: optional(dict) = None, *args, **kwargs):
        """ Execute query on collection.

        Sample:
        >>> # Fetch all elements from collection
        >>> ejdb.find("mycoll")
        >>> # Query document with 'foo==bar' condition, include in resulting doc 'foo' and '_id' fields only
        >>> ejdb.find("mycoll", {'foo' : 'bar'}, hints={$fields : {'foo' : 1, '_id' : 1}});

        General format:
            find(<collection name>, <query object>, <OR joined query objects>,..., hints=<Query Hints>)

        :Parameters:
           - `cname` Collection name
           - `qobj` Main query object
           - *args OR joined query object
           - hints={} (optional) Query hints. See explanations below.
           - log=StringIO (optional) StringIO buffer for ejdb query log (debugging mode)

        :Returns:
            Resultset cursor :class:`EJDBCursorWrapper`

        EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
        - Supported queries:
           - Simple matching of String OR Number OR Array value:
               -   {'fpath' : 'val', ...}
           - $not Negate operation.
               -   {'fpath' : {'$not' : val}} //Field not equal to val
               -   {'fpath' : {'$not' : {'$begin' : prefix}}} //Field not begins with val
           - $begin String starts with prefix
               -   {'fpath' : {'$begin' : prefix}}
           - $gt, $gte (>, >=) and $lt, $lte for number types:
               -   {'fpath' : {'$gt' : number}, ...}
           - $bt Between for number types:
               -   {'fpath' : {'$bt' : [num1, num2]}}
           - $in String OR Number OR Array val matches to value in specified array:
               -   {'fpath' : {'$in' : [val1, val2, val3]}}
           - $nin - Not IN
           - $strand String tokens OR String array val matches all tokens in specified array:
               -   {'fpath' : {'$strand' : [val1, val2, val3]}}
           - $stror String tokens OR String array val matches any token in specified array:
               -   {'fpath' : {'$stror' : [val1, val2, val3]}}
           - $exists Field existence matching:
               -   {'fpath' : {'$exists' : true|false}}
           - $icase Case insensitive string matching:
               -    {'fpath' : {'$icase' : 'val1'}} //icase matching
               icase matching with '$in' operation:
               -    {'name' : {'$icase' : {'$in' : ['tHéâtre - театр', 'heLLo WorlD']}}}
               For case insensitive matching you can create special type of string index.
           - $elemMatch The $elemMatch operator matches more than one component within an array element.
               -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
               Restriction: only one $elemMatch allowed in context of one array field.

        - Queries can be used to update records:

           - $set Field set operation.
               - {.., '$set' : {'field1' : val1, 'fieldN' : valN}}
           - $upsert Atomic upsert. If matching records are found it will be '$set' operation,
                     otherwise new record will be inserted with fields specified by argment object.
               - {.., '$upsert' : {'field1' : val1, 'fieldN' : valN}}
           - $inc Increment operation. Only number types are supported.
               - {.., '$inc' : {'field1' : number, ...,  'field1' : number}
           - $dropall In-place record removal operation.
               - {.., '$dropall' : true}
           - $addToSet Atomically adds value to the array only if its not in the array already.
                       If containing array is missing it will be created.
               - {.., '$addToSet' : {'fpath' : val1, 'fpathN' : valN, ...}}
           - $addToSetAll Batch version if $addToSet
               - {.., '$addToSetAll' : {'fpath' : [array of values to add], ...}}
           - $pull Atomically removes all occurrences of value from field, if field is an array.
               - {.., '$pull' : {'fpath' : val1, 'fpathN' : valN, ...}}
           - $pullAll Batch version of $pull
               - {.., '$pullAll' : {'fpath' : [array of values to remove], ...}}

        - Collection joins supported in the following form:
           - {..., $do : {fpath : {$join : 'collectionname'}} }
            Where 'fpath' value points to object's OIDs from 'collectionname'. Its value
            can be OID, string representation of OID or array of this pointers.

        .. NOTE:: It is better to execute update queries with `$onlycount=true` hint flag
               or use the special `update()` method to avoid unnecessarily data fetching.

        .. NOTE:: Negate operations: $not and $nin not using indexes
                 so they can be slow in comparison to other matching operations.

        .. NOTE:: Only one index can be used in search query operation.


        QUERY HINTS (specified by `hints=` argument):
           - $max Maximum number in the result set
           - $skip Number of skipped results in the result set
           - $orderby Sorting order of query fields.
           - $onlycount true|false If `true` only count of matching records will be returned
                                   without placing records in result set.
           - $fields Set subset of fetched fields.
               If field presented in $orderby clause it will be forced to include in resulting records.
               Example:
               hints:    {
                   "$orderby" : [ //ORDER BY field1 ASC, field2 DESC
                       ("field1", 1),
                       ("field2", -1)
                   ],
                   "$fields" : { //SELECT ONLY {_id, field1, field2}
                       "field1" : 1,
                       "field2" : 1
                   }
               }

        """
        if not qobj: qobj = {}
        qobj = bson.serialize_to_bytes(qobj)
        hints = bson.serialize_to_bytes(
            self.__preprocessQHints(kwargs.get("hints", {})))
        orarr = [bson.serialize_to_bytes(x) for x in args]
        qflags = kwargs.get("qflags", 0)
        log = kwargs.get("log")
        log = log if isinstance(log, strio) else None
        cursor = self.__ejdb.find(cname, qobj, orarr, hints, qflags, log)
        return cursor if isinstance(
            cursor, numbers.Number) else EJDBCursorWrapper(cursor)