Exemple #1
0
    def _raba__init__(self, **fieldsSet):

        self.sqlSave = {}
        self.sqlSaveQMarks = {}
        self.listsToSave = {}
        self.rabaLists = []

        if self.__class__ is Raba:
            raise TypeError(
                'Raba class should never be instanciated, use inheritance')

        self._runtimeId = (
            self.__class__.__name__, random.random()
        )  #this is used only during runtime ex, to avoid circular calls
        self._rabaClass = self.__class__

        self.connection = RabaConnection(self._rabaClass._raba_namespace)
        self.rabaConfiguration = RabaConfiguration(
            self._rabaClass._raba_namespace)

        self._saved = False  #True if present in the database

        if 'initDbLine' in fieldsSet and 'initDbLine' != None:
            self._initDbLine(fieldsSet['initDbLine'])
            self._saved = True

        if self.raba_id == None:
            self.raba_id = self.connection.getNextRabaId(self)
Exemple #2
0
    def __init__(self, **kwargs):
        self._runtimeId = (
            self.__class__.__name__, random.random()
        )  #this is using only during runtime ex, to avoid circular calls
        self.anchorObj = kwargs['anchorObj']
        self.relationName = kwargs['relationName']
        self.length = kwargs['length']
        self._raba_namespace = self.anchorObj._raba_namespace

        self.connection = RabaConnection(self._raba_namespace)

        self.tableName = self.connection.makeRabaListTableName(
            self.anchorObj._rabaClass.__name__, self.relationName)
Exemple #3
0
 def getIndexes(cls):
     "returns a list of the indexes of a class"
     con = RabaConnection(cls._raba_namespace)
     idxs = []
     for idx in con.getIndexes(rabaOnly=True):
         if idx[2] == cls.__name__:
             idxs.append(idx)
         else:
             for k in cls.columns:
                 if RabaFields.isRabaListField(getattr(
                         cls, k)) and idx[2] == con.makeRabaListTableName(
                             cls.__name__, k):
                     idxs.append(idx)
     return idxs
Exemple #4
0
    def _initDbLine(self, dbLine):
        self.raba_id = dbLine[self.__class__.columns['raba_id']]
        self.json = dbLine[self.__class__.columns['json']]

        lists = []
        for kk, i in self.columns.iteritems():
            k = self.columnsToLowerCase[kk.lower()]
            elmt = getattr(self._rabaClass, k)
            if RabaFields.isPrimitiveField(elmt):
                try:
                    self.__setattr__(k, cPickle.loads(str(dbLine[i])))
                except:
                    self.__setattr__(k, dbLine[i])

            elif RabaFields.isRabaObjectField(elmt):
                if dbLine[i] != None:
                    val = json.loads(dbLine[i])
                    objClass = RabaConnection(val["raba_namespace"]).getClass(
                        val["className"])
                    self.__setattr__(k, RabaPupa(objClass, val["raba_id"]))
            elif RabaFields.isRabaListField(elmt):
                if dbLine[i] == None:
                    lists.append((k, 0))
                else:
                    lists.append((k, int(dbLine[i])))
            else:
                raise ValueError(
                    "Unable to set field %s to %s in Raba object %s" %
                    (k, dbLine[i], self._rabaClass.__name__))

        #~ self.rabaLists = []
        for k, leng in lists:
            rlp = RabaListPupa(anchorObj=self, relationName=k, length=leng)
            self.__setattr__(k, rlp)
            self.rabaLists.append(rlp)
Exemple #5
0
    def dropIndex(cls, fields):
        "removes an index created with ensureIndex "
        con = RabaConnection(cls._raba_namespace)
        rlf, ff = cls._parseIndex(fields)

        for name in rlf:
            con.dropIndex(name, 'anchor_raba_id')

        con.dropIndex(cls.__name__, ff)
        con.commit()
Exemple #6
0
    def _parseIndex(cls, fields):
        con = RabaConnection(cls._raba_namespace)
        ff = []
        rlf = []
        tmpf = []
        if type(fields) is types.StringType:
            tmpf.append(fields)
        else:
            tmpf = fields

        for field in tmpf:
            if RabaFields.isRabaListField(getattr(cls, field)):
                lname = con.makeRabaListTableName(cls.__name__, field)
                rlf.append(lname, )
            else:
                ff.append(field)

        return rlf, ff
