def get_db_engine(self, key: EnumDbEngineType): """ Method for get db engine by key. If key is None or dont find engine return None :param key: for get db engine :return: db engine if found else return None """ RFContext.get_db_engine(key)
def add_db_engine(self, key: EnumDbEngineType, db_engine): """ Method for add db engine. This method only add db_engine if not None and key not None :param key: for db engine :param db_engine: to add :return: None """ RFContext.add_db_engine(key, db_engine)
def add_service(self, key, service): """ Method for add service. Only add if key is not none and service is not none and key dont find in service :param key: to add service :param service: to add :return: None """ RFContext.add_service(key, service)
def fetch_value_query(vo_class_instance, ar_data): """ Mehtod for fetch data in vo :param vo_class_instance: class for vo :param ar_data: to fetch :return: ar data for fetches values """ ar_response = [] if ar_data is not None: for data in ar_data: vo_instance = vo_class_instance() for key in data: old_instance = vo_instance ar_key_split = RFUtilsStr.split(key, FIELD_TABLE_SEPARATOR) if RFUtilsArray.is_not_empty(ar_key_split): for field in ar_key_split: # Not use default alias if field == DEFAULT_ALIAS: continue if RFUtilsBuilt.has_attr(old_instance, field): old_tpm_instance = RFUtilsBuilt.get_attr( old_instance, field) if old_tpm_instance is None: rf_column = RFContext.get_column_table( old_instance.__class__.__name__, field) if rf_column is not None and RFUtilsStr.is_not_emtpy( rf_column.join_vo_class_name ) is True: old_tpm_instance = RFContext.instance_vo( vo_class_name=rf_column. join_vo_class_name) RFUtilsBuilt.set_attr( old_instance, field, old_tpm_instance) old_instance = old_tpm_instance else: RFUtilsBuilt.set_attr( old_instance, field, data[key]) else: old_instance = old_tpm_instance else: break ar_response.append(vo_instance) return ar_response
def decorator_func(cls): if cls is not None: # Set table name for class if cls.__table_name__ is None: cls.__table_name__ = table_name # Set pk for field if cls.__ar_pk_fields__ is None: cls.__ar_pk_fields__ = ar_pk_fields # add table for context RFContext.add_table(cls) return cls
def decorator_func(cls): if cls is not None: # Add column for table in context RFContext.add_column_table( vo_class_name=cls.__name__, rf_column=RFColumn(name=name, column_name=column_name, join_table=join_table, join_vo_class_name=join_vo_class_name, join_table_column=join_table_column, insertable=insertable, updatable=updatable)) return cls
def get_service(self, key): """ Method for get service :param key: for get service :return: service if found by key else return None """ return RFContext.get_service(key)
def __init__( self, vo_class=None, db_engine_type: EnumDbEngineType = EnumDbEngineType.RF_MYSQL_POOL): """ Constructor for dao :param vo_class is a class vo data :param db_engine_type: default value is EnumDbEngineType.RF_MYSQL """ self.vo_class = vo_class self.db_engine_type = db_engine_type self._table_name = self.vo_class.__table_name__ self._columns_table = None self._fields_table = [] self._vo_class_name = self.vo_class.__name__ # Load fields for db engine if RFUtilsStr.is_not_emtpy( self._vo_class_name) and self.db_engine_type is not None: self._columns_table = RFContext.get_columns_table( self._vo_class_name) if self._columns_table is not None: for key_column in self._columns_table: column = self._columns_table[key_column] self._fields_table.append(Field(column.name))
def __init__(self, rf_py_web: RFPyWeb, path_requests: str = TEST_ROUTE, path_request_read: str = DEFAULT_PATH_REQUEST_READ, path_request_edit: str = DEFAULT_PATH_REQUEST_EDIT, path_request_delete: str = DEFAULT_PATH_REQUEST_DELETE, path_request_add: str = DEFAULT_PATH_REQUEST_ADD, path_request_list: str = DEFAULT_PATH_REQUEST_LIST, path_request_count: str = DEFAULT_PATH_REQUEST_COUNT, path_request_load_new: str = DEFAULT_PATH_REQUEST_LOAD_NEW, secure: bool = True, service_name: str = None): # Call super constructor RFBaseRoute.__init__(self, rf_py_web, path_requests=path_requests) self.path_request_read = path_request_read self.path_request_edit = path_request_edit self.path_request_delete = path_request_delete self.path_request_add = path_request_add self.path_request_list = path_request_list self.path_request_count = path_request_count self.path_request_load_new = path_request_load_new self.secure = secure self.service = None if RFUtilsStr.is_not_emtpy(service_name): self.service = RFContext.get_service(service_name)
def build_insert_query(vo_instance=None, dic_params_query={}): """ Method for insert build query :param table_name: for build insert query :param vo_instance: for build insert query :param dic_params_query: for build params :return: query for insert """ query_builder = "INSERT INTO " + vo_instance.__table_name__ + " " query_builder_columns = "" query_builder_values = "" dic_rf_columns = RFContext.get_columns_table( vo_instance.__class__.__name__) first: bool = True for key, rf_column in dic_rf_columns.items(): if rf_column.insertable: column_value = None if first is not True: query_builder_columns = query_builder_columns + " , " query_builder_values = query_builder_values + " , " column_name = rf_column.column_name if RFUtilsStr.is_not_emtpy( rf_column.join_table) else rf_column.name query_builder_columns = query_builder_columns + column_name if RFUtilsStr.is_not_emtpy(rf_column.join_table): join_instance = RFUtilsBuilt.get_attr( vo_instance, rf_column.name) if join_instance is not None: column_value = RFUtilsBuilt.get_attr( join_instance, rf_column.join_table_column) else: column_value = RFUtilsBuilt.get_attr( vo_instance, column_name) dic_params_query[column_name] = column_value query_builder_values = query_builder_values + " %(" + column_name + ")s " first = False # Build columns query_builder = query_builder + " ( " query_builder = query_builder + query_builder_columns query_builder = query_builder + " ) " # Build values query_builder = query_builder + " VALUES ( " query_builder = query_builder + query_builder_values query_builder = query_builder + " ) " return query_builder
def configure_transaction_manager(self, function_create_transaction=None, function_commit_transaction=None, function_rollback_transaction=None): """ Method for configure transaction manager :param function_create_transaction: this function must be params enum_transaction_type and params=None :param function_commit_transaction: this function must be params rf_transaction and params=None :param function_rollback_transaction: this function must be params rf_transaction and params=None :return: None """ rf_transaction_manager = RFContext.get_transaction_manager() rf_transaction_manager.function_create_transaction = function_create_transaction rf_transaction_manager.function_commit_transaction = function_commit_transaction rf_transaction_manager.function_rollback_transaction = function_rollback_transaction
def json_data_to_vo(self, vo_class_name, data): """ Mehtod for fetch data in vo :param vo_class_name: class name for vo :param ar_data: to fetch :return: ar data for fetches values """ vo_instance = RFContext.instance_vo(vo_class_name) if data is not None: for key, data_vo in data.items(): rf_column = RFContext.get_column_table(vo_class_name, key) if data_vo is not None and rf_column is not None: if isinstance(data_vo, Mapping): RFUtilsBuilt.set_attr(vo_instance, key, self.json_data_to_vo(rf_column.join_vo_class_name, data_vo)) elif isinstance(data_vo, float): RFUtilsBuilt.set_attr(vo_instance, key, Decimal(data_vo)) else: RFUtilsBuilt.set_attr(vo_instance, key, data_vo) return vo_instance
def __get_pk_filters__(self, ar_pks_values): """ Method for get pk filters :param ar_pks_values: to set in filters :return: array pk filters """ ar_filters = [] for index, pk in enumerate(self.vo_class.__ar_pk_fields__): rf_column = RFContext.get_column_table(self.vo_class.__name__, pk) if RFUtilsStr.is_not_emtpy(rf_column.join_table): ar_filters.append( Filter(field=pk + DOT + rf_column.column_name, value=ar_pks_values[index])) else: ar_filters.append(Filter(field=pk, value=ar_pks_values[index])) return ar_filters
def create_transaction( self, enum_transaction_type: EnumTransactionType = EnumTransactionType. PROPAGATED, params=None, db_engine_type: EnumDbEngineType = EnumDbEngineType.RF_MYSQL_POOL): """ Method for create transaction :param enum_transaction_type: type for transaction to create :param params :param db_engine_type engine for db :return: response for transaction create """ from rfpyweb.context.rf_context import RFContext # set default transaction propagated enum_transaction_type = enum_transaction_type if not None else EnumTransactionType.PROPAGATED response = None if self.function_create_transaction is not None: response = self.function_create_transaction( enum_transaction_type, params=params, db_engine_type=db_engine_type) else: rf_mysql_engine = RFContext.get_db_engine(db_engine_type) if db_engine_type == EnumDbEngineType.RF_MYSQL_POOL: response = RFTransaction(enum_transaction_type, transaction_database=rf_mysql_engine. connection.get_connection()) elif db_engine_type == EnumDbEngineType.RF_MYSQL: # No pool response = RFTransaction( enum_transaction_type, transaction_database=rf_mysql_engine.get_db()) return response
def build_joins_query( db_engine_type: EnumDbEngineType = EnumDbEngineType.RF_MYSQL_POOL, ar_joins_query=None, vo_class_name=None): """ Method for build join query :param db_engine_type: for build joins :param ar_joins_query: to build :param vo_class_name for get columns and field :return: build whit joins """ query_builder = "" if RFUtilsArray.is_not_empty(ar_joins_query): for join in ar_joins_query: if db_engine_type == EnumDbEngineType.RF_MYSQL or db_engine_type == EnumDbEngineType.RF_MYSQL_POOL: if RFUtilsStr.is_not_emtpy(join.custom_query_join): query_builder = query_builder + " " + join.custom_query_join else: join_type = " INNER JOIN " if join.join_type == EnumJoinType.RIGHT_JOIN or \ join.join_type == EnumJoinType.RIGHT_JOIN_FETCH: join_type = " INNER JOIN " elif join.join_type == EnumJoinType.LEFT_JOIN or \ join.join_type == EnumJoinType.LEFT_JOIN_FETCH: join_type = " LEFT JOIN " elif join.join_type == EnumJoinType.RIGHT_JOIN or \ join.join_type == EnumJoinType.RIGHT_JOIN_FETCH: join_type = " RIGHT JOIN " join_table = None join_table_field = None ar_join_split_values = RFUtilsStr.split( join.field, DOT) column_name = None alias_join = RFUtilsStr.replace( join.field, DOT, JOIN_ASSOCIATION_SEPARATOR) vo_class_name_join = vo_class_name len_split_values = len(ar_join_split_values) - 1 origin_alias_table = DEFAULT_ALIAS for index, join_split_value in enumerate( ar_join_split_values): rf_column = RFContext.get_column_table( vo_class_name=vo_class_name_join, column_name=join_split_value) vo_class_name_join = rf_column.join_vo_class_name join_table = rf_column.join_table join_table_field = rf_column.join_table_column column_name = rf_column.column_name if index != len_split_values: origin_alias_table = origin_alias_table + join_split_value query_builder = query_builder + " " + join_type + " " + join_table if RFUtilsStr.is_not_emtpy(join.alias): query_builder = query_builder + " AS " + join.alias query_builder = query_builder + " ON " + join.alias + "." + join_table_field \ + " = " + origin_alias_table + "." + column_name else: query_builder = query_builder + " AS " + DEFAULT_ALIAS + JOIN_ASSOCIATION_SEPARATOR + \ alias_join + " " query_builder = query_builder + " ON " + DEFAULT_ALIAS + JOIN_ASSOCIATION_SEPARATOR + \ alias_join + "." + join_table_field \ + " = " + origin_alias_table + "." + column_name return query_builder
def build_update_query(vo_instance=None, dic_params_query={}): """ Method for build update query :param vo_instance: to update :param dic_params_query: to set update query :return:to get build query """ query_builder = "UPDATE " + vo_instance.__table_name__ + " " dic_rf_columns = RFContext.get_columns_table( vo_instance.__class__.__name__) first: bool = True for key, rf_column in dic_rf_columns.items(): if rf_column.updatable: column_value = None if first is not True: query_builder = query_builder + " , " else: query_builder = query_builder + " SET " column_name = rf_column.column_name if RFUtilsStr.is_not_emtpy( rf_column.join_table) else rf_column.name if RFUtilsStr.is_not_emtpy(rf_column.join_table): join_instance = RFUtilsBuilt.get_attr( vo_instance, rf_column.name) if join_instance is not None: column_value = RFUtilsBuilt.get_attr( join_instance, rf_column.join_table_column) else: column_value = RFUtilsBuilt.get_attr( vo_instance, column_name) query_builder = query_builder + " " + column_name + " = " dic_params_query[column_name] = column_value query_builder = query_builder + " %(" + column_name + ")s " first = False query_builder = query_builder + " WHERE " first: bool = True for pk in vo_instance.__ar_pk_fields__: if first is not True: query_builder = query_builder + " AND " column_value = None rf_column = RFContext.get_column_table( vo_instance.__class__.__name__, pk) column_name = rf_column.column_name if RFUtilsStr.is_not_emtpy( rf_column.join_table) else rf_column.name if RFUtilsStr.is_not_emtpy(rf_column.join_table): join_instance = RFUtilsBuilt.get_attr(vo_instance, rf_column.name) if join_instance is not None: column_value = RFUtilsBuilt.get_attr( join_instance, rf_column.join_table_column) else: column_value = RFUtilsBuilt.get_attr(vo_instance, column_name) query_builder = query_builder + " " + column_name + " = " dic_params_query["keyPK_" + pk] = column_value query_builder = query_builder + " %(" + "keyPK_" + pk + ")s " first = False return query_builder
def wrapper_func(self, *args, **kwargs): rf_transaction = None transaction_propagated_created = False try: time_ns = time.time_ns() if APP_ENABLE_LOG_TRANSACTION_DECORATOR: RFUtilsLogger.debug("$$Transaction type: " + str(enum_transaction_type)) # EnumTransactionType.PROPAGATED if enum_transaction_type == EnumTransactionType.PROPAGATED: if 'rf_transaction' not in kwargs: rf_transaction = RFContext.get_transaction_manager( ).create_transaction( enum_transaction_type=EnumTransactionType. PROPAGATED_CREATED) kwargs['rf_transaction'] = rf_transaction transaction_propagated_created = True else: rf_transaction = kwargs['rf_transaction'] # EnumTransactionType.REQUIRED_NEW elif enum_transaction_type == EnumTransactionType.REQUIRED_NEW: rf_transaction = RFContext.get_transaction_manager( ).create_transaction( enum_transaction_type=enum_transaction_type) kwargs['rf_transaction'] = rf_transaction # EnumTransactionType.REQUIRED_NEVER elif enum_transaction_type == EnumTransactionType.REQUIRED_NEVER and 'rf_transaction' not in kwargs: kwargs['rf_transaction'] = None if APP_ENABLE_LOG_TRANSACTION_DECORATOR: time_ns_create_transaction = time.time_ns() - time_ns RFUtilsLogger.debug("$$Time create transaction ns: " + str(time_ns_create_transaction) + ", ms " + str(time_ns_create_transaction / 1000000)) # Execute method response = f(self, *args, **kwargs) # commit transaction if necessary if transaction_propagated_created is True or enum_transaction_type == EnumTransactionType.REQUIRED_NEW: RFContext.get_transaction_manager().commit(rf_transaction) if APP_ENABLE_LOG_TRANSACTION_DECORATOR: time_ns = time.time_ns() - time_ns RFUtilsLogger.debug( "$$Time execute transaction in in function " + str(f.__name__) + ", for class " + str(self) + ", ns: " + str(time_ns) + ", ms " + str(time_ns / 1000000)) return response except Exception as ex: # If transaction is not none execute rollback if rf_transaction is not None: RFContext.get_transaction_manager().rollback( rf_transaction) if APP_ENABLE_LOG_TRANSACTION_DECORATOR: RFUtilsLogger.debug("$$Error in function " + str(f.__name__) + ", for class " + str(self)) RFUtilsLogger.debug("$$Error in Transaction type: " + str(enum_transaction_type)) RFUtilsLogger.debug("$$Error transaction decorator " + str(ex)) raise ex
def __init__( self, import_name, static_url_path=None, static_folder="static", static_host=None, host_matching=False, subdomain_matching=False, template_folder="templates", instance_path=None, instance_relative_config=False, root_path=None, security_check_request_function=None, security_auth_mode: EnumSecurityAuthMode = EnumSecurityAuthMode.JWT ): """ Constructor for web application. This class extends Flask for build lightweight applications :param import_name: the name of the application package :param static_url_path: can be used to specify a different path for the static files on the web. Defaults to the name of the `static_folder` folder. :param static_folder: The folder with static files that is served at ``static_url_path``. Relative to the application ``root_path`` or an absolute path. Defaults to ``'static'``. :param static_host: the host to use when adding the static route. Defaults to None. Required when using ``host_matching=True`` with a ``static_folder`` configured. :param host_matching: set ``url_map.host_matching`` attribute. Defaults to False. :param subdomain_matching: consider the subdomain relative to :data:`SERVER_NAME` when matching routes. Defaults to False. :param template_folder: the folder that contains the templates that should be used by the application. Defaults to ``'templates'`` folder in the root path of the application. :param instance_path: An alternative instance path for the application. By default the folder ``'instance'`` next to the package or module is assumed to be the instance path. :param instance_relative_config: if set to ``True`` relative filenames for loading the config are assumed to be relative to the instance path instead of the application root. :param root_path: Flask by default will automatically calculate the path to the root of the application. In certain situations this cannot be achieved (for instance if the package is a Python 3 namespace package) and needs to be manually defined. :param security_check_request_function: function for execute extra check validation request function. First argument is rf_py_web application, second argument is path for request, third argument is the request :param security_auth_mode: Mode for login and secure path request. For default value is JWT """ # Call super constructor from Flask Flask.__init__( self, import_name, static_url_path=static_url_path, static_folder=static_folder, static_host=static_host, host_matching=host_matching, subdomain_matching=subdomain_matching, template_folder=template_folder, instance_path=instance_path, instance_relative_config=instance_relative_config, root_path=root_path ) # Function for check security self.security_check_request_function = security_check_request_function # Mode security # if is none default jwt self.security_auth_mode = security_auth_mode if not None else EnumSecurityAuthMode.JWT # Call this for init context RFContext.get_transaction_manager() # Config error handler self.__config_error_handler__() # Config log self.__config_logger__() # Config cors self.__config_cors__()
def build_select_query( ar_fields_query=None, ar_joins_query=None, db_engine_type: EnumDbEngineType = EnumDbEngineType.RF_MYSQL_POOL, ar_default_fields_table=None, vo_class_name=None): """ Method for build select query :param ar_fields_query: to get in query :param ar_joins_query: joins for query. Is necessary if has join is fetch :param db_engine_type for database :param ar_default_fields_table for table :param vo_class_name for query :return: select query """ query_builder = "" # Engine EnumDbEngineType.RF_MYSQL if db_engine_type == EnumDbEngineType.RF_MYSQL or db_engine_type == EnumDbEngineType.RF_MYSQL_POOL: query_builder = " SELECT " # Load selected fields if RFUtilsArray.is_not_empty(ar_fields_query): first = True for field in ar_fields_query: if not first: query_builder = query_builder + " , " if RFUtilsStr.is_not_emtpy(field.alias_table): query_builder = query_builder + " " + field.alias_table.strip( ) + "." else: query_builder = query_builder + " " + DEFAULT_ALIAS + "." ar_field = RFUtilsStr.split(field.name, DOT) field_name = field.name field_name_alias = field.name rf_column = None old_vo_class_name = vo_class_name for field_ar in ar_field: rf_column = RFContext.get_column_table( vo_class_name=old_vo_class_name, column_name=field_ar) if rf_column is not None and RFUtilsStr.is_not_emtpy( rf_column.join_table): old_vo_class_name = rf_column.join_vo_class_name field_name = rf_column.column_name field_name_alias = field_name_alias + DOT + rf_column.join_table_column else: break query_builder = query_builder + field_name if RFUtilsStr.is_not_emtpy(field.alias_field): query_builder = query_builder + " " + field.alias_field.strip( ) + " " else: query_builder = query_builder + " " + \ RFUtilsStr.replace(field_name_alias, DOT, FIELD_TABLE_SEPARATOR) + " " first = False # Load all fields elif RFUtilsArray.is_not_empty(ar_default_fields_table): first = True for field in ar_default_fields_table: if not first: query_builder = query_builder + " , " rf_column = RFContext.get_column_table( vo_class_name=vo_class_name, column_name=field.name) if RFUtilsStr.is_empty(rf_column.join_table): query_builder = query_builder + " " + DEFAULT_ALIAS + "." + field.name.strip() + " " + \ RFUtilsStr.replace(field.name.strip(), DOT, FIELD_TABLE_SEPARATOR) + " " else: query_builder = query_builder + " " + DEFAULT_ALIAS + "." + rf_column.join_table_column + " " + \ RFUtilsStr.replace(field.name.strip(), DOT, FIELD_TABLE_SEPARATOR) + rf_column.join_table_column + " " first = False # Check joins for get data if RFUtilsArray.is_not_empty(ar_joins_query): # For each join add if join fetch ar_joins_fetch = [ EnumJoinType.INNER_JOIN_FETCH, EnumJoinType.LEFT_JOIN_FETCH, EnumJoinType.RIGHT_JOIN_FETCH ] for join in ar_joins_query: # Add join if fetch for join table. Only join for non alias table by the moment if join.join_type in ar_joins_fetch: old_vo_class_name = vo_class_name ar_join_fields = RFUtilsStr.split(join.field, DOT) for join_field in ar_join_fields: rf_column = RFContext.get_column_table( vo_class_name=old_vo_class_name, column_name=join_field) if rf_column is not None and RFUtilsStr.is_not_emtpy( rf_column.join_table) is True: old_vo_class_name = rf_column.join_vo_class_name ar_rf_columns = RFContext.get_columns_table( old_vo_class_name) field_alias = RFUtilsStr.replace( join.field, DOT, FIELD_TABLE_SEPARATOR) alias = DEFAULT_ALIAS + JOIN_ASSOCIATION_SEPARATOR + RFUtilsStr.replace( join.field, DOT, JOIN_ASSOCIATION_SEPARATOR) for key_rf_column_apply in ar_rf_columns: rf_column_apply = ar_rf_columns[ key_rf_column_apply] query_builder = query_builder + " , " column_name = rf_column_apply.name if RFUtilsStr.is_empty( rf_column_apply.join_table ) else rf_column_apply.column_name query_builder = query_builder + " " + alias + "." + column_name + " " + \ field_alias + FIELD_TABLE_SEPARATOR + column_name query_builder = query_builder + " " return query_builder