diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2d85ac68819d05771d0cc246b0351b7c616804ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea +__pycache__/ +setup.py +upload.bat +pyproject.toml +delete.py +*.pyc +venv \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 8f02d69fcb5a98d02eebec4fb93cab6b854c9dee..0000000000000000000000000000000000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/../../../../:\Github\CACodeFramework-python-ORM\.idea/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/CACodeFramework-python-ORM.iml b/.idea/CACodeFramework-python-ORM.iml deleted file mode 100644 index 5ed0139f27bed0fe8b3612df9b3ca502d70295bb..0000000000000000000000000000000000000000 --- a/.idea/CACodeFramework-python-ORM.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index da484797c158b883f2d96a10bf70ccfcdca0d2fe..0000000000000000000000000000000000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da2d6447d11dfe32bfb846c3d5b199fc99..0000000000000000000000000000000000000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index d56657add3eb3c246989284ec6e6a8475603cf1d..0000000000000000000000000000000000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 99e9e955e8d95bcaddbec9f85230693536e2e743..0000000000000000000000000000000000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f4cb416c083d265558da75d457237d671..0000000000000000000000000000000000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/CACodeFramework/MainWork/Annotations.py b/CACodeFramework/MainWork/Annotations.py deleted file mode 100644 index 2f3df4be341a21106a49e6b000b51082e6ba9fa7..0000000000000000000000000000000000000000 --- a/CACodeFramework/MainWork/Annotations.py +++ /dev/null @@ -1,92 +0,0 @@ -def Table(name, msg, **kwargs): - """ - 标注该类为一个表 - :param name:表的名称 - :param msg:表的描述 - :return: - """ - - def set_to_field(func): - setattr(func, '__table_name__', name) - setattr(func, '__table_msg__', msg) - for key, value in kwargs.items(): - setattr(func, key, value) - return func - - return set_to_field - - -def Operations(): - """ - 标注该类为一个操做 - :return: - """ - - def set_to_field(func): - print('1111111') - return func - - return set_to_field - - -def Before(function): - """ - 切入操做,在执行函数之前切入指定函数 - - 切入: - - 在执行函数之前首先执行指定操做称为切入 - - """ - - def set_to_field(func): - print('1111111') - return func - - return set_to_field - - -def After(function): - """ - 切出操做,在执行函数之前切出指定函数 - - 切出: - - 在指定函数调用完毕时执行得操做成为切除 - """ - - def set_to_field(func): - print('1111111') - return func - - return set_to_field - - -from functools import wraps - - -def decorater(func): - @wraps(func) # 保持原函数名不变 - def wrapper(*args, **kwargs): - print('位置参数:{}'.format(args)) - print('关键字参数:{}'.format(kwargs)) - res = func(*args, **kwargs) - print('装饰器内函数名:%s' % func.__name__) - print('返回值:%s' % res) - print('函数func所属的类:%s' % func.__qualname__) - print('被调用时的行号:', sys._getframe().f_back.f_lineno) - return res - - return wrapper - - -class Name(): - @decorater - def func2(self, *args, **kwargs): - return 'return' - - -if __name__ == '__main__': - a = Name() - a.func2(1, 2, a=3, b=4) - print('装饰外内函数名:%s' % a.func2.__name__) diff --git a/CACodeFramework/MainWork/CACodePureORM.py b/CACodeFramework/MainWork/CACodePureORM.py index 95ae8e6a61402994d50ea2facd11e1ce3b3f9b97..500b9fc158e947cc02e80708910da143e3058eac 100644 --- a/CACodeFramework/MainWork/CACodePureORM.py +++ b/CACodeFramework/MainWork/CACodePureORM.py @@ -1,5 +1,7 @@ # 纯净ORM -from CACodeFramework.MainWork.opera import obj_dict, op_db +from CACodeFramework.cacode.Serialize import QuerySet +from CACodeFramework.exception import e_fields +from CACodeFramework.util.Log import CACodeLog from CACodeFramework.util.ParseUtil import ParseUtil from CACodeFramework.field.sql_fields import * @@ -16,19 +18,27 @@ class CACodePureORM(object): 上手快 """ - def __init__(self, repository): - """ + def __init__(self, repository, serializer=QuerySet): + """s 初始化ORM :param repository:仓库 """ - self.parses = op_db.parses() self.args = [] self.params = [] if repository is None: - raise SyntaxError('') + CACodeLog.err(AttributeError, 'Repository is null,Place use repository of ORM framework') self.repository = repository self.__table_name__ = '{}{}{}'.format(subscript, repository.__table_name__, subscript) - self.parses = obj_dict.parses() + + self.first_data = False + self.serializer = serializer + + def first(self): + """ + 是否只返回第一行数据 + """ + self.first_data = True + return self # ------------------------主键-------------------------- @@ -43,7 +53,7 @@ class CACodePureORM(object): # 添加insert关键字 # self.args.append(insert_str) # self.args.append('{}{}'.format(self.__table_name__, left_par)) - sql = obj_dict.parses().parse_insert(pojo, self.__table_name__.replace('`', '')) + sql = ParseUtil.parse_insert_pojo(pojo, self.__table_name__.replace('`', '')) self.args.append(sql['sql']) self.params = sql['params'] @@ -244,6 +254,12 @@ class CACodePureORM(object): find('all').desc().end() find('all').order_by('param').desc().limit(10,20) """ + + if order_by_str not in self.args: + raise CACodeLog.err(AttributeError, + e_fields.CACode_SQLERROR( + 'There is no `order by` field before calling `desc` field,You have an error in your SQL syntax')) + self.args.append(desc_str) return self @@ -261,7 +277,7 @@ class CACodePureORM(object): # set是加逗号不是and self.args.append(comma) self.params.append(value) - self.rep_sym(comma, '') + self.rep_sym(comma) return self # ------------------------预设符-------------------------- @@ -282,7 +298,7 @@ class CACodePureORM(object): 最终执行任务 """ sql = '' - conf = self.repository.config_obj.conf + conf = self.repository.config_obj.get_dict() print_sql = 'print_sql' in conf.keys() and conf['print_sql'] is True last_id = 'last_id' in conf.keys() and conf['last_id'] is True for i in self.args: @@ -296,7 +312,7 @@ class CACodePureORM(object): ) _result_objs = [] for i in _result: - _obj = self.parses.parse_obj(data=i, participants=self.repository.participants) + _obj = ParseUtil.parse_obj(data=i, instance=self.repository.participants) _result_objs.append(_obj) _result = _result_objs else: @@ -309,7 +325,12 @@ class CACodePureORM(object): # 清空资源,为下一次使用做准备 self.args.clear() self.params.clear() - return _result + if self.first_data: + if type(_result) is list or type(_result) is tuple: + return self.serializer(instance=self.repository.participants, base_data=_result).first() + else: + q = self.serializer(instance=self.repository.participants, base_data=_result) + return q def con_from(self): """ diff --git a/CACodeFramework/MainWork/CACodeRepository.py b/CACodeFramework/MainWork/CACodeRepository.py index 4fd0061f59778085aa3c13cbeb3fb3e4b7096ff7..20b6d3637f6e9716e9a7333c7fd83da260d94a8f 100644 --- a/CACodeFramework/MainWork/CACodeRepository.py +++ b/CACodeFramework/MainWork/CACodeRepository.py @@ -1,6 +1,7 @@ import copy -from CACodeFramework.MainWork.opera import op_db +from CACodeFramework.cacode.Serialize import QuerySet +from CACodeFramework.opera import op_db from CACodeFramework.util.Log import CACodeLog from CACodeFramework.MainWork.CACodePureORM import CACodePureORM @@ -11,6 +12,8 @@ import threading import uuid # threadLocal 避免线程干扰 +from CACodeFramework.util.ParseUtil import ParseUtil + t_local = threading.local() @@ -36,8 +39,8 @@ class Repository(object): - 需要配合:@Table(name, msg, **kwargs)使用 """ - def __init__(self, config_obj=None, participants=None, log_conf=None, close_log=False): - """作者:CACode 最后编辑于2021/4/12 + def __init__(self, config_obj=None, participants=None, log_conf=None, close_log=False, serializer=QuerySet): + """作者:CACode 最后编辑于2021/4/27 通过继承此类将数据表实体化 @@ -61,11 +64,10 @@ class Repository(object): 使用本类需要携带一个来自CACodeFramework.util.Config.config的配置类,详见:CACodeFramework.util.Config.config - Attributes: - - config_obj:配置类,继承自CACodeFramework.util.Config.config类 - - participants:参与解析的对象 + :param config_obj:配置类 + :param log_conf:日志配置类 + :param close_log:是否关闭日志显示功能 + :param serializer:自定义序列化器,默认使用CACodeFramework.cacode.Serialize.QuerySet """ # 移除name和msg键之后,剩下的就是对应的数据库字段 # 设置表名 @@ -73,13 +75,12 @@ class Repository(object): self.close_log = close_log self.__table_name__ = self.__table_name__ self.operation = op_db.DbOperation() - self.parse = op_db.parses() if not self.close_log: - CACodeLog.log(_obj=self, msg='Being Initialize this object') + CACodeLog.log(obj=self, msg='Being Initialize this object') # 模板类 self.participants = participants # 该对象的所有字段 - fds = participants.to_dict() + fds = participants.fields self.fields = list(fds.keys()) # 配置类 self.config_obj = config_obj @@ -99,6 +100,8 @@ class Repository(object): self.log_obj = LogObj(**log_conf) # 返回的结果 self.result = None + # 序列化器 + self.serializer = serializer def conversion(self): """作者:CACode 最后编辑于2021/4/12 @@ -108,7 +111,7 @@ class Repository(object): Return: ORM转换之后的实体对象 """ - return CACodePureORM(self) + return CACodePureORM(self, serializer=self.serializer) def find_all(self): """作者:CACode 最后编辑于2021/4/12 @@ -122,7 +125,10 @@ class Repository(object): name = str(uuid.uuid1()) # 开启任务 kwargs = {'func': self.operation.__find_all__, '__task_uuid__': name, 't_local': self} - self.result = self.operation.start(*self.fields, **kwargs) + result = self.operation.start(*self.fields, **kwargs) + + self.result = self.serializer(instance=self.participants, base_data=result) + return self.result def find_by_field(self, *args): @@ -145,8 +151,9 @@ class Repository(object): # 开启任务 kwargs = {'func': self.operation.__find_by_field__, '__task_uuid__': name, 't_local': self} - self.result = self.operation.start(*args, **kwargs) + result = self.operation.start(*args, **kwargs) + self.result = self.serializer(instance=self.participants, base_data=result) return self.result def find_one(self, **kwargs): @@ -214,7 +221,9 @@ class Repository(object): kwargs['func'] = self.operation.__find_many__ kwargs['__task_uuid__'] = name kwargs['t_local'] = self - self.result = self.operation.start(**kwargs) + result = self.operation.start(**kwargs) + + self.result = self.serializer(instance=self.participants, base_data=result) return self.result def find_sql(self, **kwargs): @@ -223,8 +232,6 @@ class Repository(object): - 可自动化操作 - 请尽量使用find_many(sql)操作 :param kwargs:包含所有参数: - pojo:参照对象 - last_id:是否需要返回最后一行数据,默认False sql:处理过并加上%s的sql语句 params:需要填充的字段 print_sql:是否打印sql语句 @@ -236,7 +243,9 @@ class Repository(object): kwargs['func'] = self.operation.__find_sql__ kwargs['__task_uuid__'] = name kwargs['t_local'] = self - self.result = self.operation.start(**kwargs) + result = self.operation.start(**kwargs) + + self.result = self.serializer(instance=self.participants, base_data=result) return self.result def update(self, **kwargs): @@ -252,8 +261,8 @@ class Repository(object): :return: """ kwargs['config_obj'] = t_local.config_obj - kwargs = self.parse.print_sql(**kwargs) - kwargs = self.parse.last_id(**kwargs) + kwargs = ParseUtil.print_sql(**kwargs) + kwargs = ParseUtil.last_id(**kwargs) return t_local.db_util.update(**kwargs) def insert_sql(self, **kwargs): @@ -266,8 +275,8 @@ class Repository(object): params:需要填充的字段 :return rowcount,last_id if last_id=True """ - kwargs = self.parse.print_sql(**kwargs) - kwargs = self.parse.last_id(**kwargs) + kwargs = ParseUtil.print_sql(**kwargs) + kwargs = ParseUtil.last_id(**kwargs) return self.db_util.insert(**kwargs) def save(self, **kwargs): @@ -284,7 +293,6 @@ class Repository(object): :param kwargs:包含所有参数: pojo:参照对象 last_id:是否需要返回最后一行数据,默认False - params:需要填充的字段 :return:rowcount,last_id if last_id=True """ # 设置名称 @@ -307,9 +315,9 @@ class Repository(object): params:需要填充的字段 :return:list[rowcount,last_id if last_id=True] """ - kwargs['config_obj'] = t_local.config_obj - kwargs = self.parse.print_sql(**kwargs) - kwargs = self.parse.last_id(**kwargs) + kwargs['config_obj'] = self.config_obj + kwargs = ParseUtil.print_sql(**kwargs) + kwargs = ParseUtil.last_id(**kwargs) t_local._result = [] for item in kwargs['pojo_list']: kwargs['pojo'] = item diff --git a/CACodeFramework/MainWork/__pycache__/Annotations.cpython-39.pyc b/CACodeFramework/MainWork/__pycache__/Annotations.cpython-39.pyc deleted file mode 100644 index f8c58dfeae26ae8cd288a70af163dc1c38a14678..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/__pycache__/Annotations.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/__pycache__/CACodePojo.cpython-39.pyc b/CACodeFramework/MainWork/__pycache__/CACodePojo.cpython-39.pyc deleted file mode 100644 index 67d39a40abb877adc9e874b3813652affcb8815d..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/__pycache__/CACodePojo.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/__pycache__/CACodePureORM.cpython-39.pyc b/CACodeFramework/MainWork/__pycache__/CACodePureORM.cpython-39.pyc deleted file mode 100644 index 85963b53b56f0e106fc91e799f0914f2dda84f19..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/__pycache__/CACodePureORM.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/__pycache__/CACodeRepository.cpython-39.pyc b/CACodeFramework/MainWork/__pycache__/CACodeRepository.cpython-39.pyc deleted file mode 100644 index 6c5f6d5ee8ca3907f3d13315f3c766b03e158e58..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/__pycache__/CACodeRepository.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/__pycache__/__init__.cpython-39.pyc b/CACodeFramework/MainWork/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 5c70e4f5f15a98629aa4c960d98cb2cbf49c3057..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/__pycache__/__init__.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/exception/__pycache__/__init__.cpython-39.pyc b/CACodeFramework/MainWork/exception/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 5c21c0cdea6d85f7db1f3b09a11612f523499b8d..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/exception/__pycache__/__init__.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/exception/__pycache__/e_except.cpython-39.pyc b/CACodeFramework/MainWork/exception/__pycache__/e_except.cpython-39.pyc deleted file mode 100644 index ada947f55639221d46c2c7efd801b2a60f578755..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/exception/__pycache__/e_except.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/exception/e_except.py b/CACodeFramework/MainWork/exception/e_except.py deleted file mode 100644 index d76a1c846b109c8c671cd7f17597f51ee5aa6f80..0000000000000000000000000000000000000000 --- a/CACodeFramework/MainWork/exception/e_except.py +++ /dev/null @@ -1,41 +0,0 @@ -from datetime import datetime -import warnings - -from CACodeFramework.field import e_fields - - -def warn(obj, line, msg, f_warn, LogObject=None, task_name='\t\tMAIN'): - """作者:CACode 最后编辑于2021/4/13 - - 输出日志并返回日志内容 - - 此方法不会中断程序运行 - - 格式: - - 时间 类型 日志名称 对象地址 被调用行号 执行类型 信息 - 示例: - - line:234: Warning: 2021-04-13 08:24:08.169 WARN CACode-Database-Operation [1907116304800] [line:234] [2021-04-13 08:24:08.169] :INITIALIZE THIS OBJECT - """ - t = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] - info = '{} {} {} [{}] [{}] [{}] \t\t\t:{}'.format(t, f_warn, - e_fields.LOG_OPERA_NAME, - id(obj), - obj.__str__(), - task_name, - msg) - # 输出日志信息 - warnings.warn_explicit(info, category=Warning, filename='line', lineno=line) - if LogObject is not None: - LogObject.warn(info) - return info - - -def error(cls, msg): - """作者:CACode 最后编辑于2021/4/13 - - 抛出异常并终止程序执行 - Atte - """ - raise cls(msg) diff --git a/CACodeFramework/MainWork/opera/__pycache__/__init__.cpython-39.pyc b/CACodeFramework/MainWork/opera/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 182160f084aff99160926d35493f7004b84dff6b..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/opera/__pycache__/__init__.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/opera/__pycache__/obj_dict.cpython-39.pyc b/CACodeFramework/MainWork/opera/__pycache__/obj_dict.cpython-39.pyc deleted file mode 100644 index 7475998d1dbe35583e3c538fb681aa6ac2e4e080..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/opera/__pycache__/obj_dict.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/opera/__pycache__/op_db.cpython-39.pyc b/CACodeFramework/MainWork/opera/__pycache__/op_db.cpython-39.pyc deleted file mode 100644 index 3344c3ad6be5eda086b00a7262216aa8f98fa62d..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/MainWork/opera/__pycache__/op_db.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/opera/obj_dict.py b/CACodeFramework/MainWork/opera/obj_dict.py deleted file mode 100644 index 5d00ca8882472e1153e85528a4753e5a079f138f..0000000000000000000000000000000000000000 --- a/CACodeFramework/MainWork/opera/obj_dict.py +++ /dev/null @@ -1,111 +0,0 @@ -import copy -import sys - -from CACodeFramework.MainWork.exception import e_except -from CACodeFramework.field import e_fields -from CACodeFramework.util.ParseUtil import ParseUtil - - -class parses(object): - def __init__(self, *args, **kwargs): - self.args = args - self.kwargs = kwargs - - def log(self, _obj, msg, name='\t\tTask', LogObject=None): - """ - 输出任务执行日志 - - :param _obj:任务对象的值 - - """ - # 获得该函数被调用前的行号 - _l = sys._getframe().f_back.f_lineno - # 格式:时间 类型 日志名称 对象地址 被调用行号 执行类型 信息 - info = e_except.warn(obj=_obj, line=_l, task_name=name, f_warn=e_fields.INFO, msg=msg, LogObject=LogObject) - - def last_id(self, **kwargs): - """作者:CACode 最后编辑于2021/4/12 - - 遵循规则: - - 内部>配置文件 - - 是否包含返回最后一行ID的配置 - - 只存在于更新操做的方法内,如: - - insert, - - update, - - delete - - Attributes: - - conf_obj:配置类 - """ - conf_obj = kwargs['config_obj'] - if 'last_id' not in kwargs.keys(): - if 'last_id' in conf_obj.conf.keys(): - kwargs['last_id'] = conf_obj.conf['last_id'] - else: - kwargs['last_id'] = False - return kwargs - - def print_sql(self, **kwargs): - """ - 遵循规则: - 内部>配置文件 - - 是否包含打印sql的配置 - - 存在于所有数据库操做 - - Attributes: - conf_obj:配置类 - """ - conf_obj = kwargs['config_obj'] - if 'print_sql' not in kwargs.keys(): - if 'print_sql' in conf_obj.conf.keys(): - kwargs['print_sql'] = conf_obj.conf['print_sql'] - else: - kwargs['print_sql'] = False - return kwargs - - def parse_insert(self, pojo, __table_name__): - """ - 解析插入语句 - - INSERT INTO `__table_name__`(`title`,'selects') VALUE ('','') - - :param pojo:POJO对象 - :param __table_name__:表名 - :return: - """ - _dict = pojo.to_dict() - # 得到所有的键 - keys = pojo.fields - # 在得到值之后解析是否为空并删除为空的值和对应的字段 - cp_value = [] - values = [getattr(pojo, v) for v in keys] - for i, j in enumerate(values): - if j is None or pojo.eq_default(j): - del keys[i] - else: - cp_value.append(j) - return ParseUtil().parse_insert(keys, cp_value, __table_name__) - - def parse_obj(self, data: dict, participants): - """ - 将数据解析成对象 - 注意事项: - 数据来源必须是DbUtil下查询出来的 - :param data:单行数据 - :param participants:参与解析的对象 - :return:POJO对象 - """ - # 深度复制对象 - part_obj = copy.copy(participants) - for key, value in data.items(): - setattr(part_obj, key, value) - return part_obj diff --git a/CACodeFramework/__pycache__/__init__.cpython-39.pyc b/CACodeFramework/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 4b3cc958dcf1b08eb490f01173a3b9ba80737d6d..0000000000000000000000000000000000000000 Binary files a/CACodeFramework/__pycache__/__init__.cpython-39.pyc and /dev/null differ diff --git a/CACodeFramework/MainWork/exception/__init__.py b/CACodeFramework/anno/__init__.py similarity index 100% rename from CACodeFramework/MainWork/exception/__init__.py rename to CACodeFramework/anno/__init__.py diff --git a/CACodeFramework/anno/annos.py b/CACodeFramework/anno/annos.py new file mode 100644 index 0000000000000000000000000000000000000000..1401ae638eeb1896613173afc4d8ee63fbae42f9 --- /dev/null +++ b/CACodeFramework/anno/annos.py @@ -0,0 +1,192 @@ +import re +import inspect + +from CACodeFramework.anno.aop import AopModelObject +from CACodeFramework.cacode.Serialize import QuerySet + + +def Table(name, msg, **kwargs): + """ + 标注该类为一个表 + :param name:表的名称 + :param msg:表的描述 + :return: + """ + + def set_to_field(cls): + setattr(cls, '__table_name__', name) + setattr(cls, '__table_msg__', msg) + for key, value in kwargs.items(): + setattr(cls, key, value) + return cls + + return set_to_field + + +def parse_kwargs(params, kwargs): + """ + 通过${key}方式解析特殊字段 + """ + new_args = [] + for i in params: + # 反选字符并替换 + sub = re.sub(r'\${(.*?)}', '{}', str(i)) + context = re.findall(r'\${(.*?)}', str(i)) + if context: + mk = [] + for con in context: + mk.append(kwargs[con]) + # 将字符格式化进sub + sfm = sub.format(*mk) + new_args.append(sfm) + + else: + new_args.append(i) + + return new_args + + +def Select(sql, params=None): + """ + 快捷的查询装饰器 + + 使用此装饰器,可以将大量重复代码继承到此装饰器内部实现 + + 使用方法: + @Select(sql="SELECT * FROM demo_table WHERE t_id<=%s AND t_msg like %s", params=['${t_id}', '%${t_msg}%']) + + sql:执行的sql语句,需要加密的参数使用`%s`表示 + + params:加密参数的内容,标记使用传参请使用`${字段名}`表示 + + + + """ + + def base_func(cls): + def _wrapper_(*args, **kwargs): + lines = list(args) + obj = lines[0] + del lines[0] + # cls_obj = cls(*lines, **kwargs) + + new_args = parse_kwargs(params, kwargs) + + result = obj.find_sql(sql=sql, params=new_args) + + return QuerySet(obj, result) + + return _wrapper_ + + return base_func + + +def AopModel(before=None, after=None, + before_args=None, before_kwargs=None, + after_args=None, after_kwargs=None): + """ + + AOP切面模式: + 依赖AopModel装饰器,再在方法上加入@AopModel即可切入编程 + + + 优点: + + 当使用@AopModel时,内部函数将会逐级调用回调函数,执行循序是: + - func(*self.args, **self.kwargs) + - func(*self.args) + - func(**self.kwargs) + - func() + 这将意味着,如果你的参数传入错误时,AopModel依旧会遵循原始方法所使用的规则,最令人大跌眼镜的使用方法就是: + + def Before(**kwargs): + print('Before:', kwargs) + # 此处的Before方法未存在args参数,而使用@AopModel时却传入了args + @AopModel(before=Before,before_args=(0,1,2), before_kwargs={'1': '1'}) + def find_title_and_selects(self, **kwargs): + + print('function task', kwargs['uid']) + + _r = self.orm.find().where(index="<<100").end() + + print(_r) + + return _r + + 其中包含参数有: + before:切入时需要执行的函数 + + before_args:切入的参数 + 传入的列表或元组类型数据 + 如果是需要使用当前pojo中的内容时,传参格式为:(pojo.字段名) + 可扩展格式,例如需要传入字典 + + before_kwargs:切入的参数 -- 传入的字典数据 + + after:切出前需要执行的参数 + + after_args:切出的参数 + 传入的列表或元组类型数据 + 如果是需要使用当前pojo中的内容时,传参格式为:('self.字段名') + 可扩展格式,例如需要传入字典:('self.dict.key') + + after_kwargs:切出的参数 -- 传入的字典数据 + + + 执行流程: + + Before->original->After + + Before注意事项: + + 使用该参数时,方法具有返回值概不做处理,需要返回值内容可使用`global`定义一个全局字段用于保存数值 + + 当无法解析或者解析失败时m将使用pass关键字忽略操作 + + After注意事项: + + 使用该参数时,必须搭配至少一个result=None的kwargs存在于方法的形参中, + + 当original方法执行完成将把返回值固定使用result键值对注入到该函数中 + + 当无法解析或者解析失败时m将使用pass关键字忽略操作 + + + + Attributes: + + before:切入时需要执行的函数 + + after:切出前需要执行的参数 + + before_args:切入的参数 + 传入的列表或元组类型数据 + 如果是需要使用当前pojo中的内容时,传参格式为:(pojo.字段名) + 可扩展格式,例如需要传入字典 + + before_kwargs:切入的参数 -- 传入的字典数据 + + after_args:切出的参数 + 传入的列表或元组类型数据 + 如果是需要使用当前pojo中的内容时,传参格式为:('self.字段名') + 可扩展格式,例如需要传入字典:('self.dict.key') + + after_kwargs:切出的参数 -- 传入的字典数据 + + + """ + # 得到对象组 + aop_obj = AopModelObject(before, after, + before_args, before_kwargs, + after_args, after_kwargs) + + def base_func(func): + aop_obj.set_func(func) + + def _wrapper_(*args, **kwargs): + aop_obj.set_args(*args, **kwargs) + return aop_obj.start() + + return _wrapper_ + + return base_func diff --git a/CACodeFramework/anno/aop.py b/CACodeFramework/anno/aop.py new file mode 100644 index 0000000000000000000000000000000000000000..4394c0490acb916ec8677db6af18898a9ae8ab8a --- /dev/null +++ b/CACodeFramework/anno/aop.py @@ -0,0 +1,247 @@ +import types + +from CACodeFramework.opera.CompulsoryRun import Compulsory + + +class AopModelObject(object): + """ + 此类为AopModel提供所有操作 + """ + + def __init__(self, before=None, after=None, + before_args=None, before_kwargs=None, + after_args=None, after_kwargs=None): + # wraps(func)(self) + # self.func = func + # 初始化所有字段 + self.__before_func__ = before + self.__before_args_data__ = before_args + self.__before_kwargs_data__ = before_kwargs + + self.__after_func__ = after + self.__after_args_data__ = after_args + self.__after_kwargs_data__ = after_kwargs + + def set_func(self, func): + self.func = func + + def set_args(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + + def start(self): + """ + 主操作 + """ + + # self.func = args[0] + self.init_fields() + # wraps(self.func)(self) + self.init_attr() + + # 解析参数需要 + # self.before_parse() + # 执行before操作 + self.before_run() + # 执行原始数据 + result = self.original_func() + # after解析 + # self.after_parse(result) + # after操作 + self.after_run(result) + # 返回原始数据 + return result + + def init_fields(self): + # 定义名称规则 + self.after = 'after' + self.after_args = 'after_args' + self.after_kwargs = 'after_kwargs' + + self.before = 'before' + self.before_args = 'before_args' + self.before_kwargs = 'before_kwargs' + + self.__after__ = '__after_func__' + self.__after_args__ = '__after_args__' + self.__after_kwargs__ = '__after_kwargs__' + + # 得到before参数的名称 + self.__before_name__ = self.format_name(self.before) + self.__before_args_name__ = self.format_name(self.before_args) + self.__before_kwargs_name__ = self.format_name(self.before_kwargs) + + # 得到after参数的名称 + + self.__after_name__ = self.format_name(self.__after__) + self.__after_args_name__ = self.format_name(self.__after_args__) + self.__after_kwargs_name__ = self.format_name(self.__after_kwargs__) + + def __get__(self, instance, cls): + if instance is None: + return self + else: + return types.MethodType(self, instance) + + def format_name(self, name): + """ + 格式化名称字符串 + """ + return '{}{}'.format(name, self.func.__name__) + + def setters(self, i1, i2, i3, k1, v1, k2, v2, k3, v3): + """ + 批量设置 + """ + if i1 in self.__dict__.keys(): + setattr(self, v1, self.__dict__[k1]) + if i2 in self.__dict__.keys(): + setattr(self, v2, self.__dict__[k2]) + if i3 in self.__dict__.keys(): + setattr(self, v3, self.__dict__[k3]) + + def init_attr(self): + """ + 初始化cls下的字段 + 通过使用setters下的setter()功能批量解析是否需要before或者after操作 + """ + + self.setters( + i1=self.before, + i2=self.before_args, + i3=self.before_kwargs, + k1=self.before, + k2=self.before_args, + k3=self.before_kwargs, + v3=self.__before_kwargs_name__, + v1=self.__before_name__, + v2=self.__before_args_name__, + ) + + self.setters( + i1=self.after, + i2=self.after_args, + i3=self.after_kwargs, + k1=self.after, + k2=self.after_args, + k3=self.after_kwargs, + v1=self.__after_name__, + v2=self.__after_args_name__, + v3=self.__after_kwargs_name__ + ) + + # def before_parse(self): + # """ + # 解析before参数的方法需要什么参数类型 + # """ + # __before_func__ = None + # __before_args_data__ = None + # __before_kwargs_data__ = None + # # 如果包含切入函数的字段 + # if hasattr(self, self.__before_name__): + # # 得到参数的名称 + # __before_func__ = getattr(self, self.__before_name__) + # if hasattr(self, self.__before_args_name__) and hasattr(self, self.__before_kwargs_name__): + # + # __before_args_data__ = getattr(self, self.__before_args_name__) + # __before_kwargs_data__ = getattr(self, self.__before_kwargs_name__) + # + # elif hasattr(self, self.__before_args_name__): + # __before_args_data__ = getattr(self, self.__before_args_name__) + # + # elif hasattr(self, self.__before_kwargs_name__): + # __before_kwargs_data__ = getattr(self, self.__before_kwargs_name__) + # + # # 批添加方法、参数和键值对 + # self.__before_func__ = __before_func__ + # self.__before_args_data__ = __before_args_data__ + # self.__before_kwargs_data__ = __before_kwargs_data__ + + def before_run(self): + """ + 执行before方法 + """ + if self.__before_func__ and self.__before_args_data__ and self.__before_kwargs_data__: + self.__before_func__(*self.__before_args_data__, **self.__before_kwargs_data__) + elif self.__before_func__ and self.__before_args_data__: + self.__before_func__(*self.__before_args_data__) + elif self.__before_func__ and self.__before_kwargs_data__: + self.__before_func__(**self.__before_kwargs_data__) + elif self.__before_func__: + self.__before_func__() + else: + pass + + # def after_parse(self, result): + # """ + # 解析追加方法 + # :param result:原始方法返回的值 + # """ + # __after_func__ = None + # __after_args_data__ = None + # __after_kwargs_data__ = {} + # # 如果包含切入函数的字段 + # if hasattr(self, self.__after_name__): + # # 得到参数的名称 + # __after_func__ = getattr(self, self.__after_name__) + # if hasattr(self, self.__after_args_name__) and hasattr(self, self.__after_kwargs_name__): + # + # __after_args_data__ = getattr(self, self.__after_args_name__) + # __after_kwargs_data__ = getattr(self, self.__after_kwargs_name__) + # + # elif hasattr(self, self.__after_args_name__): + # __after_args_data__ = getattr(self, self.__after_args_name__) + # + # elif hasattr(self, self.__after_kwargs_name__): + # __after_kwargs_data__ = getattr(self, self.__after_kwargs_name__) + # + # # 批添加方法、参数和键值对 + # self.__after_func__ = __after_func__ + # self.__after_args_data__ = __after_args_data__ + # __after_kwargs_data__.update({'result': result}) + # self.__after_kwargs_data__ = __after_kwargs_data__ + + def after_run(self, result): + """ + 执行after方法 + """ + if self.__after_kwargs_data__ is None: + self.__after_kwargs_data__ = {} + + self.__after_kwargs_data__.update({'result': result}) + if self.__after_func__ and self.__after_args_data__ and self.__after_kwargs_data__: + self.__after_func__(*self.__after_args_data__, **self.__after_kwargs_data__) + elif self.__after_func__ and self.__after_args_data__: + self.__after_func__(*self.__after_args_data__) + elif self.__after_func__ and self.__after_kwargs_data__: + self.__after_func__(**self.__after_kwargs_data__) + elif self.__after_func__: + self.__after_func__() + else: + pass + + def original_func(self): + """ + 最后使用强制法返回函数执行的结果 + 使用四个try逐一抛出 + """ + return Compulsory.run_function(func=self.func, args=self.args, kwargs=self.kwargs) + # try: + # return self.func(*self.args, **self.kwargs) + # except TypeError as e: + # pass + # + # try: + # return self.func(*self.args) + # except TypeError as e: + # pass + # + # try: + # return self.func(**self.kwargs) + # except TypeError as e: + # pass + # + # try: + # return self.func() + # except TypeError as e: + # pass diff --git a/CACodeFramework/cache/__init__.py b/CACodeFramework/cache/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d415e1d44ab6ccb233d5fa4989f938d97139a825 --- /dev/null +++ b/CACodeFramework/cache/__init__.py @@ -0,0 +1,5 @@ +# -*- utf-8 -*- +# @Time: 2021/4/21 0:41 +# @Author: CACode +# @File: __init__.py +# @Software: PyCharm diff --git a/CACodeFramework/cacode/Factory.py b/CACodeFramework/cacode/Factory.py new file mode 100644 index 0000000000000000000000000000000000000000..a02642dff12e31181781319426a39cd2ec69473c --- /dev/null +++ b/CACodeFramework/cacode/Factory.py @@ -0,0 +1,96 @@ +import threading + +from CACodeFramework.cacode import Modes +from CACodeFramework.exception import e_fields +from CACodeFramework.opera.CompulsoryRun import Compulsory +from CACodeFramework.util.Log import CACodeLog +import importlib + + +class Factory(object): + _instance_lock = threading.Lock() + + def __init__(self, modules): + try: + self.modules = modules + except AttributeError: + CACodeLog.err(SyntaxError, e_fields.CACode_Factory_Error( + 'Please import the Pojo module first,请先设置导入modules模块')) + + self.module_names = {} + self.__base_init__() + + def __base_init__(self): + for package_name in self.modules: + base_module = str(package_name).split('.') + last_name = base_module[ + (len(base_module) - 1) if + len(base_module) > 0 else + CACodeLog.err(TypeError, + e_fields.CACode_Factory_Error( + 'The module cannot be found, perhaps the `instances` are not set,' + '找不到模块,也许是未设置`instances`') + ) + ] + # 将包导入 + self.module_names[last_name] = package_name + + @classmethod + def createInstance(cls, name: str, *args, **kwargs): + """ + 建造一个对象并将对象实例化 + + 使用方法: + + class MyFactory(Factory): + def __init__(self): + self.instances = [ + 'test.modules.Demo', + 'test.modules.BaseData', + ] + super().__init__() + + + if __name__ == '__main__': + ins = MyFactory.createInstance("Demo.DemoTable",kwargs={}) + print(ins) + + + + + :param name:类的名称,从配置的instances开始获得 + :param args:类的附属参数 + :param kwargs:类的附属参数 + """ + + # 使用单例模式初始化仓库 + this = Modes.Singleton.createFactory(cls) + + module_names = str(name).split('.') + first_module = module_names[0] + del module_names[0] + + assert len(module_names) > 0 + + import_module = importlib.import_module(this.module_names[first_module]) + + result = this.search_target(import_module, module_names) + + end_obj = Compulsory.run_function(func=result, args=args, kwargs=kwargs) + + return end_obj + + def search_target(self, module, target_names): + if len(target_names) == 0: + return module + # 当前的标记位置 + now_target = target_names[0] + del target_names[0] + if hasattr(module, now_target): + next_module = getattr(module, now_target) + return self.search_target(next_module, target_names) + else: + CACodeLog.err(ImportError, + e_fields.CACode_Factory_Error( + f'The package name does not exist in the search tree: {now_target}, please check ' + 'whether the package name is filled in correctly')) diff --git a/CACodeFramework/cacode/Modes.py b/CACodeFramework/cacode/Modes.py new file mode 100644 index 0000000000000000000000000000000000000000..5596b88c2871c921ad65c3f764761166e5a69c7c --- /dev/null +++ b/CACodeFramework/cacode/Modes.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- # +# ------------------------------------------------------------------ +# File Name: Modes +# Author: CACode +# Version: 1.2 +# Created: 2021/4/27 +# Description: Main Function: 所有用到的设计模式 +# 此文件内保存可外置的设计模式,用于让那些脑瘫知道我写的框架用了什么设计模式而不是 +# 一遍一遍问我这框架都用了什么设计模式、体现在哪里,我叼你妈 +# Class List: Singleton -- 单例模式 +# History: +#