Exemple #7
0
    def develop(self):
        def getAttr(name):
            return object.__getattribute__(self, name)

        def setAttr(name, value):
            object.__setattr__(self, name, value)

        rabaClass = getAttr('_rabaClass')
        uniqueId = getAttr('raba_id')
        connection = RabaConnection(getAttr('_raba_namespace'))
        dbLine = connection.getRabaObjectInfos(
            getAttr('_rabaClass').__name__, {
                'raba_id': uniqueId
            }).fetchone()
        setAttr('__class__', rabaClass)
        purge = getAttr('__dict__').keys()
        for k in purge:
            delattr(self, k)

        self._rabaClass = rabaClass
        self.connection = connection
        rabaClass._raba__init__(self, initDbLine=dbLine)
        rabaClass.__init__(self)
Exemple #8
0
    def ensureIndex(cls, fields, where='', whereValues=[]):
        """Add an index for field, indexes take place and slow down saves and deletes but they speed up a lot everything else. If you are going to do a lot of saves/deletes drop the indexes first re-add them afterwards
		Fields can be a list of fields for Multi-Column Indices or simply the name of a single field. But as RabaList are basicaly in separate tables you cannot create a multicolumn indice on them. A single index will
		be create for the RabaList alone"""
        con = RabaConnection(cls._raba_namespace)
        rlf, ff = cls._parseIndex(fields)
        ww = []
        for i in range(len(whereValues)):
            if isRabaObject(whereValues[i]):
                ww.append(whereValues[i].getJsonEncoding())

        for name in rlf:
            con.createIndex(name, 'anchor_raba_id')

        if len(ff) > 0:
            con.createIndex(cls.__name__, ff, where=where, whereValues=ww)
        con.commit()
Exemple #9
0
    def __call__(clsObj, *args, **kwargs):
        anchorObj = kwargs['anchorObj']
        relationName = kwargs['relationName']
        length = kwargs['length']

        try:
            return _getRabaListInstance(anchorObj, relationName)
        except KeyError:
            pass

        connection = RabaConnection(anchorObj._raba_namespace)

        obj = super(_RabaListPupaSingleton_Metaclass,
                    clsObj).__call__(*args,
                                     anchorObj=anchorObj,
                                     relationName=relationName,
                                     length=length)

        _registerRabaListInstance(obj, anchorObj, relationName)

        return obj
Exemple #10
0
    def __init__(self, *listElements, **listArguments):
        """To avoid the check of all elements of listElements during initialisation pass : noInitCheck = True as argument
		It is also possible to define both the anchor object and the namespace durint initalisation using argument keywords: anchorObj and namespace. But only do it
		if you really now what you are doing."""
        self._runtimeId = (
            self.__class__.__name__, random.random()
        )  #this is used only during runtime ex, to avoid circular calls

        self.raba_id = None
        self.relationName = None
        self.tableName = None
        self.anchorObj = None

        self._raba_namespace = None
        self.connection = None
        self.rabaConfiguration = None
        self._saved = False
        self._mutated = True

        if len(listElements) > 0:
            self.data = list(listElements[0])
        else:
            self.data = []

        if 'initFromPupa' in listArguments:
            pupaInit = listArguments['initFromPupa']
            self.anchorObj = pupaInit['anchorObj']
            self.relationName = pupaInit['relationName']
            self._raba_namespace = self.anchorObj._raba_namespace
            #self.raba_id = pupaInit['raba_id']
            self.tableName = pupaInit['tableName']
            length = pupaInit['length']

            self._setNamespaceConAndConf(self.anchorObj._raba_namespace)
            self.connection.createRabaListTable(self.tableName)
            #if self.raba_id == None :
            #	self.raba_id, self.tableName = self.connection.registerRabalist(self.anchorObj._rabaClass.__name__, self.anchorObj.raba_id, self.relationName)

            if length > 0:
                sql, values = 'SELECT * FROM %s WHERE anchor_raba_id = ?' % self.tableName, (
                    self.anchorObj.raba_id, )
                cur = self.connection.execute(sql, values)
                for aidi in cur:
                    self._saved = True
                    value = aidi[2]
                    typ = aidi[3]
                    className = aidi[4]
                    raba_id = aidi[5]
                    raba_namespace = aidi[6]
                    if typ == RabaFields.RABA_FIELD_TYPE_IS_PRIMITIVE:
                        self.append(value)
                    elif typ == RabaFields.RABA_FIELD_TYPE_IS_RABA_LIST:
                        raise FutureWarning(
                            'RabaList in RabaList not supported')
                    elif typ == RabaFields.RABA_FIELD_TYPE_IS_RABA_OBJECT:
                        classObj = RabaConnection(raba_namespace).getClass(
                            className)
                        self.append(RabaPupa(classObj, raba_id))
                    else:
                        raise ValueError("Unknown type: %s in rabalist %s" %
                                         (typ, self))
