def set_working(self): assert self.is_in_writable_transaction(), "해당 instance 가 수정 가능한 Transaction 내에 없습니다." if self.status == Status.NEW: tran = TransactionManager.get_transaction() self._syncdb_insert(tran) assert self.status in (Status.NORMAL, Status.DIRTY) self._set_fields(status=Status.WORKING)
def register_on_transaction(self): # TODO : Transaction 매번 조회하는 부분 튜닝 tran = TransactionManager.get_transaction() assert self.id not in tran.instances, "해당 id 값으로 이미 생성된 instance 가 존재합니다." assert self.uri not in tran.uri_mapping, "해당 uri 값으로 이미 생성된 instance 가 존재합니다." self.creator = tran.checkin_actor tran.set(self)
def _mark_delete(self): if self._status_before_delete is None: self._status_before_delete = self.status self._old_syncdb_required = self._syncdb_required self.__dict__["status"] = Status.DELETED tran = TransactionManager.get_transaction() tran._mark_delete(self)
def assert_transaction(self): tran = TransactionManager.get_transaction() self_tran = self.tran if tran: assert TransactionManager.is_same_outermost_transaction( self_tran, tran ), "outermost transaction 이 일치하지 않습니다."
def _pre_create(self): tran = TransactionManager.get_transaction() assert tran and tran.key_gen, "트랜잭션 안에서만 인스턴스 생성이 가능합니다." self.status = Status.CREATING self.id = tran.gen_key() self.version = 0 self.last_transaction = tran.id
def test(self): tran = TransactionManager.get_transaction() instance1 = LoginID() instance1.uname = "gulby" instance1.save() instance2 = LoginID() with self.assertRaises(DuplicateUriException): instance2.uname = "gulby"
def onchange_uri(self, old, new): tran = TransactionManager.get_transaction() assert not old or old in tran.uri_mapping, "Transaction.uri_mapping 에 기존 uri 값이 존재하지 않습니다." if new in tran.uri_mapping: if self.status == Status.NEW: tran.remove(self) raise DuplicateUriException self._old_uri = old tran.set(self)
def create_history(self): column_names = [f for f in self.column_names if not f.startswith("computed") and not f.startswith("raw")] field_names_str = ",".join(column_names) tran = TransactionManager.get_transaction() query = "insert into base_modelhistory ({},{}) select {},{} from base_model where id=%s".format( "history_transaction", field_names_str, tran.id, field_names_str ) instance_id = self.id run_sql(query, params=(instance_id,))
def from_db(cls, db, field_names, values): new_id = values[0] tran = TransactionManager.get_transaction() already = tran and tran.get(new_id) if already: return already new = cls.from_db_impl(db, field_names, values) assert new.id == new_id tran and tran.set(new) return new
def checkin(self, actor_type): if not isinstance(actor_type, Type): assert issubclass(actor_type, Actor) actor_type = actor_type.my_type actor = self.actors.filter(type=actor_type).order_by("-id").first() if not actor: raise CheckinException("{} 권한이 없습니다.".format(actor_type.name)) tran = TransactionManager.get_transaction() tran.checkin(actor) return actor
def id_password_login(request): tran = TransactionManager.get_transaction() if request.method == "POST": login_id = LoginID.objects.get(login_id=request.POST.get("login_id", "")) password = request.POST.get("password", "") human = login_id.authenticate(password) human.checkin(Type.TaxAccountant) return render( request, "human/id_password_login.html", {"login_user": tran.login_user, "checkin_actor": tran.checkin_actor} )
def _destroy(self, using=None, keep_parents=True): assert using is None, "using 은 지원하지 않습니다." assert keep_parents is True, "keep_parents 는 지원하지 않습니다." assert self.status == Status.DELETED, "DELETED 상태에서만 _destroy() 호출이 가능합니다." assert self._syncdb_required is False, "_syncdb_required 가 False 일때만 _destroy() 호출이 가능합니다." if self._status_before_delete != Status.NEW: super().delete(using=None, keep_parents=True) self.init_variables() tran = TransactionManager.get_transaction() tran.clear_query_cache() tran.remove(self) self.__dict__["id"] = None
def authenticate(self, password): if not self.check_password(password): raise PasswordNotMatchException("password 가 일치하지 않습니다.") password_expire_date = self.password_expire_date if password_expire_date and password_expire_date < now(): raise PasswordExpiredException("패스워드가 만료되었습니다.") human = self.human assert isinstance(human, Human) tran = TransactionManager.get_transaction() if tran.login_user is not None and tran.login_user != human: tran.logout() tran.login(human) return human
def test_uri_property(self): uri = "/uri/1/" assert Dummy.objects.filter(uri=uri).count() == 0 instance = Dummy() assert instance.uri is None assert instance.computed["uri"] is None assert not instance.computed_uri_hash with ForceChanger(instance): instance.uri = uri assert instance.uri == uri assert instance.computed["uri"] == uri assert instance.computed_uri_hash instance.save() assert Dummy.objects.filter(uri=uri).count() == 1 with ForceChanger(instance): instance.uri = None assert instance.uri is None assert instance.computed_uri_hash is None uname = "*****@*****.**" instance.uname = uname assert instance.uname == uname assert instance.uri == "/uri/base/dummy/{}/".format(uname) assert instance.computed_uri_hash is not None instance.save() tran = TransactionManager.get_transaction() instance._syncdb_update(tran) query = str(Dummy.objects.filter(uname=uname).query) assert query.find("computed_uri_hash") != -1 assert Dummy.objects.filter(uname=uname).count() == 1 assert Dummy.objects.filter(uname="asdf").count() == 0 with self.assertRaises(AssertionError): instance.uri = "asdf" other_uname = "*****@*****.**" instance.uname = other_uname assert instance.uname == other_uname instance.uname = uname assert instance.uname == uname instance2 = Dummy() instance2.uname = other_uname assert instance2.uname == other_uname assert instance2.status == Status.NEW with self.assertRaises(DuplicateUriException): instance2.uname = uname assert instance2.status == Status.INVALID with self.assertRaises(AssertionError): instance2.uname = other_uname with self.assertRaises(AssertionError): instance2.save() instance.save()
def test_transaction(self): with Transaction(): instance = Dummy() instance.save() assert instance.last_transaction is not None old_last_transaction = instance.last_transaction with Transaction() as tran1: tran2 = TransactionManager.get_transaction() assert id(tran1) == id(tran2) instance1 = Model.objects.get(id=instance.id) # 중간에 다른 트랜잭션에서 치고 들어온 것을 simulation with Transaction() as tran3: assert tran3 != tran1 tran4 = TransactionManager.get_transaction() assert id(tran3) == id(tran4) instance2 = Model.objects.get(id=instance1.id) assert instance2 == instance1 assert id(instance1) != id(instance2) with ForceChanger(instance2): instance2.uri = "/uri/1/" instance2.save() assert instance2.last_transaction > old_last_transaction old_last_transaction = instance2.last_transaction with tran1: tran6 = TransactionManager.get_transaction() assert id(tran6) == id(tran1) assert instance1.computed["uri"] is None with Transaction(): instance3 = Model.objects.get(id=instance1.id) assert instance3.computed["uri"] == "/uri/1/" instance3.delete() assert instance3.last_transaction > old_last_transaction
def __init__(self, *args, **kwargs): subfield_kwargs = kwargs.pop("subfield_kwargs", {}) super().__init__(*args, **kwargs) is_create = not self.id if is_create: self._pre_create() self.init_variables() if is_create: self.register_on_transaction() self._init_subfields(**subfield_kwargs) tran = TransactionManager.get_transaction() if tran and tran.is_readonly: self.__dict__["status"] = Status.NO_SYNC else: self.__dict__["status"] = Status.NEW self.on_create()
def test(self): tran = TransactionManager.get_transaction() # setUp() 시점에 이미 transaction 이 만들어져 있어서 instance.last_transaction_date <= t0 가 성립하지 않을 수 있어 교체 tran.key_gen = KeyGenerator() t00 = now() instance = Dummy.objects.create() assert instance.last_transaction t0 = now() assert t00 <= instance.created_date <= t0 assert self.t_before_tran <= instance.last_transaction_date <= t0 instance.created_date = t0 assert instance.created_date == t0 assert instance.data["created_date"] == str(t0) t1 = now() instance.created_date = t1 assert instance.created_date == t1 assert instance.data["created_date"] == str(t1) instance.created_date = None assert instance.created_date is None assert instance.data["created_date"] is None instance.save()
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): # check assert not using or using == "default", "using 은 지원하지 않습니다." assert update_fields is None, "update_fields 는 지원하지 않습니다." assert self.is_in_writable_transaction( ), "해당 instance 가 수정 가능한 Transaction 내에 없습니다." old_status = self.status if old_status in (Status.NORMAL, Status.WORKING): self.on_nosave() return assert old_status in ( Status.NEW, Status.DIRTY, Status.DELETED), "save() 호출이 가능한 상태가 아닙니다: {}".format(old_status) assert not force_insert or old_status == Status.NEW assert not force_update or old_status == Status.DIRTY # impl self._syncdb_required = True tran = TransactionManager.get_transaction() tran.clear_query_cache()
def tran(self): return TransactionManager.get_transaction()
def logout(self): tran = TransactionManager.get_transaction() assert tran.login_user == self tran.logout()
def setUp(self): tran = TransactionManager.get_transaction() self.t_before_tran = get_datetime_from_key(tran.id)
def _set_invalid_and_raise(self, e=Exception()): tran = TransactionManager.get_transaction() self.__dict__["status"] = Status.INVALID tran.remove(self) raise e
def is_in_writable_transaction(self): tran = TransactionManager.get_transaction() return tran and not tran.is_readonly and self.id in tran.instances
def assert_changeable(self, field_name=None): assert self.status, "DELETED 상태여서 수정할 수 없습니다." tran = TransactionManager.get_transaction() assert tran, "Transaction 내부가 아니어서 수정할 수 없습니다." assert tran.is_readonly is False, "ReadonlyTransaction 에서는 수정할 수 없습니다."
def __init__(self, model=None, query=None, using=None, hints=None, cache=None): super().__init__(model, query, using, hints) self._result_cache = cache self.tran = TransactionManager.get_transaction() self._filters = []