B
    JDb:                 @   s  d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlmZ ddlmZmZmZmZ d	Zd
ZdZdd Ze Zdd Zdd Zdd Zdd Zdd Zd,ddZdd ZedfddZdd Z d d! Z!d-d"d#Z"d.d$d%Z#d&d' Z$d(d) Z%d*d+ Z&dS )/    )print_functionN)settings)cache)InternalErrorOperationalError)etree   )	fetch_all	fetch_oneexecute
multi_execTi:	 Fc              C   sn   d} dt jd d  kr d} nJdt jd d  kr<d} n.t j dkrPd} nd	t jd d  krjd	} | S )
N Z
sql_serverdefaultZENGINEZ	sqlservermysql)
postgresqlr   oracle)r   Z	DATABASESlowerZDATABASE_ENGINE)Zdb_name r   )G:\easytimepro\master/mysite/sql_utils.pyget_curr_db_engine_name   s    r   c           
   C   s   d} d}d}d}d}t dkr d}z`y(t } |  }|| | }d}W n2 tk
r| } zt  t|}W dd}~X Y nX W d|r|	  | r| 	  ||fS )z~
        Test database connection
        return:
        res: True:normal, False:abnormal
        msg: Exception message
    NFr   zselect 1)r   r   zselect 1 from dualT)
curr_db_engine_namegetConncursorr   fetchall	Exception	traceback	print_excstrclose)conncurresmsgZtest_sqler   r   r   	test_conn.   s*    
r$   c          
   C   s   ddl m} d}d}d}tr*|d|  d tr6t| S zy$t }| }||  | }W nl t	t
fk
rz   t  Y nP tk
r } z2t  t|ddkr|d| d t  W dd}~X Y nX W d|r|  |r|  |S )aU  
        dbutils pool connection
        Only can execute query statement, otherwise raise exception
        Only fetch the first one query result

        @parm: query sql statemnet
        @return:
            []: query result is null
            None: sql query failed, rasie exception
            Two-dimensional list: normal result
    r   )cprintNz"p_query_one()=============>sql: %sredzInvalid object namez/>>>>>>>Database Error  Re-Connect>>>>>%s>>>>>>>)mysite._utilsr%   develop_modelDJANGOr
   r   r   r   Zfetchoner   r   reConnr   r   r   r   findr   )sqlr%   r   r    r!   r#   r   r   r   p_query_oneM   s2    

r-   c          
   C   s   ddl m} d}d}d}tr*|d|  d tr6t| S zy$t }| }||  | }W nt t	t
fk
r   t  t  Y nP tk
r } z2t  t|ddkr|d| d t  W dd}~X Y nX W d|r|  |r|  |S )	a'  
        dbutils pool connection
        Only can execute query statement, otherwise raise exception

        @parm: query sql statemnet
        @return:
            []: query result is null
            None: sql query failed, rasie exception
            Two-dimensional list: normal result
    r   )r%   Nzp_query()=============>sql: %sgreyzInvalid object namez/>>>>>>>Database Error  Re-Connect>>>>>%s>>>>>>>r&   )r'   r%   r(   r)   r	   r   r   r   r   r   r   r*   r   r   r   r   r+   r   )r,   r%   r   r    r!   r#   r   r   r   p_queryu   s4    
r/   c          
   C   s  ddl m} d}d}d}tr*|d|  d tr6t| S zy,t }| }||  |jj}|	  W n\ t
k
r } z>|r|  t  t|ddkr|d| d t  W dd}~X Y nX W d|d	krt \}}|st  d
}|r|  |r|  |S )aG  
        dbutils pool connection
        Execute database operation statement, including update, insert, delete

        @parm: operation sql statemnet
        @return:
            None: sql execute failed, rasie exception
            Number: effect record number
            -2: execute failed caused by connection failed
    r   )r%   Nz p_execute()=============>sql: %sr.   zInvalid object namez/>>>>>>>Database Error  Re-Connect>>>>>%s>>>>>>>r&   )r'   r%   r(   r)   r   r   r   Z_cursorZrowcountZcommitr   Zrollbackr   r   r   r+   r*   r$   r   )r,   r%   r   r    r!   r#   Zretr"   r   r   r   	p_execute   s>    

r2   c             C   sD   ddl m} tr|d|  d tr@yt| S  tk
r>   dS X dS )a7  
        dbutils pool connection
        Execute multiple database operation statements, including update, insert, delete

        @parm: operation sql statemnets, type: list
        @return:
            (flag,res):
            flag<True or False>: True means all statements execute successfully
            res<list> : The number of rows affected by each sql statement execution.
                        If the execution failed, it can be judged which sql statement execute failed.
                        If you encounter a database disconnection, return [-2,]
    r   )r%   z!p_mutiexec()=============>sql: %sr&   FN)r'   r%   r(   r)   r   r   )Zsql_listr%   r   r   r   
p_mutiexec   s    r3   c             C   s8   g }dd t jD }| r&| |kr&| g}dd |D }|S )Nc             S   s&   g | ]}| d dkr|d dqS )zmysite.r   r   )r+   replace).0ir   r   r   
<listcomp>   s    z$get_sql_file_dir.<locals>.<listcomp>c             S   s   g | ]}d | qS )zmysite/%s/sqlr   )r5   appr   r   r   r7      s    )r   ZINSTALLED_APPS)r8   Zfile_dir_listZapp_listr   r   r   get_sql_file_dir   s    r9   c             C   sZ   ddl m} g }x2| D ]*}dtj||}tj|r|| qW t	rV|sV|dd |S )z
        @params:
            dir_list: type<list> sql xml file dir
            sqlfile: type<str> sql xml file name
        @return: type<list> xml file path
    r   )r%   z{0}/{1}/{2}.xmlz8get_sql_file()========> can't find specific sql xml filer.   )
r'   r%   formatr   ZAPP_HOMEospathexistsappendr(   )Zdir_listZsqlfiler%   Zsql_xml_filesfile	file_pathr   r   r   get_sql_file   s    

rA   c             C   s   d}x| D ]}t j|r
t|}|r6d||f }nd| }||}|rX|d }P q
|rjd|df }ndd }||}|r
|d }P q
W |S )a~  
        @desc: get specific sql statement from sql xml
            If can't find specific sql statement with db_engine, will return default node
        @params:
            sql_files: type<list>, list of sql files' path
            engine_name: type<str> , database engine name
            sql_id: type(str), sql tag id of sql statement
        @return: type<Ele> sql element
    Nz-/sqlgroup/sql[@id='%s']/content[@engine='%s']z#/sqlgroup/sql/content[@engine='%s']r   r   )r;   r<   r=   r   parsexpath)Z	sql_filesengine_nameZsql_idsql_elefr#   Zcontent_expr   r   r   get_sql_ele_content   s&    




rG   c             C   s&   t }t|}t|| }t|||}|S )z(
        get sql statement xml node
    )r   r9   rA   rG   )sqlfilenamesqlidr8   rD   Z
config_dirZsql_filerE   r   r   r   get_sql_ele"  s
    
rJ   c             C   sX   i }| j  dddd}| d}x$|D ]}|j  ||jd  < q.W ||dS )z
        convert sql element to one dictionary
        format:
        {
            "sql_text": content,
            "part":{
                   "id1": part_content1,
                   "id2": part_content2
            }
        }
    z
	z  
partid)sql_textrL   )textstripr4   rC   Zattrib)rE   rL   rN   part_elepr   r   r   convert_ele_to_dict-  s    

rS   c             C   st  |dkri }|dkri }i }| d }| d }|r8|}n8x|  D ]\}}	d||< t|	tsb|	g}	x|	D ]}
|
|krh||
 }y ||  | d | 7  < W qh tk
r } zd|
t|d }t|W dd}~X Y qh tk
r   t  Y qhX qhW qBW |	| y|| }W n\ tk
rN } zdd	t|i }t|W dd}~X Y n" tk
rn   d}t  Y nX |S )
ue  
        @desc:根据节点 以及相关的参数,获取sql语句
        @params:
            ele_dict: type<dict> sql 的内容和part 组成的字典
            params: type<dict>,  key 为  sql语句主体 和part主体 中要格式化的内容,value 为要替换的值
            id_part: type<dict>  key 为 sql 语句主体中需要 格式化 的内容,value 为 要格式化的part标签中的 id值 ,like {"aa":"bb"} or {"aa":["bb","cc",]}
            only_content : 如果设置为True,则直接返回 xml中的content 内容,不会进行参数匹配
        @return: type<str> 完整的sql语句
    NrL   rN   r    zbget_sql_by_dict()========>parameter error:
	 id--%(val)s--<part>not exist this parameter[%(msg)s] )valr"   zYget_sql_by_dict()========>parameter error:
	 <content>not exist this parameter [%(msg)s] r"   )
items
isinstancelistrP   KeyErrorr   r   r   r   update)Zele_dictparamsid_partonly_contentrL   Z	part_dictrN   r,   kvrU   rQ   r#   Z
except_strr   r   r   get_sql_by_dictA  sF    


 
r`   c          	   C   s   |dkri }|dkri }ddl m} trZ|dt| t|t|t|t|t|f d d}y`d| ||f }t|}	|	st| ||}
t|
}	t||	t	 ntr|dd t
|	|||}W n tk
r   t  Y nX tr|d	| d |S )
u  
        @desc:获取sql语句内容
        @params:
            sqlfilename: type<str>指定存放sql语句的 xml文件名
            sqlid:type<str> xml文件中 sql 语句指定 sql标签的id
            app:type<str>  sql 语句所指定的app
            params: type<dict>,  key 为  sql语句主体 和part主体 中要格式化的内容,value 为要替换的值
            id_part: type<dict>  key 为 sql 语句主体中需要 格式化 的内容,value 为 要格式化的part标签中的 id值 ,like {"aa":"bb"} or {"aa":["bb","cc"]}
            only_content: 如果设置为True,则直接返回 xml中的content 内容,不会进行参数匹配
        @return: 根据条件筛选出来的 sql 语句
    Nr   )r%   zget_sql()===========> The params you given is:
                sqlfilename:%s
                sqlid:%s
                app:%s
                params:%s
                id_part:%s
                only_content:%s
        r.   r   z%s_%s_%sz0get_sql()===========>The sql is come from cache.z&get_sql()============> sql_result:
	%s)r'   r%   r(   r   r   getrJ   rS   setTIMEOUTr`   r   r   r   )rH   rI   r8   r[   r\   r]   r%   r,   keyZsql_dictrE   r   r   r   get_sqlq  s0    0