Exemple #11
0
class RabaListPupa(MutableSequence):

    _isRabaList = True
    __metaclass__ = _RabaListPupaSingleton_Metaclass

    def __init__(self, **kwargs):
        self._runtimeId = (
            self.__class__.__name__, random.random()
        )  #this is using only during runtime ex, to avoid circular calls
        self.anchorObj = kwargs['anchorObj']
        self.relationName = kwargs['relationName']
        self.length = kwargs['length']
        self._raba_namespace = self.anchorObj._raba_namespace

        self.connection = RabaConnection(self._raba_namespace)

        self.tableName = self.connection.makeRabaListTableName(
            self.anchorObj._rabaClass.__name__, self.relationName)

    def develop(self):
        MutableSequence.__setattr__(self, '__class__', RabaList)

        initFromPupa = {}

        initFromPupa['relationName'] = MutableSequence.__getattribute__(
            self, 'relationName')
        initFromPupa['anchorObj'] = MutableSequence.__getattribute__(
            self, 'anchorObj')
        initFromPupa['_raba_namespace'] = MutableSequence.__getattribute__(
            self, '_raba_namespace')
        initFromPupa['tableName'] = MutableSequence.__getattribute__(
            self, 'tableName')
        initFromPupa['length'] = MutableSequence.__getattribute__(
            self, 'length')
        #initFromPupa['raba_id'] = MutableSequence.__getattribute__(self, 'raba_id')

        purge = MutableSequence.__getattribute__(self, '__dict__').keys()
        for k in purge:
            delattr(self, k)

        RabaList.__init__(self, initFromPupa=initFromPupa)
        RabaList._attachToObject(self, initFromPupa['anchorObj'],
                                 initFromPupa['relationName'])

    def __getitem__(self, i):
        self.develop()
        return self[i]

    def __delitem__(self, i):
        self.develop()
        self.__delitem__(i)

    def __setitem__(self, k, v):
        self.develop()
        self.__setitem__(k, v)

    def insert(self, k, i, v):
        self.develop()
        self.insert(i, v)

    def append(self, k):
        self.develop()
        self.append(k)

    def _attachToObject(self, anchorObj, relationName):
        "dummy fct for compatibility reasons, a RabaListPupa is attached by default"
        #MutableSequence.__getattribute__(self, "develop")()
        self.develop()
        self._attachToObject(anchorObj, relationName)

    def _save(self, *args, **kwargs):
        "dummy fct for compatibility reasons, a RabaListPupa represents an unmodified list so there's nothing to save"
        self.develop()
        RabaList._save(self)

    def __getattr__(self, name):
        self.develop()
        return MutableSequence.__getattribute__(self, name)

    def __repr__(self):
        return "[%s length: %d, relationName: %s, anchorObj: %s, raba_id: %s]" % (
            self._runtimeId, self.length, self.relationName, self.anchorObj,
            self.raba_id)

    def __len__(self):
        if self.length < 0:
            self.develop()
        return self.length
Exemple #12
0
 def flushIndexes(cls):
     "drops all indexes for a class"
     con = RabaConnection(cls._raba_namespace)
     for idx in cls.getIndexes():
         con.dropIndexByName(idx[1])
