Esempio n. 1
0
    def update(self, id, **kwargs):
        ret = Storage()


        if self.parent:
           ret.parent = self.parent.update(id,**kwargs)

        self._write_history(id)
        db = self.db
        splited_args = self._split_args(kwargs)

        # update own
        if splited_args['own_args']:
            ret.own = db(self.own.id==id).update(**splited_args['own_args'])

        # update opt
        opt_args = splited_args['opt_args']
        if opt_args:
            for opt_tbl in opt_args:
                rows_to_update = opt_args[opt_tbl]
                if not rows_to_update:
                    continue

                rows_to_update = isinstance(rows_to_update, (list, tuple)) and rows_to_update \
                                or (rows_to_update,)
                own_FK_name = opt_tbl._entopt.own_FK.name
                ret_opt = ret[opt_tbl._tablename] = Storage(upd_ids=[], del_ids=[], ins_ids=[])
                for row in rows_to_update:
                    row[own_FK_name] = id
                    rec_id = row.get('id', None) or (opt_tbl._entopt.type=='one' and id)
                    rec = opt_tbl(rec_id)
                    if rec: # delete or update
                        rec = rec.as_dict()
                        if not rec:
                            raise RuntimeError('option update err: '+ opt_tbl._tablename+'[%s]'%rec_id+' - not found')
                        if rec[own_FK_name]!=id:
                            raise RuntimeError('option update err: '+ opt_tbl._tablename+'[%s]'%rec_id+' - has alien FK')
                        rec.update(row)
                        if  self.is_all_null(rec, ('id', own_FK_name)):
                            db(opt_tbl._id==rec_id).delete()
                            ret_opt.del_ids.append(rec_id)
                        else:
                            db(opt_tbl._id==rec_id).update(**rec)
                            ret_opt.upd_ids.append(rec_id)
                    elif not self.is_all_null(row, ('id', own_FK_name)): # insert
                        ret_opt.ins_ids.append(opt_tbl.insert(**row))
        return ret
Esempio n. 2
0
 def insert(self, **kwargs):
     ret = Storage()
     if self.parent:
         kwargs[self.parent.D_field.name] = self.D_value
         ret.parent = self.parent.insert(**kwargs)
         kwargs['id'] =  ret.parent.own
     splited_args = self._split_args(kwargs)
     id = self.own.insert(**splited_args['own_args'])
     opt_args = splited_args['opt_args']
     for opt_tbl in opt_args:
         rows_to_insert = opt_args[opt_tbl]
         rows_to_insert = isinstance(rows_to_insert, (list, tuple)) and rows_to_insert \
                         or (rows_to_insert,)
         own_FK_name = opt_tbl._entopt.own_FK.name
         ret[opt_tbl._tablename] = []
         for row in rows_to_insert:
             if self.is_all_null(row,['id', own_FK_name]):
                 continue
             row.pop('id', None)
             row[own_FK_name] = id
             ret[opt_tbl._tablename].append( opt_tbl.insert(**row) )
     ret.own = id
     return ret
Esempio n. 3
0
    def update_many(self, q, del_insert = False, **kwargs):
        ret = Storage()
        if self.parent:
           ret.parent = self.parent.update_many(q, del_insert, **kwargs)

        self._write_history(q)
        db = self.db
        #del_insert = kwargs.pop('del_insert', None)
        pg_com = db.executesql
        pg_com('CREATE TEMP TABLE  IF NOT EXISTS  tmp_ids (id bigint primary key);')
        pg_com(' TRUNCATE tmp_ids;')
        # select ids into temp
        sel_str = db(q)._select(self.own._id)
        save_str = ' INSERT INTO tmp_ids (%s);'%sel_str[:-1]
        pg_com(save_str)
        splited_args = self._split_args(kwargs)



        # update own
        sel_ids = 'select tmp_ids.id from tmp_ids;'
        ret.own = db(self.own.id.belongs(sel_ids)).update(**splited_args['own_args'])

        # update opt
        opt_args = splited_args['opt_args']

        for opt_tbl in opt_args:
            own_FK_name = opt_tbl._entopt.own_FK.name
            row_to_update = opt_args[opt_tbl]
            if opt_tbl._entopt.type == 'list':
            #if isinstance(row_to_update, (list, tuple)):
                if not del_insert:
                    raise RuntimeError('Can\'t update list option \'%s\' by query, set del_insert=True'%opt_tbl._tablename)
                else:
                    ids = db().select(db.tmp_ids.id)
                    ret_del_ins = ret[opt_tbl._tablename] = Storage()
                    ret_del_ins.deleted = db(opt_tbl._entopt.own_FK.belongs(sel_ids)).delete()
                    ret_del_ins.inserted_ids = []
                    row_to_ins=[r for r in row_to_update if not self.is_all_null(r, [own_FK_name, 'id'])]
                    for rid in ids:
                        for r in row_to_ins:
                            r.pop('id', None)
                            r[own_FK_name] = rid.id
                            ret_del_ins.inserted_ids.append(opt_tbl.insert(**r))
            else:
                ret_upd_ins =  ret[opt_tbl._tablename] = Storage()
                ret_upd_ins.updated = db(opt_tbl[own_FK_name].belongs(sel_ids)).update(**row_to_update)
                ret_upd_ins.inserted_ids=[]
                ret_upd_ins.deleted=[]
                if ret[opt_tbl._tablename] != db(db.tmp_ids).count():
                    #preform insert
                    ids= db(opt_tbl[own_FK_name]==None).select(db.tmp_ids.id, left = opt_tbl.on(opt_tbl[own_FK_name]==db.tmp_ids.id))
                    for r in ids:
                        row_to_update[own_FK_name] = r.id
                        ret_upd_ins.inserted_ids.append(opt_tbl.insert(**row_to_update))
                #delete nulls rows
                fld_lst= [f for f in  opt_tbl if f is not opt_tbl._entopt.own_FK]
                q_to_del = (fld_lst[0]==None) | ((fld_lst[0]==''))
                q_to_del=reduce( lambda q, f: q & ((f==None) | (f=='')) , fld_lst[1:] , q_to_del )
                ret_upd_ins.deleted = db(q_to_del).delete()
        return ret