def add(cls, redeem_code, user): sql = ( 'insert into {.table_name} (code_id, user_id, activity_id, consumed_time)' ' values(%s, %s, %s, %s)').format(cls) params = (redeem_code.id_, user.id_, redeem_code.activity.id_, datetime.now()) try: id_ = db.execute(sql, params) except MySQLdb.IntegrityError: raise RedeemCodeUsedError() code_used_times = cls.count_by_code_id(redeem_code.id_) code_usage = cls.get(id_) #: 超出兑换码本身使用次数限制时抛出异常 if code_used_times > redeem_code.max_usage_limit_per_code: code_usage.delete_by_id(code_usage.id_) raise RedemptionBeyondLimitPerCodeError() usage_used_times = cls.count_by_user_and_activity( user.id_, redeem_code.activity.id_) #: 用户在本次活动中使用兑换码数量超过活动限制时抛出异常 if usage_used_times > redeem_code.activity.max_usage_limit_per_user: code_usage.delete_by_id(code_usage.id_) raise RedemptionBeyondLimitPerUserError() else: db.commit() #: 清除缓存 cls.clear_cache(id_) cls.clear_cache_by_user_id(user.id_) cls.clear_cache_by_user_and_activity_id(user.id_, redeem_code.activity.id_) cls.clear_cache_by_code_id(redeem_code.id_) return cls.get(id_)
def add(cls, service_id, user_id, order_amount, fin_order_id, creation_time=None): """Creates a unpaid order. :param service_id: the UUID of chosen P2P service. :param user_id: the user id of order creator. :param order_amount: the payment amount for this order. :param fin_order_id: the UUID of remote order. :returns: the created order. """ cls.check_before_adding(service_id, user_id, order_amount) creation_time = creation_time or datetime.datetime.now() sql = ('insert into {.table_name} (service_id, user_id, order_amount,' ' fin_order_id, creation_time, status) ' 'values (%s, %s, %s, %s, %s, %s)').format(cls) params = (service_id, user_id, order_amount, fin_order_id, creation_time, OrderStatus.unpaid.value) id_ = db.execute(sql, params) db.commit() order = cls.get(id_) order.clear_cache() return order
def add(cls, account_id): if not Account.get(account_id): raise NotFoundError(account_id, Account) existent = cls.get(account_id) if existent: # 临时做法,弥补之前未添加创建时间的错误 if existent.creation_time is None: supply_sql = ('update {.table_name} set creation_time=%s' 'where account_id=%s').format(cls) supply_params = (datetime.now(), account_id) db.execute(supply_sql, supply_params) db.commit() cls.clear_cache(account_id) return existent sql = ('insert into {.table_name} (account_id, creation_time) ' 'values (%s, %s) ' 'on duplicate key update account_id = account_id').format(cls) params = (account_id, datetime.now()) db.execute(sql, params) db.commit() from core.models.hoard.profile import HoardProfile # if user hasn't hoard profile if not HoardProfile.get(account_id): add_savings_users() cls.clear_cache(account_id) return cls.get(account_id)
def add(cls, account, bankcard, amount, type_, transaction_id, status=Status.raw): """Creates a raw transaction.""" assert isinstance(account, WalletAccount) assert isinstance(amount, decimal.Decimal) assert isinstance(type_, cls.Type) assert isinstance(status, cls.Status) if not account.service_provider.is_avalable_bankcard(bankcard): raise UnavailableBankError(bankcard, account.service_provider) if str(account.local_account.id_) != str(bankcard.user_id): raise ValueError('mismatched user id') sql = ( 'insert into {0} (account_id, amount, type, bankcard_id, status,' ' transaction_id) ' 'values (%s, %s, %s, %s, %s, %s)').format(cls.table_name) params = ( account.id_, amount, type_.value, bankcard.id_, status.value, transaction_id) id_ = db.execute(sql, params) db.commit() cls.clear_cache(id_) cls.clear_cache_by_bankcard(bankcard.id_) cls.clear_cache_by_account(account.id_) cls.clear_cache_for_sum_amount() return cls.get(id_)
def create(cls, user, device_binding, notification): from core.models.notification import Notification assert isinstance(user, Account) assert isinstance(device_binding, DeviceBinding) assert isinstance(notification, Notification) if not (user.id_ == device_binding.user_id == notification.user_id): raise ValueError('invalid push tempt as user infos are unmatched') if cls.get_by_device_and_notification( device_binding.device_id, notification.id_): raise ValueError('notification can only be pushed once') sql = ('insert into {.table_name} (user_id, device_id, notification_id, ' 'status, creation_time) values (%s, %s, %s, %s, %s)').format(cls) params = (user.id_, device_binding.device_id, notification.id_, cls.Status.created.value, datetime.now()) id_ = db.execute(sql, params) db.commit() cls.clear_cache_key_by_user(user.id_) cls.clear_cache_key_by_device_and_notification( device_binding.device_id, notification.id_) return cls.get(id_)
def add(cls, subject, subject_type, content, content_type, start_time, stop_time, endpoint): assert isinstance(subject_type, cls.SubjectType) assert isinstance(content_type, cls.ContentType) assert start_time < stop_time assert datetime.datetime.now() < stop_time initial_status = cls.Status.present sql = ('insert into {0} (subject_type, content_type, status,' ' start_time, stop_time, endpoint, creation_time) ' 'values (%s, %s, %s, %s, %s, %s, %s)').format(cls.table_name) params = (subject_type.value, content_type.value, initial_status.value, start_time, stop_time, endpoint, datetime.datetime.now()) id_ = db.execute(sql, params) db.commit() cls.clear_cache(id_) for date in datetime_range(start_time, stop_time): cls.clear_cache_by_date(date) instance = cls.get(id_) instance.subject = subject instance.content = content return instance
def create(cls, user_id, kind, properties=None): assert isinstance(kind, NotificationKind) assert properties is None or isinstance(properties, dict) # 校验参数 user = Account.get(user_id) if not user: raise ValueError('invalid user id') if kind.is_once_only: id_list = cls.get_id_list_by_user_and_kind(user.id_, kind.id_) if id_list: return cls.get(id_list[0]) sql = ('insert into {.table_name} (user_id, kind_id, is_read, ' 'creation_time) values (%s, %s, %s, %s)').format(cls) params = (user_id, kind.id_, False, datetime.now()) id_ = db.execute(sql, params) db.commit() instance = cls.get(id_) instance.properties = properties or {} # 单播消息则提交并加入推送队列 cls.clear_cache_by_user(user.id_) cls.clear_cache_by_user_and_kind(user.id_, kind.id_) # 由推送控制中心来记录和完成推送 if kind.allow_push: mq_notification_push.produce(str(id_)) return instance
def add(cls, user_id, get_type, lottery_num, creation_time): sql = ('insert into {.table_name}' ' (user_id, get_type, lottery_num, creation_time)' ' values (%s, %s, %s, %s)').format(cls) params = (user_id, get_type, lottery_num, creation_time) db.execute(sql, params) db.commit()
def add(cls, user_id, gift_id, creation_time): sql = (u'insert into {.table_name}' u' (user_id, gift_id, creation_time)' u' values (%s, %s, %s)').format(cls) params = (user_id, gift_id, creation_time) db.execute(sql, params) db.commit()
def add(cls, user_id, code_type, verify_delta=timedelta(hours=24)): assert isinstance(verify_delta, timedelta) created_time = datetime.now() verify_time = created_time + verify_delta cls._remove(user_id) verify_code = gen_verify_code(code_type) i = 0 while i < MAX_RETRY: try: id = db.execute( 'insert into user_verify ' '(user_id, code_type, verify_code, created_time, ' 'verify_time) values(%s, %s, %s, %s, %s)', (user_id, code_type, verify_code, created_time, verify_time)) if id: db.commit() c = cls.get(id) return c else: i += 1 verify_code = gen_verify_code(code_type) db.rollback() except IntegrityError: i += 1 verify_code = gen_verify_code(code_type) db.rollback()
def add(cls, user_id): sql = ('insert into {0} (id, secret_key, is_enabled, creation_time) ' 'values (%s, %s, %s, %s)').format(cls.table_name) params = (user_id, cls.generate_key(), False, datetime.datetime.now()) db.execute(sql, params) db.commit() return cls.get(user_id)
def _set_is_frozen(self, flag): self.is_frozen = bool(flag) sql = 'update oauth_token set is_frozen = %s where id = %s' params = (self.is_frozen, self.id_) db.execute(sql, params) db.commit() self.clear_cache_by_instance()
def record(cls, date, annual_rate, ttp_income, fund_code): """Creates or updates one record of some day.""" # The ``on duplicate key update`` is useful in this situation. # But there are some MySQL issues (Bug #11765650, Bug #58637) stop us # from using it. # # The annual rates could be updated by schedule tasks only. We could # trust it that it is far away from concurrent writting. # So UPDATE after SELECT is safe there. # # See also: # http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html id_ = cls.get_id_by_date(date, fund_code) if id_: sql = ('update {0} set annual_rate = %s, ttp_income = %s ' 'where id = %s').format(cls.table_name) params = (annual_rate, ttp_income, id_) db.execute(sql, params) else: sql = ('insert into {0} (date, annual_rate, ttp_income,' ' fund_code) ' 'values (%s, %s, %s, %s)').format(cls.table_name) params = (date, annual_rate, ttp_income, fund_code) id_ = db.execute(sql, params) db.commit() cls.clear_cache(id_) return cls.get(id_)
def bind(cls, account_id, p2p_account, p2p_token, commit=True): """Creates new binding relationship and cancels all existent.""" cls.check_before_binding(account_id) params = (account_id, p2p_account, p2p_token) if not Account.get(account_id): raise NotFoundError(account_id, Account) existent = cls.get_by_local(account_id) if existent: cls.unbind(account_id, commit=False) if cls.get_by_remote(p2p_account) or cls.get_by_p2p_token(p2p_token): raise RemoteAccountUsedError(p2p_account) sql = ('insert into {.table_name} (account_id, p2p_account, p2p_token)' 'values (%s, %s, %s)').format(cls) db.execute(sql, params) if commit: db.commit() cls.clear_cache(account_id) return cls.get_by_local(account_id)
def status(self, new_status): assert isinstance(new_status, self.Status) db.execute('update {.table_name} set status=%s where id=%s', (new_status.value, self.id_)) db.commit() self._status = new_status.value self.clear_cache(self.id_)
def add(cls, account_id): """Creates a new profile for specific account and return it. If a profile exists, it will be return directly. :param account_id: the primary key of local account. :returns: the created (or existent) profile. """ if not Account.get(account_id): raise NotFoundError(account_id, Account) existent = cls.get(account_id) if existent: return existent sql = ('insert into {.table_name} (account_id) values (%s) ' 'on duplicate key update account_id = %s').format(cls) params = (account_id, account_id) db.execute(sql, params) db.commit() from core.models.hoard.zhiwang.profile import ZhiwangProfile from core.models.hoard.xinmi.profile import XMProfile # if user hasn't zhiwang and xm profile if not ZhiwangProfile.get(account_id) and not XMProfile.get( account_id): add_savings_users() cls.clear_cache(account_id) cls.clear_cache_for_account_ids() return cls.get(account_id)
def save(cls, user_id, person_name, person_ricn): if not cls._validate(person_name, person_ricn): raise IdentityValidationError(person_name, person_ricn) person_ricn = person_ricn.upper() if cls.get_by_ricn(person_ricn): raise IdentityUsedError if not is_matched_in_mathilde(person_name, person_ricn): raise IdentityDismatchError updated_time = datetime.datetime.now() sql = ('insert into {0} (id, person_name, person_ricn, updated_time) ' 'values (%s, %s, %s, %s) on duplicate key update' ' person_name = %s, person_ricn = %s,' ' updated_time = %s').format(cls.table_name) params = (user_id, person_name, person_ricn, updated_time, person_name, person_ricn, updated_time) db.execute(sql, params) db.commit() cls.clear_cache(user_id) instance = cls.get(user_id) identity_saved.send(instance) return instance
def update(self, mobile_phone, bank_id, city_id, province_id, local_bank_name, is_default): self.is_default = is_default changed = [field_name for field_name, field_changed in [ ('mobile_phone', self.mobile_phone != mobile_phone), ('bank_id', self.bank_id != bank_id), ('city_id', self.city_id != city_id), ('province_id', self.province_id != province_id), ('local_bank_name', self.local_bank_name != local_bank_name), ] if field_changed] if changed: sql = ('update {.table_name} set bank_id_sha1 = %s ' 'where id = %s').format(self) params = (calculate_checksum(bank_id), self.id_) db.execute(sql, params) self.update_props_items({ 'mobile_phone': mobile_phone, 'card_number': self.card_number, 'bank_id': bank_id, 'city_id': city_id, 'province_id': province_id, 'local_bank_name': local_bank_name, 'is_default': self.is_default, }) db.commit() bankcard_updated.send(self, changed_fields=changed) return changed
def record_for_binding(cls, bankcard, provider): """This method is a context manager for binding bankcard. The caller should access the remote API of third-party service provider with this context. :param bankcard: The bankcard instance. :param provider: The service provider instance. """ assert isinstance(bankcard, BankCard) assert isinstance(provider, ServiceProvider) id_ = cls.get_id_by_bankcard(bankcard.id_, provider.id_) if not id_: sql = ('insert into {0} (bankcard_id, provider_id, is_confirmed,' ' creation_time) ' 'values (%s, %s, %s, %s)').format(cls.table_name) params = (bankcard.id_, provider.id_, False, datetime.datetime.now()) id_ = db.execute(sql, params) db.commit() yield sql = ('update {0} set is_confirmed = %s ' 'where id = %s').format(cls.table_name) params = (True, id_) db.execute(sql, params) db.commit() cls.clear_cache(id_) cls.clear_cache_by_bankcard(bankcard.id_, provider.id_)
def restore(cls, id_, user_id): if not Account.get(user_id): raise ValueError('invalid user %r' % user_id) instance = cls(id_, user_id, None, None, None, None) new_card = cls.get_by_card_number(instance.card_number) if new_card: raise BankCardChanged(new_card.id_) card_number_sha1 = calculate_checksum(instance.card_number) bank_id_sha1 = calculate_checksum(instance.bank_id) sql = ('insert into {.table_name} (id, user_id, card_number_sha1,' ' bank_id_sha1, status) ' 'values (%s, %s, %s, %s, %s)').format(cls) params = (id_, user_id, card_number_sha1, bank_id_sha1, cls.Status.active.value) db.execute(sql, params) db.commit() bankcard = cls.get(id_) rsyslog.send('\t'.join([ str(id_), str(user_id), str(bankcard.card_number), str(bankcard.bank_id), str(bankcard.mobile_phone), str(bankcard.province_id), str(bankcard.city_id), str(bankcard.local_bank_name), ]), tag='restore_bankcard') return bankcard
def add(cls, alias, passwd_hash, salt, name, reg_type=ACCOUNT_REG_TYPE.MOBILE, gender=ACCOUNT_GENDER.UNKNOWN, status=ACCOUNT_STATUS.NEED_VERIFY): if Account.get_by_alias(alias): return try: id = db.execute( 'insert into account ' '(password, salt, name, gender, ' 'status, create_time)' 'values(%s, %s, %s, %s, %s, %s)', (passwd_hash, salt, name, gender, status, datetime.now())) if id: db.execute( 'insert into account_alias (`id`, alias, reg_type) ' 'values(%s, %s, %s)', (id, alias, reg_type)) db.commit() return cls.get(id) else: db.rollback() except IntegrityError: db.rollback() warn('insert account failed')
def status(self, item): sql = 'update {.table_name} set status=%s where id=%s;'.format(self) params = (item.value, self.id_,) db.execute(sql, params) db.commit() self.clear_cache() self._status = item.value
def add(cls, user_id, division_id, street, receiver_name='', receiver_phone=''): """Creates an address record. :param user_id: The id of local account. :param division_id: The GB2260 division code of city. :param street: The concrete street information. :param receiver_name: The real name of express delivery receiver. :param receiver_phone: The phone number of express delivery receiver. """ cls._validate(user_id, division_id, street) sql = ('insert into {0} (user_id, division_id, street, receiver_name,' ' receiver_phone) ' 'values (%s, %s, %s, %s, %s)').format(cls.table_name) params = (user_id, division_id, street, receiver_name, receiver_phone) id_ = db.execute(sql, params) db.commit() return cls.get(id_)
def add(cls, asset_no, order_code, bankcard_id, bank_account, product_id, user_id, status, annual_rate, actual_annual_rate, create_amount, current_amount, base_interest, expect_interest, current_interest, interest_start_date, interest_end_date, expect_payback_date, buy_time, creation_time=None): try: cls.check_before_adding(asset_no, order_code, create_amount, product_id) except AssetCreatedError: return None sql = ('insert into {.table_name}(asset_no, order_code, bankcard_id, bank_account, ' 'product_id, user_id, status, annual_rate, actual_annual_rate, create_amount, ' 'current_amount, base_interest, expect_interest, current_interest, ' 'interest_start_date, interest_end_date, expect_payback_date, buy_time, ' 'creation_time) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ' '%s, %s, %s, %s, %s, %s, %s)').format(cls) params = (asset_no, order_code, bankcard_id, bank_account, product_id, user_id, status.value, annual_rate, actual_annual_rate, create_amount, current_amount, base_interest, expect_interest, current_interest, interest_start_date, interest_end_date, expect_payback_date, buy_time, creation_time or datetime.datetime.now()) id_ = db.execute(sql, params) db.commit() instance = cls.get(id_) instance.clear_cache() return instance
def create(cls, loans_digest, loans, _commit=True): assert isinstance(loans_digest, XMLoansDigest) sql = 'insert into {.table_name} (loans_digest_id, creation_time) values(%s, %s)'.format( cls) params = (loans_digest.id_, datetime.datetime.now()) id_ = db.execute(sql, params) if _commit: db.commit() instance = cls.get(id_) cls.clear_cache(id_) cls.clear_cache_by_loans_digest_id(loans_digest.id_) instance.update_props_items({ 'loan_receipt_no': loans.loan_receipt_no, 'invest_id': loans.order_id, 'debtor_name': loans.bc_name, 'debtor_ricn': loans.debtor_identity_no, 'debtor_type': loans.debtor_type, 'debt_purpose': loans.debt_desc, 'lending_amount': str(loans.loan_receipt_amt), 'start_date': loans.start_date.isoformat() }) return instance
def _commit_and_refresh(self, sql, params): db.execute(sql, params) db.commit() self.clear_cache() new_state = vars(self.get(self.id_)) vars(self).update(new_state)
def create(cls, notification_kind, subdivision_kind=None): from core.models.notification import NotificationKind assert isinstance(notification_kind, NotificationKind) assert subdivision_kind is None or isinstance( subdivision_kind, notification_kind.subdivision_kind_cls) # 双层通知类型组播由于面向平台、标签组,可以进行单例检查 # 对于面向多别名、多设备的组播,由于有单次组播限制,因此无法进行单例检查 if subdivision_kind: if cls.get_by_bilayer_kinds(notification_kind, subdivision_kind): raise ValueError( 'the bilayer multicast/broadcast has been pushed once') sql = ( 'insert into {.table_name} (notification_kind_id, subdivision_kind_id, ' 'is_pushed, creation_time) values (%s, %s, %s, %s)').format(cls) params = (notification_kind.id_, subdivision_kind.id_ if subdivision_kind else None, False, datetime.now()) id_ = db.execute(sql, params) db.commit() cls.clear_cache(id_) cls.clear_cache_by_bilayer_kinds( notification_kind.id_, subdivision_kind.id_ if subdivision_kind else None) return cls.get(id_)
def add(cls, user_id): """Adds profile entity for specific user. Don't use it without any user's operation. If you need to obtain an attribute, use :meth:`.WalletProfile.get` instead:: wallet_profile = WalletProfile.get(g.user.id_) wallet_foo = wallet_profile.foo if wallet_profile else None The following way will cause users lost their landing page:: wallet_foo = WalletProfile.add(g.user.id_). :param user_id: The id of local account. """ existent = cls.get(user_id) if existent: return existent sql = ('insert into {0} (id, creation_time) ' 'values (%s, %s)').format(cls.table_name) params = (user_id, datetime.now()) id_ = db.execute(sql, params) db.commit() cls.clear_cache(id_) return cls.get(id_)
def create(cls, raw_product, wrapper_kind): # check the limit if (min(wrapper_kind.limit) < raw_product.min_amount or max(wrapper_kind.limit) > raw_product.max_amount): raise InvalidWrapRule(wrapper_kind.limit) # check the frozen time raw_days_period = [ raw_product.profit_period['min'].value, raw_product.profit_period['max'].value ] if not min(raw_days_period) <= wrapper_kind.frozen_days.value <= max( raw_days_period): raise InvalidWrapRule(wrapper_kind.id_) instance = cls.get_by_kind_and_raw_product_id(wrapper_kind.id_, raw_product.product_id) if instance is None: sql = ('insert into {.table_name} (kind_id, raw_product_id, ' 'creation_time) values (%s, %s, %s)').format(cls) params = (wrapper_kind.id_, raw_product.product_id, datetime.now()) id_ = db.execute(sql, params) db.commit() instance = cls.get(id_) instance.deploy(wrapper_kind) cls.clear_cache(id_) cls.clear_all_ids_cache() cls.clear_product_ids_by_raw_id_cache(raw_product.product_id) cls.clear_product_by_kind_and_raw_cache(wrapper_kind.id_, raw_product.product_id) return instance
def add(cls, user_id, product_id, bankcard_id, amount, pay_amount, expect_interest, start_date, due_date, order_code, pay_code, wrapped_product_id=None, creation_time=None): cls.check_before_adding(user_id, bankcard_id, product_id, amount, wrapped_product_id) sql = ( 'insert into {.table_name} (user_id, product_id, bankcard_id, amount, ' 'pay_amount, expect_interest, start_date, due_date, order_code, pay_code, ' 'status, wrapped_product_id, creation_time) values (%s, %s, %s, %s, %s, ' '%s, %s, %s, %s, %s, %s, %s, %s)').format(cls) params = (user_id, product_id, bankcard_id, amount, pay_amount, expect_interest, start_date, due_date, order_code, pay_code, cls.Status.unpaid.value, wrapped_product_id, creation_time or datetime.now()) id_ = db.execute(sql, params) db.commit() order = cls.get(id_) order.clear_cache() return order