Exemple #13
0
class Raba(object):
    "All raba object inherit from this class"
    __metaclass__ = _RabaSingleton_MetaClass
    raba_id = RabaFields.Primitive()
    json = RabaFields.Primitive()
    _raba_abstract = True

    def __init__(self, *a, **b):
        pass

    def unreference(self):
        "explicit deletes the object from the singleton reference dictionary. This is mandatory to be able to delete the object using del(). Also, any attempt to reload an object with the same parameters will result un a new instance being created"
        try:
            del (self.__class__._instances[makeRabaObjectSingletonKey(
                self.__class__.__name__, self._raba_namespace, self.raba_id)])
        except KeyError:
            pass

    def _initDbLine(self, dbLine):
        self.raba_id = dbLine[self.__class__.columns['raba_id']]
        self.json = dbLine[self.__class__.columns['json']]

        lists = []
        for kk, i in self.columns.iteritems():
            k = self.columnsToLowerCase[kk.lower()]
            elmt = getattr(self._rabaClass, k)
            if RabaFields.isPrimitiveField(elmt):
                try:
                    self.__setattr__(k, cPickle.loads(str(dbLine[i])))
                except:
                    self.__setattr__(k, dbLine[i])

            elif RabaFields.isRabaObjectField(elmt):
                if dbLine[i] != None:
                    val = json.loads(dbLine[i])
                    objClass = RabaConnection(val["raba_namespace"]).getClass(
                        val["className"])
                    self.__setattr__(k, RabaPupa(objClass, val["raba_id"]))
            elif RabaFields.isRabaListField(elmt):
                if dbLine[i] == None:
                    lists.append((k, 0))
                else:
                    lists.append((k, int(dbLine[i])))
            else:
                raise ValueError(
                    "Unable to set field %s to %s in Raba object %s" %
                    (k, dbLine[i], self._rabaClass.__name__))

        #~ self.rabaLists = []
        for k, leng in lists:
            rlp = RabaListPupa(anchorObj=self, relationName=k, length=leng)
            self.__setattr__(k, rlp)
            self.rabaLists.append(rlp)

    def _raba__init__(self, **fieldsSet):

        self.sqlSave = {}
        self.sqlSaveQMarks = {}
        self.listsToSave = {}
        self.rabaLists = []

        if self.__class__ is Raba:
            raise TypeError(
                'Raba class should never be instanciated, use inheritance')

        self._runtimeId = (
            self.__class__.__name__, random.random()
        )  #this is used only during runtime ex, to avoid circular calls
        self._rabaClass = self.__class__

        self.connection = RabaConnection(self._rabaClass._raba_namespace)
        self.rabaConfiguration = RabaConfiguration(
            self._rabaClass._raba_namespace)

        self._saved = False  #True if present in the database

        if 'initDbLine' in fieldsSet and 'initDbLine' != None:
            self._initDbLine(fieldsSet['initDbLine'])
            self._saved = True

        if self.raba_id == None:
            self.raba_id = self.connection.getNextRabaId(self)

    def pupa(self):
        """returns a pupa version of self"""
        return RabaPupa(self.__class__, self.raba_id)

    def develop(self):
        "Dummy fct, so when you call develop on a full developed object you don't get nasty exceptions"
        pass

    @classmethod
    def _parseIndex(cls, fields):
        con = RabaConnection(cls._raba_namespace)
        ff = []
        rlf = []
        tmpf = []
        if type(fields) is types.StringType:
            tmpf.append(fields)
        else:
            tmpf = fields

        for field in tmpf:
            if RabaFields.isRabaListField(getattr(cls, field)):
                lname = con.makeRabaListTableName(cls.__name__, field)
                rlf.append(lname, )
            else:
                ff.append(field)

        return rlf, ff

    @classmethod
    def ensureIndex(cls, fields, where='', whereValues=[]):
        """Add an index for field, indexes take place and slow down saves and deletes but they speed up a lot everything else. If you are going to do a lot of saves/deletes drop the indexes first re-add them afterwards
		Fields can be a list of fields for Multi-Column Indices or simply the name of a single field. But as RabaList are basicaly in separate tables you cannot create a multicolumn indice on them. A single index will
		be create for the RabaList alone"""
        con = RabaConnection(cls._raba_namespace)
        rlf, ff = cls._parseIndex(fields)
        ww = []
        for i in range(len(whereValues)):
            if isRabaObject(whereValues[i]):
                ww.append(whereValues[i].getJsonEncoding())

        for name in rlf:
            con.createIndex(name, 'anchor_raba_id')

        if len(ff) > 0:
            con.createIndex(cls.__name__, ff, where=where, whereValues=ww)
        con.commit()

    @classmethod
    def dropIndex(cls, fields):
        "removes an index created with ensureIndex "
        con = RabaConnection(cls._raba_namespace)
        rlf, ff = cls._parseIndex(fields)

        for name in rlf:
            con.dropIndex(name, 'anchor_raba_id')

        con.dropIndex(cls.__name__, ff)
        con.commit()

    @classmethod
    def getIndexes(cls):
        "returns a list of the indexes of a class"
        con = RabaConnection(cls._raba_namespace)
        idxs = []
        for idx in con.getIndexes(rabaOnly=True):
            if idx[2] == cls.__name__:
                idxs.append(idx)
            else:
                for k in cls.columns:
                    if RabaFields.isRabaListField(getattr(
                            cls, k)) and idx[2] == con.makeRabaListTableName(
                                cls.__name__, k):
                        idxs.append(idx)
        return idxs

    @classmethod
    def flushIndexes(cls):
        "drops all indexes for a class"
        con = RabaConnection(cls._raba_namespace)
        for idx in cls.getIndexes():
            con.dropIndexByName(idx[1])

    def mutated(self):
        'returns True if the object has changed since the last save'
        return len(self.sqlSave) > 0 or len(self.listsToSave) > 0

    def save(self):
        if self.mutated():
            if not self.raba_id:
                raise ValueError(
                    "Field raba_id of self has the not int value %s therefore i cannot save the object, sorry"
                    % (self, self.raba_id))

            for k, v in self.listsToSave.iteritems():
                v._save()
                self.sqlSave[k] = len(v)
                if not self._saved:  #this dict is only for optimisation purpose for generating the insert sql
                    self.sqlSaveQMarks[k] = '?'

            self.sqlSave['json'] = self.getJsonEncoding()
            if not self._saved:  #this dict is only for optimisation purpose for generating the insert sql
                self.sqlSaveQMarks['json'] = '?'

            if not self._saved:
                values = self.sqlSave.values()
                sql = 'INSERT INTO %s (%s) VALUES (%s)' % (
                    self.__class__.__name__, ', '.join(self.sqlSave.keys()),
                    ', '.join(self.sqlSaveQMarks.values()))
            else:
                values = self.sqlSave.values()
                sql = 'UPDATE %s SET %s = ? WHERE raba_id = ?' % (
                    self.__class__.__name__, ' = ?, '.join(
                        self.sqlSave.keys()))
                values.append(self.raba_id)

            self.connection.execute(sql, values)
            self.connection.commit()
            self._saved = True
            self.sqlSave = {}
            self.sqlSaveQMarks = {}
            self.listsToSave = {}

    def delete(self):
        if self._saved:
            for c in self.columnsToLowerCase.itervalues():
                if isRabaList(getattr(self, c)):
                    getattr(self, c).empty()
            self.connection.delete(table=self.__class__.__name__,
                                   where='raba_id = ?',
                                   values=(self.raba_id, ))
            self.connection.commit()

    def copy(self):
        v = copy.copy(self)
        v.raba_id = None
        return v

    def getDctDescription(self):
        "returns a dict describing the object"
        return {
            'type': RabaFields.RABA_FIELD_TYPE_IS_RABA_OBJECT,
            'className': self._rabaClass.__name__,
            'raba_id': self.raba_id,
            'raba_namespace': self._raba_namespace
        }

    def getJsonEncoding(self):
        "returns a json encoding of self.getDctDescription()"
        return json.dumps(self.getDctDescription())

    def set(self, **args):
        "set multiple values quickly, ex : name = woopy"
        for k, v in args.items():
            setattr(self, k, v)

    def __setattr__(self, k, v):
        "This also keeps track of wich fields have been updated."
        vv = v
        if hasattr(self.__class__, k) and RabaFields.isField(
                getattr(self.__class__, k)):
            vSQL = None
            if not RabaFields.isRabaListField(getattr(self.__class__, k)):
                classType = getattr(self.__class__, k)
                if not classType.check(vv):
                    raise ValueError(
                        "Unable to set '%s' to value '%s'. Constrain function violation"
                        % (k, vv))
                if isRabaObject(vv):
                    vSQL = vv.getJsonEncoding()
                elif isPythonPrimitive(vv):
                    vSQL = vv
                else:
                    vSQL = buffer(cPickle.dumps(vv))

                self.sqlSave[k] = vSQL

                if not self._saved:  #this dict is only for optimisation purpose for generating the insert sql
                    self.sqlSaveQMarks[k] = '?'
            else:
                if not isRabaList(vv) and not isRabaListPupa(vv):
                    try:
                        vv = RabaList(v)
                    except:
                        raise ValueError(
                            "Unable to set '%s' to value '%s'. Value is not a valid RabaList"
                            % (k, vv))

                currList = object.__getattribute__(self, k)
                if not RabaFields.isRabaListField(
                        currList) and vv is not currList and len(currList) > 0:
                    currList.erase()
                    self.connection.unregisterRabalist(
                        anchor_class_name=self.__class__.__name__,
                        anchor_raba_id=self.raba_id,
                        relation_name=k)

                vv._attachToObject(self, k)
                self.listsToSave[
                    k] = vv  #self.sqlSave[k] and self.sqlSaveQMarks[k] are updated in self.save() for lists

        object.__setattr__(self, k, vv)

    def __getattribute__(self, k):
        try:
            elmt = object.__getattribute__(self, k)
            if RabaFields.isRabaListField(elmt):  #if empty
                elmt = RabaListPupa(anchorObj=self, relationName=k, length=-1)
                object.__setattr__(self, k, elmt)
            elif RabaFields.isField(elmt):
                elmt = elmt.default

            return elmt
        except AttributeError:
            return self.__getattr__(k)

    def __getattr__(self, k):
        raise AttributeError('%s has no attribute "%s"' % (repr(self), k))

    def __getitem__(self, k):
        return self.__getattribute__(k)

    def __setitem__(self, k, v):
        self.__setattr__(k, v)

    def __repr__(self):
        return "<Raba obj: %s, raba_id: %s>" % (self._runtimeId, self.raba_id)

    @classmethod
    def getFields(cls):
        """returns a set of the available fields. In order to be able ti securely loop of the fields, "raba_id" and "json" are not included in the set"""
        s = set(cls.columns.keys())
        s.remove('json')
        s.remove('raba_id')
        return s

    @classmethod
    def help(cls):
        "returns a string of lisinting available fields"
        return 'Available fields for %s: %s' % (cls.__name__, ', '.join(
            cls.getFields()))