re   c          	   C   sr   yHt j|st | t j||}t|d}||  W d Q R X W n$ tk
rl   dd l}|	  Y nX d S )Nar   )
r;   r<   r=   makedirsjoinopenwriter   r   r   )ZwstrfilenameZwdirZm_filerF   r   r   r   r   	write_log  s    
rl   c             C   s:   d}dt j  d }dt j  | } t| || d S )Nzcalculate/deal_calculate_failedz%s.logz%Y_%mz	{0}: {1}
)datetimeZnowstrftimer:   rl   )dataZlog_dirrk   r   r   r   att_calculate_logger  s    rp   c             C   s^   ddl m} | rZt| \}}|sZx8| D ]0}t|}|d krFtd|  |dkr&d}|q&W d S )Nr   )DatabaseErrorzError sql -->%sr1   T)	django.dbrq   r3   r2   rp   )Z	batch_sqlrq   successr!   ZbsZdb_contion_errorr   r   r   att_batch_sql_execute  s    
rt   )N)NNF)NNNNF)'Z
__future__r   rm   r;   r   Zdjango.confr   Zdjango.core.cacher   rr   r   r   Zlxmlr   Zdjango_sql_utilsr	   r
   r   r   r)   rc   r(   r   r   r$   r-   r/   r2   r3   r9   rA   rG   rJ   rS   r`   re   rl   rp   rt   r   r   r   r   <module>   s8   ((-
	"
0
-