o k`A@snddlmZddlZddlZddlZddlmZddlmZm Z ddl Tddl m Z ddl mZmZmZddlmZmZdd lmZmZdd lmZdd lmZdd lmZmZmZdd lm Z z ddl!Z"ddl#Z!ddl!m$Z$m%Z%ddl#m&Z&m'Z'm(Z(m)Z)m*Z*Wn e+yeddgwe&e'e(edde(e,eddee"-de"j.Z/dZ0e1e"dsdZ2Z3zDe4e"j5j6d3Z2ej7dkre8d9de2:ej;Z3e3re3yYnw[2[3e?dZ@dd iZAd!ZBd.d"d#ZCd$d%ZDd&d'ZEd(d)ZFGd*d+d+eGZHGd,d-d-eeZIdS)/) find_libraryN)DistributionNotFound)PopenPIPE)*)Option)ConnectionBaseIDatabaseConnectorparse_connection_uri)ConnectionWrapperIterableCursor) get_pkginfolazy) close_fds)Markup)emptyexception_to_unicode to_unicode)_) DataErrorProgrammingError) register_typeUNICODEregister_adapterAsIs QuotedStringz psycopg2>=2.0 or psycopg2-binaryTraccCs tt|SN)rstr)markupr :/usr/lib/python3/dist-packages/trac/db/postgres_backend.py-s r"cCstdS)Nz'')r)rr r r!r".sversion libpq_versionrbntz \0( (?:/[^/\0]+)*/? libpq\.(?:so\.[0-9]+|[0-9]+\.dylib) )\0 zutf-8z\0libpq\.dll\0libpqz([/_%])int64bigint) r'rcs4dd|||||d}dfdd|DS)z*Quote the parameters and assemble the DSN.cSs*t|ts t|}d|ddddS)Nz'%s'\z\\'z\') isinstancerreplace)valuer r r!quoteVs zassemble_pg_dsn..quote)dbnameuserpasswordhostport c3s(|]\}}|rd||fVqdS)z%s=%sNr ).0namer0r1r r! ]sz"assemble_pg_dsn..)joinitems)pathr3r4r5r6dsnr r:r!assemble_pg_dsnTsr@cCsd|ddS)N"%s""z"")r/) identifierr r r!_quoteasrDcCs>|rt|d\}}|dkr||fSt|d\}}|||fSdS)Ni' d)divmod)vermajorminorpatchr r r!_version_tuplees rLcCs.|r t|ts t|}|rdtt|SdS)N.z (unknown))r.tuplerLr<mapr)rHr r r!_version_stringqs rPc@seZdZdZeedZeddddZddZ d d Z d d d d d ifd d Z ddZ d d d d d d ifddZ d d d d d ifddZd d d d d ifddZddZddZddZddZeddZd d!Zd S)"PostgreSQLConnectorzDatabase connector for PostgreSQL. Database URLs should be of the form: {{{ postgres://user[:password]@host[:port]/database[?schema=my_schema] }}} Ftrac pg_dump_pathpg_dumpz1Location of pg_dump for Postgres database backupscCsdt|j|_dS)Nz#server: (not-connected), client: %s)rP_client_version_postgresql_versionselfr r r!__init__szPostgreSQLConnector.__init__ccs dVdS)N)postgresr'r rWr r r!get_supported_schemess z)PostgreSQLConnector.get_supported_schemesNc Csv|ddt|||||||}t|j} t|j} |js9|jtkr/td| ttd} t| d| | f|_ d|_|S)NschemapubliczOPostgreSQL version is %(version)s. Minimum required version is %(min_version)s.)r# min_versionzserver: %s, client: %sT) setdefaultPostgreSQLConnectionrPserver_versionrUrequiredmin_postgresql_versionr TracErrorrV) rXr>logr3r4r5r6paramscnx server_ver client_vererrorr r r!get_connections$     z"PostgreSQLConnector.get_connectioncCstSr)psycopgrWr r r!get_exceptionsz"PostgreSQLConnector.get_exceptionsc Cs||||||||} | } | jr)| jdkr)| dt| j| d| jf|dur3ddlm}|D]} || D]} | | qr\rer3r4r5r6rfrgrptablestmtr r r!init_dbs   zPostgreSQLConnector.init_dbc Csh||||||||}|jr|jdkr|dt|jn|D] } |dt| q"|dS)Nr]zDROP SCHEMA %s CASCADEz DROP TABLE %s)rkr\rqrDget_table_namesrt) rXr>rer3r4r5r6rfrgrur r r! destroy_dbs  zPostgreSQLConnector.destroy_dbc Cs:||||||||}|} | d|jf| dS)NzU SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname=%s); r)rkrprqr\fetchone) rXr>rer3r4r5r6rfrgrpr r r! db_existss zPostgreSQLConnector.db_existsc cs2dt|jg}g}|jD]-}|j}t||}|jrd}t|jdkr/|j|jvr/|d7}| dt|j|fqt|jdkrZ| dt|jdd d d |jDf| d |d d |V|j D])}|j rtdnd}d|td|jd |jft|jd dd |jDfVqmdS)NzCREATE TABLE %s (SERIALr'z PRIMARY KEYz %s %sz" CONSTRAINT %s PRIMARY KEY (%s)_pk,cs|]}t|VqdSrrDr8colr r r!r;z-PostgreSQLConnector.to_sql..z, z ) UNIQUEzCREATE %s INDEX %s ON %s (%s)z %s_%s_idxrcsrrrrr r r!r;r) rDr9columnstype _type_mapgetauto_incrementlenkeyappendr<indicesunique)rXrusqlcoldefscolumnctypeindexrr r r!rss:     zPostgreSQLConnector.to_sqlccsxg}t|D]\}\}}t||}|t||kr$|||fq |r:dt|ddd|DfVdSdS)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. zALTER TABLE %s %sz, css$|] \}}dt||fVqdS)zALTER COLUMN %s TYPE %sNr)r8r9type_r r r!r;sz9PostgreSQLConnector.alter_column_types..N)sortedr=rrrrDr<)rXrur alterationsr9from_tor r r!alter_column_typess    z&PostgreSQLConnector.alter_column_typesc Cs|jjdd}t|\}}|di}|ddtj|d}|jddd d d g}d |vr8| d |d g|d|d}|r[| d|gd|vr[| dt |ddg| dd|dg|d7}| d||gtj } d|vrt |d| d<z t || ttd} Wnty} z ttd|jt| dd} ~ ww| d} | jdkrttdt| d tj|sttd!|S)"NrRdatabaserfr\r]r>z-Cz --insertsz-xz-Z8r3z-Ur5z-h/z-pr65432z-nrAz.gzz-fr4 PGPASSWORD)envstderrrUnable to run %(path)s: %(msg)sr>msgr'rzpg_dump failed: %(msg)s)rzNo destination file created)rconfigrr r_osr>basenamerSextendrenvironcopyrrrOSErrorrdrr communicate returncoderstripexists) rX dest_filedb_urlschemedb_prop db_paramsdb_nameargsr5rpeerrmsgr r r!backupsH         zPostgreSQLConnector.backupccsd|jfVdtfVdS)N PostgreSQLpsycopg2)rVpsycopg2_versionrWr r r!get_system_info s z#PostgreSQLConnector.get_system_infoc Csd}ttdrt}t |Str@ztt}|}Wt |Sty?}z|j dt |ddWYd}~t |Sd}~wwt |S)Nr$z3Exception caught while retrieving libpq's version%sT) traceback) hasattrrlr$_libpq_pathnamectypesCDLL PQlibVersion ExceptionrewarningrrL)rXr#librr r r!rU$s"     z#PostgreSQLConnector._client_versionc CsVz t|jdgttd}Wnty$}z ttd|jt|dd}~ww|dS)Nz --version)stdoutrrrr) rrSrrrrdrrr)rXrrr r r!_pgdump_version3s   z#PostgreSQLConnector._pgdump_version)__name__ __module__ __qualname____doc__ implementsr rbrrSrYr[rkrmrwryr{rsrrrrrUrr r r r!rQzs:      '  rQc@seZdZdZdZdddddifddZddZdd Zd d Zd d Z ddZ ddZ d/ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd/d)d*Zd+d,Zed-d.ZdS)0r`z"Connection wrapper for PostgreSQL.TNc Cs|dr |dd}d|vr|d}tt|||||}|d|dd|_|jdkrOz|d|jf| Wnt t fyN| Ynwt |||dS)Nrr'r5rr\r]ro) startswithrlconnectr@set_client_encodingrr\rprqrtrrrollbackr rY) rXr>rer3r4r5r6rfrgr r r!rYCs"      zPostgreSQLConnection.__init__cCst|j|jSr)r rgrprerWr r r!rpXszPostgreSQLConnection.cursorcCsd|t||fS)NzCAST(%s AS %s))rr)rXrrr r r!cast[szPostgreSQLConnection.castcGs d|S)Nz||)r<)rXrr r r!concat_s zPostgreSQLConnection.concatcCs"|d||||fdS)NzA ALTER TABLE %s DROP COLUMN IF EXISTS %s rqr1rXrurr r r! drop_columnbs z PostgreSQLConnection.drop_columncCs|d||dS)NzDROP TABLE IF EXISTS r)rXrur r r! drop_tablegszPostgreSQLConnection.drop_tablecCs|d|f}dd|DS)Nz SELECT column_name FROM information_schema.columns WHERE table_schema=current_schema() AND table_name=%s ORDER BY ordinal_position cSg|]}|dqSrr r8rowr r r! pz9PostgreSQLConnection.get_column_names..rqrXrurowsr r r!get_column_namesjsz%PostgreSQLConnection.get_column_namesidc Cs(|d||||f|dS)NzSELECT CURRVAL(%s)r)rqr1_sequence_namerzrXrprurr r r! get_last_idrs z PostgreSQLConnection.get_last_idcs,ddddD}tfdd|DS)NcSs g|] \}|dtd qS)N_id_seq)rr8r9r r r!rxs z;PostgreSQLConnection.get_sequence_names..a SELECT c.relname FROM pg_class c INNER JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = ANY (current_schemas(false)) AND c.relkind='S' AND c.relname LIKE %s ESCAPE '!' )z %!_id!_seqc3s |] }|vr|VqdSr)rxrrWr r!r;sz:PostgreSQLConnection.get_sequence_names..)rqr)rXseqsr rWr!get_sequence_namesws z'PostgreSQLConnection.get_sequence_namescCs|d}dd|DS)Nzm SELECT table_name FROM information_schema.tables WHERE table_schema=current_schema()cSrrr rr r r!rrz8PostgreSQLConnection.get_table_names..r)rXrr r r!rxs z$PostgreSQLConnection.get_table_namescCs|d|f}|ddS)Nz SELECT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=current_schema() AND table_name=%s) rrrr r r! has_tables zPostgreSQLConnection.has_tablecCdS)NzILIKE %s ESCAPE '/'r rWr r r!likernzPostgreSQLConnection.likecCs td|S)Nz/\1)_like_escape_resub)rXtextr r r! like_escape z PostgreSQLConnection.like_escapecCs|j}|ddS)NzSELECT 1)rgrprq)rXrpr r r!pings zPostgreSQLConnection.pingcCr)NzLIKE %s ESCAPE '/'r rWr r r! prefix_matchrnz!PostgreSQLConnection.prefix_matchcCs||dS)N%)r)rXprefixr r r!prefix_match_valuesz'PostgreSQLConnection.prefix_match_valuecCst|Srr)rXrCr r r!r1szPostgreSQLConnection.quotecCs`|}|d|jf|D] \}|d|q|}|D] }|d||q!|S)Nzu SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema=%s z ALTER SEQUENCE %s RESTART WITH 1z DELETE FROM )rprqr\fetchallrxr1)rXrpseq table_namesr9r r r! reset_tablessz!PostgreSQLConnection.reset_tablesc Cs4|d||||f||||fdS)Nz,SELECT SETVAL(%%s, (SELECT MAX(%s) FROM %s)))rqr1rrr r r!update_sequences z$PostgreSQLConnection.update_sequencecCs d||fS)Nz %s_%s_seqr rr r r!rrz#PostgreSQLConnection._sequence_namecCs t|jjSr)rLrgrarWr r r!ras z#PostgreSQLConnection.server_version)r)rrrrpoolablerYrprrrrrrrrxrrrrrrr1rrrrrar r r r!r`>s6    r`)NNNN)J ctypes.utilrrrre pkg_resourcesr subprocessrr trac.core trac.configr trac.db.apirr r trac.db.utilr r trac.utilr rtrac.util.compatrtrac.util.htmlrtrac.util.textrrrtrac.util.translationrrrlpsycopg2.extensionsrrrrrrr ImportErrorrr __version__rrr_f_matchopen_psycopg__file__r9searchencodereadVERBOSEgroup IGNORECASEAttributeErrorcompilerrrcr@rDrLrP ComponentrQr`r r r r!s                   E