Exemple #14
0
    def __call__(cls, *args, **fieldsDct):
        if cls == Raba:
            return super(_RabaSingleton_MetaClass, cls).__call__(**fieldsDct)

        if 'raba_id' in fieldsDct:
            try:
                return _getRabaObjectInstance(cls, cls._raba_namespace,
                                              raba_id)
            except KeyError:
                pass
        else:
            key = None

        params = copy.copy(fieldsDct)
        nonRabaParams = {}
        for p, v in params.items():
            if p in cls.columns:
                if isRabaObject(v):
                    params[p] = v.getJsonEncoding()
            else:
                nonRabaParams[p] = v
                del (params[p])

        connection = RabaConnection(cls._raba_namespace)
        ret = connection.getRabaObjectInfos(cls.__name__, params)

        if ret != None:
            dbLine = ret.fetchone()
        else:
            dbLine = None

        if dbLine != None:
            if ret.fetchone() != None:
                raise ValueError(
                    "More than one object fit the arguments you've provided to the constructor"
                )

            raba_id = dbLine[0]
            try:
                return _getRabaObjectInstance(cls, cls._raba_namespace,
                                              raba_id)
            except KeyError:
                pass

            obj = Raba.__new__(cls, *args, **nonRabaParams)
            obj._raba__init__(initDbLine=dbLine)
            obj.__init__(*args, **nonRabaParams)

            if not hasattr(cls, '_raba_not_a_singleton') or not getattr(
                    cls, '_raba_not_a_singleton'):
                _registerRabaObjectInstance(obj)

        elif len(params) > 0:  # params provided but no result
            raise KeyError(
                "Couldn't find any object that fit the arguments you've provided to the constructor"
            )
        else:
            obj = type.__call__(cls, *args, **fieldsDct)
            obj._raba__init__(**fieldsDct)

        return obj
