o k`C@sddlZddlZddlZddlZddlmZddlmZmZddl m Z m Z m Z ddl mZmZddlmZmZmZddlmZmZddlmZmZmZdd lmZdd lmZmZe d Z!e d Z"zddl#m$Z%Wn e&yyddl'Z%Ynwe%j(Z)e%j)Z*e%j+Z,ee%-d de,Z.dZ/dZ0Gddde%j1Z2Gddde2Z3dddZ4ddZ5Gddde Z6GdddeeZ7ddZ8dd Z9d!d"Z:dS)#N)closing)ConfigurationError ListOption) Component TracError implements)ConnectionBaseIDatabaseConnector)TableColumnIndex)ConnectionWrapperIterableCursor) get_pkginfogetuserlazy)tag)_tag_z([/_%])z[*?\[]versionz%d.%d.%s)rr)rc@s&eZdZddZdddZddZdS) PyFormatCursorcOs6z ||g|Ri|WStjy|jwN)sqlite DatabaseErrorcnxrollback)selffunctionargskwargsr#8/usr/lib/python3/dist-packages/trac/db/sqlite_backend.py_rollback_on_error4s  z!PyFormatCursor._rollback_on_errorNcCs*|r |dt|}|tjj||pgS)N?)lenr%rCursorexecutersqlr!r#r#r$r*;s  zPyFormatCursor.executecCs.|sdS|dt|d}|tjj||S)Nr&r)r(r%rr) executemanyr+r#r#r$r-As  zPyFormatCursor.executemanyr)__name__ __module__ __qualname__r%r*r-r#r#r#r$r3s  rc@s6eZdZddZddZddZd dd Zd d ZdS) EagerCursorcCst||g|_d|_dSNr)r__init__rowspos)rconr#r#r$r3Qs  zEagerCursor.__init__cGs(tj|g|R}t||_d|_|Sr2)rr*fetchallr4r5)rr!resultr#r#r$r*Vs zEagerCursor.executecCs8z|j|j}Wn tyYdSw|jd7_|S)N)r4r5 IndexError)rrowr#r#r$fetchone\s zEagerCursor.fetchoneNcCs6|dur|j}|j|j|j|}|j|7_|Sr) arraysizer4r5)rnumr8r#r#r$ fetchmanyes zEagerCursor.fetchmanycCs |j|jd}t|j|_|Sr)r4r5r()rr8r#r#r$r7ms zEagerCursor.fetchallr)r.r/r0r3r*r<r?r7r#r#r#r$r1Ps  r1integer)intint64c csd|jg}g}|jD].}|j}t||}|jrd}nt|jdkr0|j|jvr0|d7}| d|j|fq t|jdkrM| dd |j| d |d d |V|j D]}|j rgd nd }d ||jd |j|jd |jfVq`dS)NzCREATE TABLE %s (zinteger PRIMARY KEYr9z PRIMARY KEYz %s %sz UNIQUE (%s),z, z ); UNIQUEz%CREATE %s INDEX %s_%s_idx ON %s (%s);r) namecolumnstypelower _type_mapgetauto_incrementr(keyappendjoinindicesunique)tabler,coldefscolumnctypeindexrRr#r#r$_to_sqlzs*       rXc@seZdZdZeedZeddddZdZ dd Z d d Z difd d Z ddZ ddifddZdifddZdifddZddZddZddZddZeddZdS) SQLiteConnectorzxDatabase connector for SQLite. Database URLs should be of the form: {{{ sqlite:path/to/trac.db }}} Fr extensionszPaths to [https://sqlite.org/loadext.html sqlite extensions]. The paths may be absolute or relative to the Trac environment. )docNcCs d|_dSr)errorrr#r#r$r3 zSQLiteConnector.__init__ccsRttkrtdtdtd|_n ttkrtddtd|_d|jr#dndfVdS) NzKSQLite version is %(version)s. Minimum required version is %(min_version)s.z%d.%d.%d)r min_versionz,Need at least PySqlite %(version)s or higherrrr9)sqlite_versionmin_sqlite_versionrsqlite_version_stringr\pysqlite_versionmin_pysqlite_versionr]r#r#r$get_supported_schemess z%SQLiteConnector.get_supported_schemesc Csbd|_|j|d<|dkr+z |jW|jSttjfy*t||||_Y|jSwt|||S)NTrZ:memory:)required _extensions memory_cnxcursorAttributeErrorrrSQLiteConnectionrpathlogparamsr#r#r$get_connections   zSQLiteConnector.get_connectioncCstSr)rr]r#r#r$get_exceptionszSQLiteConnector.get_exceptionsc sfdd}|dkre|rttd|dtj|}tj|s(t|tj |dt | ddd}t | }t|| d t|| d |||Wdn1s\wYd |_n"|||}t |  }|||Wdn1swY|dS) Ncs<|dur ddlm}|D]}|D]}||qq dS)Nr)schema)trac.db_defaultrvto_sqlr*)rlrvrSstmtr]r#r$ insert_schemas  z.SQLiteConnector.init_db..insert_schemarhz#Database already exists at %(path)srptimeouti')isolation_levelr| journal_mode synchronousDEFERRED) db_existsrrosrpdirnameexistsmakedirsrconnectrArLrrl_set_journal_modeset_synchronousr}rscommit) rrprvrqrrrzdirrrlr#r]r$init_dbs.        zSQLiteConnector.init_dbc Csp|dkr6tj|stj|jj|}zt|WdSty5}z|jtjkr*WYd}~dSd}~wwdS)Nrh) rrpisabsrPenvremoveOSErrorerrnoENOENT)rrprqrrer#r#r$ destroy_dbs  zSQLiteConnector.destroy_dbcCs tj|Sr)rrprror#r#r$rs zSQLiteConnector.db_existscCt|Sr)rXrrSr#r#r$rxzSQLiteConnector.to_sqlcCsFt|D]\}\}}t||t||kr td||fqdS)zYield SQL statements altering the type of one or more columns of a table. Type changes are specified as a `columns` dict mapping column names to `(from, to)` SQL type tuples. z+Conversion from %s to %s is not implementedr#)sorteditemsrKrLNotImplementedError)rrSrHrGfrom_tor#r#r$alter_column_typessz"SQLiteConnector.alter_column_typescCsddl}|jdd}z |d|d}Wn tyYnwtj|jj|dd}| ||tj |s?t t d|S)zlSimple SQLite-specific backup of the database. :param dest_file: Destination file basename rNtracdatabaser'zNo destination file created) shutilconfigrLrW ValueErrorrrprPrcopyrrr)r dest_filerdb_strdb_namer#r#r$backups    zSQLiteConnector.backupccsdtfVdtfVdS)NSQLitepysqlite)rdpysqlite_version_stringr]r#r#r$get_system_infos zSQLiteConnector.get_system_infocCs<g}|jD]}tj|stj|jj|}||q|Sr)rZrrprrPrrO)rrjextpathr#r#r$rjs    zSQLiteConnector._extensions)r.r/r0__doc__rr rirrZrkr3rgrsrtrrrrxrrrrrjr#r#r#r$rYs*    rYc@seZdZdZddgZedkZdifddZdd Zd d Z d d Z ddZ ddZ ddZ ddZd1ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd1d+d,Zd-d.Zd/d0ZdS)2rnzConnection wrapper for SQLite._active_cursors_eager)rrNc Csjd|_|dkr@t|tjsttd|dtj|}t|tjtj r0t|tjtj s@tt dt t t |dt|_t|dd}|dd d k|_tj|tjdtd k|d }|d g}t|d kr|d|D]}||qv|dt|} t| |dt| |dWdn1swYd|_t !|||dS)NrhzDatabase "%(path)s" not found.r{zyThe user %(user)s requires read _and_ write permissions to the database file %(path)s and the directory it is located in.)userrpr|g$@rleager)rrr9) detect_typesr}check_same_threadr|rZrTFr~rr)"rraccessF_OKrrrprR_OKW_OKrrcoderweakrefWeakKeyDictionaryrrArLrrrPARSE_DECLTYPESrbr(enable_load_extensionload_extensionrrlrrr}r r3) rrprqrrdbdirr|rrZextrlr#r#r$r3$sF         zSQLiteConnection.__init__cCs2|jttf|j}d|j|<||_t||jS)NT)rrlrr1rrrrqrrlr#r#r$rlJs  zSQLiteConnection.cursorcCs"|jD]}|q|jdSr)rcloserrrr#r#r$rPs  zSQLiteConnection.rollbackcCs0tdkrd|t||fS|dkrd|S|S)N)rrrzCAST(%s AS %s)rAz1*)rbrKrL)rrUrIr#r#r$castUs zSQLiteConnection.castcGs d|S)Nz||)rP)rr!r#r#r$concat^r^zSQLiteConnection.concatc s|}||vrc|}||g|d}|}|}||dfdd|D}} | d||f|t |D]} | | qI| d||||f|dSdS)N_oldrCc3s|]}|VqdSr)quote).0colr]r#r$ jsz/SQLiteConnection.drop_column..zO CREATE TEMPORARY TABLE %s AS SELECT * FROM %s zG INSERT INTO %s (%s) SELECT %s FROM %s ) get_column_names_get_table_schemaremove_columnsrrrPrlr* drop_tablerX) rrSrU column_names table_schema temp_table table_nametemp_table_name cols_to_copyrlr,r#r]r$ drop_columnas.         zSQLiteConnection.drop_columncCsZ|}tdkr!z |d||WdStjy YdSw|d||dS)N)rrrz DROP TABLE zDROP TABLE IF EXISTS )rlrbr*rrOperationalErrorrrSrlr#r#r$rxszSQLiteConnection.drop_tablecCsdd||DS)NcSg|]}|dqS)r9r#rr;r#r#r$ z5SQLiteConnection.get_column_names..)_get_table_inforr#r#r$rz!SQLiteConnection.get_column_namesidcCs|jSr) lastrowidrrlrSrUr#r#r$ get_last_idszSQLiteConnection.get_last_idcCsgSrr#r]r#r#r$get_sequence_namesruz#SQLiteConnection.get_sequence_namescCs|d}dd|DS)NzK SELECT name FROM sqlite_master WHERE type='table' cSr)rr#rr#r#r$rrz4SQLiteConnection.get_table_names..)r*)rr4r#r#r$get_table_namess z SQLiteConnection.get_table_namescCst||Sr)boolrrr#r#r$ has_tableszSQLiteConnection.has_tablecCstdkrdSdS)Nrr9rzLIKE %s ESCAPE '/'zLIKE %s)rbr]r#r#r$likeszSQLiteConnection.likecCstdkr td|S|S)Nrz/\1)rb_like_escape_resub)rtextr#r#r$ like_escapes zSQLiteConnection.like_escapecCsdS)NzGLOB %sr#r]r#r#r$ prefix_matchruzSQLiteConnection.prefix_matchcCstdd|dS)NcSsd|dS)Nz[%s]r)group)mr#r#r$sz5SQLiteConnection.prefix_match_value..*)_glob_escape_rer)rprefixr#r#r$prefix_match_valuerz#SQLiteConnection.prefix_match_valuecCrr)_quote)r identifierr#r#r$rrzSQLiteConnection.quotecCs,|}|}|D] }|d|q |S)NzDELETE FROM %s)rlrr*)rrl table_namesrGr#r#r$ reset_tabless zSQLiteConnection.reset_tablescCsdSrr#rr#r#r$update_sequencesz SQLiteConnection.update_sequencecCs$|}|d||t|S)NzPRAGMA table_info(%s))rlr*rlistrr#r#r$rsz SQLiteConnection._get_table_infoc Csd}g}||D](}|d}|d}|d}|dkr%|dkr%|g}d}nd}|t|||dq |} | d||| D]2}|d} |d} | d || d d | D} |durk| d rk| }qD|t| t | d qDt ||p|gd|S)Nr9rr@TF)rIrMzPRAGMA index_list(%s)zPRAGMA index_info(%s)cSr)rr#rr#r#r$rrz6SQLiteConnection._get_table_schema..sqlite_autoindex_)rR)rN) rrOr rlr*rr7 startswithr rr ) rrSrNrr;rUtype_pkrMrlrWrRrHr#r#r$rs0   z"SQLiteConnection._get_table_schema)r)r.r/r0r __slots__rbpoolabler3rlrrrrrrrrrrrrrrrrrrrr#r#r#r$rns2&    rncCsd|ddS)Nz`%s``z``)replace)rr#r#r$rsrcCs|sdS|}|dkrttd|d|dt||}|s+ttdtd|dp0d|kr>ttd |td dS) NOFFz8PRAGMA journal_mode `%(value)s` cannot be used in SQLite)valuezPRAGMA journal_mode = %sz9PRAGMA journal_mode isn't supported by SQLite %(version)sr`rrFzEPRAGMA journal_mode `%(value)s` isn't supported by SQLite %(version)s)rr)upperrrr*rr<rd)rlrr;r#r#r$rs$rcCs2|sdS|rtt|}|dt|dS)NzPRAGMA synchronous = %s)isdigitstrrAr*r)rlrr#r#r$rs  r);rrrer contextlibr trac.configrr trac.corerrr trac.db.apirr trac.db.schemar r r trac.db.utilr r trac.utilrrrtrac.util.htmlrtrac.util.translationrrcompilerrpysqlite2.dbapi2dbapi2r ImportErrorsqlite3sqlite_version_inforbrd version_inforerLrrcrfr)rr1rKrXrYrnrrrr#r#r#r$sV       %<