75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
|
import itertools
|
||
|
|
||
|
from custom_decorators import singleton
|
||
|
from database import Database
|
||
|
from models import User
|
||
|
|
||
|
|
||
|
@singleton
|
||
|
class UserRepository:
|
||
|
def __init__(self, config):
|
||
|
self.db = Database(config['MYSQL'])
|
||
|
|
||
|
def get_or_create(self, user):
|
||
|
users = []
|
||
|
cursor = self.db.execute_query(*user.select_sql(condition="OR"))
|
||
|
same_users = cursor.fetchall()
|
||
|
new_user = not len(same_users)
|
||
|
# 对用户已存在的属性判断是否有新属性
|
||
|
update_user = set()
|
||
|
update_sqls = []
|
||
|
update_params_list = []
|
||
|
delete_params = []
|
||
|
exist_conflicting_attr = False
|
||
|
for same_user in same_users:
|
||
|
exist_conflicting_attr = False
|
||
|
different_attrs = user.get_difference(same_user)
|
||
|
# 用于判断是否有新属性
|
||
|
update_sql_params = []
|
||
|
update_params = []
|
||
|
for k, v in different_attrs.items():
|
||
|
new_attr, exist_attr = v
|
||
|
if exist_attr is None:
|
||
|
setattr(same_user, k, new_attr)
|
||
|
update_sql_params.append(f"{k}=%s")
|
||
|
update_params.append(new_attr)
|
||
|
else:
|
||
|
# 出现冲突的属性,考虑新增一行记录
|
||
|
exist_conflicting_attr = True
|
||
|
break
|
||
|
|
||
|
if same_user in update_user:
|
||
|
delete_params.append((same_user.id,))
|
||
|
else:
|
||
|
users.append(same_user)
|
||
|
exist_new_attr = bool(update_params)
|
||
|
if exist_new_attr:
|
||
|
update_user.add(same_user)
|
||
|
update_sqls.append(f'UPDATE user SET {",".join(update_sql_params)} WHERE id=%s;')
|
||
|
update_params.append(same_user.id)
|
||
|
update_params_list.append(update_params)
|
||
|
sql_flag = False
|
||
|
try:
|
||
|
if delete_params:
|
||
|
sql_flag = True
|
||
|
self.db.get_connection().cursor().executemany("DELETE FROM user WHERE id=%s", delete_params)
|
||
|
if update_user:
|
||
|
sql_flag = True
|
||
|
self.db.get_connection().cursor().execute("".join(update_sqls),
|
||
|
list(itertools.chain.from_iterable(update_params_list)),
|
||
|
multi=True)
|
||
|
if sql_flag:
|
||
|
self.db.commit()
|
||
|
except Exception:
|
||
|
self.db.rollback()
|
||
|
raise
|
||
|
if new_user or exist_conflicting_attr:
|
||
|
try:
|
||
|
self.db.execute_query(*user.insert_sql())
|
||
|
self.db.commit()
|
||
|
except Exception:
|
||
|
self.db.rollback()
|
||
|
raise
|
||
|
users.append(user)
|
||
|
return users
|