Exemple #15
0
    def __new__(cls, name, bases, dct):
        if '_raba_abstract' not in dct or not dct['_raba_abstract']:

            def getFields_rec(name, sqlFields, columns, columnsToLowerCase,
                              dct, bases):
                i = 0
                if name != "Raba":
                    for base in bases:
                        i += getFields_rec(base.__name__, sqlFields, columns,
                                           columnsToLowerCase, base.__dict__,
                                           base.__bases__)

                for k, v in dct.iteritems():
                    if RabaFields.isField(v):
                        sk = str(k)
                        if k.lower() != 'raba_id' and k.lower() != 'json':
                            sqlFields.append(sk)

                        columns[sk] = i
                        columnsToLowerCase[sk.lower()] = sk
                        i += 1
                return i

            sqlFields = []
            columns = {}
            columnsToLowerCase = {}
            getFields_rec(name, sqlFields, columns, columnsToLowerCase, dct,
                          bases)
            columns["raba_id"] = 0
            columns['json'] = 1

            try:
                con = RabaConnection(dct['_raba_namespace'])
            except KeyError:
                raise ValueError(
                    "The class %s has no defined namespace, please add a valid '_raba_namespace' to class attributes"
                    % name)

            uniqueStr = ''
            if '_raba_uniques' in dct:
                for c in dct['_raba_uniques']:
                    if type(c) is types.StringType:
                        uniqueStr += 'UNIQUE (%s) ON CONFLICT REPLACE, ' % c
                    elif len(c) == 1:
                        uniqueStr += 'UNIQUE (%s) ON CONFLICT REPLACE, ' % c[0]
                    else:
                        uniqueStr += 'UNIQUE %s ON CONFLICT REPLACE, ' % str(c)
            uniqueStr = uniqueStr[:-2]

            if not con.tableExits(name):
                idJsonStr = 'raba_id INTEGER PRIMARY KEY, json '
                if len(sqlFields) > 0:
                    if len(uniqueStr) > 0:
                        con.createTable(
                            name, '%s, %s, %s' %
                            (idJsonStr, ', '.join(list(sqlFields)), uniqueStr))
                    else:
                        con.createTable(
                            name,
                            '%s, %s' % (idJsonStr, ', '.join(list(sqlFields))))
                else:
                    con.createTable(name, '%s' % idJsonStr)

                sqlCons = 'INSERT INTO raba_tables_constraints (table_name, constraints) VALUES (?, ?)'
                con.execute(sqlCons, (name, uniqueStr))
            else:
                sql = 'SELECT constraints FROM raba_tables_constraints WHERE table_name = ?'

                cur = con.execute(sql, (name, ))
                res = cur.fetchone()

                if res != None and res[0] != '' and res[0] != uniqueStr:
                    sys.stderr.write(
                        'Warning: The unique contraints have changed from:\n\t%s\n\nto:\n\t%s.\n-Unique constraints modification is not supported yet-\n'
                        % (res[0], uniqueStr))
                    #raise FutureWarning('Warning: The unique contraints have changed from:\n\t%s\n\nto:\n\t%s.\n-Unique constraints modification is not supported yet-\n' %(res[0], uniqueStr))

                cur = con.execute('PRAGMA table_info("%s")' % name)
                tableColumns = set()
                tableColumnsToKeep = []
                tableColumnsToDrop = []

                mustClean = False
                columns = {}
                columns['raba_id'] = 0
                columns['json'] = 1
                i = len(columns)
                for c in cur:
                    if c[1] != 'raba_id' and c[1] != 'json':
                        if c[1].lower() not in columnsToLowerCase:
                            mustClean = True
                            con.dropRabalist(name, c[1])
                            tableColumnsToDrop.append(c[1])
                        else:
                            tableColumnsToKeep.append(c[1])
                            columns[columnsToLowerCase[c[1].lower()]] = i
                            i += 1
                    tableColumns.add(c[1].lower())

                if mustClean:
                    con.dropColumnsFromRabaObjTable(name, tableColumnsToKeep)

                mustAlter = False
                for k in columnsToLowerCase:
                    if k not in tableColumns:
                        con.execute('ALTER TABLE %s ADD COLUMN %s' %
                                    (name, columnsToLowerCase[k]))
                        mustAlter = True

                if mustClean or mustAlter:
                    con.forceCommit()

            dct['columns'] = columns
            dct['columnsToLowerCase'] = columnsToLowerCase

            clsObj = type.__new__(cls, name, bases, dct)
            con.registerRabaClass(clsObj)
            return clsObj

        return type.__new__(cls, name, bases, dct)
Exemple #16
0
 def _setNamespaceConAndConf(self, namespace):
     self._raba_namespace = namespace
     self.connection = RabaConnection(self._raba_namespace)
     self.rabaConfiguration = RabaConfiguration(self._raba_namespace)