PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/local/lib64/perl5/DBD
Viewing File: /usr/local/lib64/perl5/DBD/MariaDB.pm
#!/usr/bin/perl use strict; use warnings; require 5.008_001; # just as DBI package DBD::MariaDB; use DBI; use DynaLoader(); our @ISA = qw(DynaLoader); our $VERSION = '1.23'; bootstrap DBD::MariaDB $VERSION; our $err = 0; # holds error code for DBI::err our $errstr = ""; # holds error string for DBI::errstr our $sqlstate = ""; # holds five character SQLSTATE code our $drh = undef; # holds driver handle once initialised my $methods_are_installed = 0; sub driver{ return $drh if $drh; my($class, $attr) = @_; $class .= "::dr"; # not a 'my' since we use it above to prevent multiple drivers $drh = DBI::_new_drh($class, { 'Name' => 'MariaDB', 'Version' => $VERSION, 'Err' => \$DBD::MariaDB::err, 'Errstr' => \$DBD::MariaDB::errstr, 'State' => \$DBD::MariaDB::sqlstate, 'Attribution' => "DBD::MariaDB $VERSION by Pali and others", }); if (!$methods_are_installed) { # for older DBI versions disable warning: method name prefix 'mariadb_' is not associated with a registered driver local $SIG{__WARN__} = sub {} unless eval { DBI->VERSION(1.640) }; DBD::MariaDB::db->install_method('mariadb_sockfd'); DBD::MariaDB::db->install_method('mariadb_async_result'); DBD::MariaDB::db->install_method('mariadb_async_ready'); DBD::MariaDB::st->install_method('mariadb_async_result'); DBD::MariaDB::st->install_method('mariadb_async_ready'); # for older DBI versions register our last_insert_id statement method if (not eval { DBI->VERSION(1.642) }) { # disable warning: method name prefix 'last_' is not associated with a registered driver local $SIG{__WARN__} = sub {}; DBD::MariaDB::st->install_method('last_insert_id'); } $methods_are_installed++; } $drh; } sub CLONE { undef $drh; } sub parse_dsn { my ($class, $dsn) = @_; my $hash = {}; my($var, $val); if (!defined($dsn)) { return $hash; } while (length($dsn)) { if ($dsn =~ /([^:;]*\[.*]|[^:;]*)[:;](.*)/) { $val = $1; $dsn = $2; $val =~ s/\[|]//g; # Remove [] if present, the rest of the code prefers plain IPv6 addresses } else { $val = $dsn; $dsn = ''; } if ($val =~ /([^=]*)=(.*)/) { $var = $1; $val = $2; if ($var eq 'hostname' || $var eq 'host') { $hash->{'host'} = $val; } elsif ($var eq 'db' || $var eq 'dbname') { $hash->{'database'} = $val; } else { $hash->{$var} = $val; } } else { foreach $var (qw(database host port)) { if (!defined($hash->{$var})) { $hash->{$var} = $val; last; } } } } return $hash; } # ====== DRIVER ====== package # hide from PAUSE DBD::MariaDB::dr; use strict; use DBI qw(:sql_types); sub connect { my($drh, $dsn, $username, $password, $attrhash) = @_; my($port); my($cWarn); my $connect_ref= { 'Name' => $dsn }; $attrhash = {} unless defined $attrhash; # create a 'blank' dbh my $attr_dsn = DBD::MariaDB->parse_dsn($dsn); my($this, $privateAttrHash) = (undef, $attrhash); $privateAttrHash = { %$attr_dsn, %$privateAttrHash, 'Name' => $dsn, 'user' => $username, 'password' => $password }; if (exists $attrhash->{dbi_imp_data}) { $connect_ref->{'dbi_imp_data'} = $attrhash->{dbi_imp_data}; } if (!defined($this = DBI::_new_dbh($drh, $connect_ref, $privateAttrHash))) { return undef; } DBD::MariaDB::db::_login($this, $dsn, $username, $password) or $this = undef; $this; } sub data_sources { my ($self, $attributes) = @_; my ($host, $port, $username, $password); if (defined $attributes) { %{$attributes} = %{$attributes}; $host = delete $attributes->{host}; $port = delete $attributes->{port}; $username = delete $attributes->{user}; $password = delete $attributes->{password}; } my $dsn = ''; $dsn .= ";host=$host" if defined $host; $dsn .= ";port=$port" if defined $port; my $dbh = $self->connect($dsn, $username, $password, $attributes); return unless defined $dbh; return $dbh->data_sources(); } # ====== DATABASE ====== package # hide from PAUSE DBD::MariaDB::db; use strict; use DBI qw(:sql_types); sub prepare { my($dbh, $statement, $attribs)= @_; return unless $dbh->func('_async_check'); # create a 'blank' dbh my $sth = DBI::_new_sth($dbh, {'Statement' => $statement}); # Populate internal handle data. if (!DBD::MariaDB::st::_prepare($sth, $statement, $attribs)) { $sth = undef; } $sth; } sub table_info { my ($dbh, $catalog, $schema, $table, $type, $attr) = @_; return unless $dbh->func('_async_check'); local $dbh->{mariadb_server_prepare} = 0; my @names = qw(TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS); my @rows; my $sponge = DBI->connect("DBI:Sponge:", '','') or return $dbh->DBI::set_err($DBI::err, "DBI::Sponge: $DBI::errstr"); # Return the list of catalogs if (defined $catalog && $catalog eq "%" && (!defined($schema) || $schema eq "") && (!defined($table) || $table eq "")) { @rows = (); # Empty, because MySQL doesn't support catalogs (yet) } # Return the list of schemas elsif (defined $schema && $schema eq "%" && (!defined($catalog) || $catalog eq "") && (!defined($table) || $table eq "")) { my $sth = $dbh->prepare("SHOW DATABASES") or return undef; $sth->execute() or return DBI::set_err($dbh, $sth->err(), $sth->errstr()); while (my $ref = $sth->fetchrow_arrayref()) { push(@rows, [ undef, $ref->[0], undef, undef, undef ]); } } # Return the list of table types elsif (defined $type && $type eq "%" && (!defined($catalog) || $catalog eq "") && (!defined($schema) || $schema eq "") && (!defined($table) || $table eq "")) { @rows = ( [ undef, undef, undef, "TABLE", undef ], [ undef, undef, undef, "VIEW", undef ], ); } # Special case: a catalog other than undef, "", or "%" elsif (defined $catalog && $catalog ne "" && $catalog ne "%") { @rows = (); # Nothing, because MySQL doesn't support catalogs yet. } # Uh oh, we actually have a meaty table_info call. Work is required! else { my @schemas; # If no table was specified, we want them all $table ||= "%"; # If something was given for the schema, we need to expand it to # a list of schemas, since it may be a wildcard. if (defined $schema && $schema ne "") { my $sth = $dbh->prepare("SHOW DATABASES LIKE " . $dbh->quote($schema)) or return undef; $sth->execute() or return DBI::set_err($dbh, $sth->err(), $sth->errstr()); while (my $ref = $sth->fetchrow_arrayref()) { push @schemas, $ref->[0]; } } # Otherwise we want the current database else { push @schemas, $dbh->selectrow_array("SELECT DATABASE()"); } # Figure out which table types are desired my ($want_tables, $want_views); if (defined $type && $type ne "") { $want_tables = ($type =~ m/table/i); $want_views = ($type =~ m/view/i); } else { $want_tables = $want_views = 1; } for my $database (@schemas) { my $sth = $dbh->prepare("SHOW /*!50002 FULL*/ TABLES FROM " . $dbh->quote_identifier($database) . " LIKE " . $dbh->quote($table)) or return undef; $sth->execute() or return DBI::set_err($dbh, $sth->err(), $sth->errstr()); while (my $ref = $sth->fetchrow_arrayref()) { my $type = (defined $ref->[1] && $ref->[1] =~ /view/i) ? 'VIEW' : 'TABLE'; next if $type eq 'TABLE' && not $want_tables; next if $type eq 'VIEW' && not $want_views; push @rows, [ undef, $database, $ref->[0], $type, undef ]; } } } my $sth = $sponge->prepare("table_info", { rows => \@rows, NUM_OF_FIELDS => scalar @names, NAME => \@names, }) or return $dbh->DBI::set_err($sponge->err(), $sponge->errstr()); return $sth; } sub column_info { my ($dbh, $catalog, $schema, $table, $column) = @_; return unless $dbh->func('_async_check'); local $dbh->{mariadb_server_prepare} = 0; # ODBC allows a NULL to mean all columns, so we'll accept undef $column = '%' unless defined $column; my $ER_NO_SUCH_TABLE= 1146; my $ER_BAD_FIELD_ERROR = 1054; my $table_id = $dbh->quote_identifier($catalog, $schema, $table); my @names = qw( TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE BUFFER_LENGTH DECIMAL_DIGITS NUM_PREC_RADIX NULLABLE REMARKS COLUMN_DEF SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH ORDINAL_POSITION IS_NULLABLE CHAR_SET_CAT CHAR_SET_SCHEM CHAR_SET_NAME COLLATION_CAT COLLATION_SCHEM COLLATION_NAME UDT_CAT UDT_SCHEM UDT_NAME DOMAIN_CAT DOMAIN_SCHEM DOMAIN_NAME SCOPE_CAT SCOPE_SCHEM SCOPE_NAME MAX_CARDINALITY DTD_IDENTIFIER IS_SELF_REF mariadb_is_pri_key mariadb_type_name mariadb_values mariadb_is_auto_increment ); my %col_info; local $dbh->{FetchHashKeyName} = 'NAME_lc'; # only ignore ER_NO_SUCH_TABLE in internal_execute if issued from here my $desc_sth = $dbh->prepare("DESCRIBE $table_id " . $dbh->quote($column)); my $desc = $dbh->selectall_arrayref($desc_sth, { Columns=>{} }); #return $desc_sth if $desc_sth->err(); if (my $err = $desc_sth->err()) { # return the error, unless it is due to the table not # existing per DBI spec if ($err != $ER_NO_SUCH_TABLE) { return undef; } $dbh->set_err(undef,undef); $desc = []; } my $ordinal_pos = 0; my @fields; for my $row (@$desc) { my $type = $row->{type}; $type =~ m/^(\w+)(\((.+)\))?\s?(.*)?$/; my $basetype = lc($1); my $typemod = $3; my $attr = $4; push @fields, $row->{field}; my $info = $col_info{ $row->{field} }= { TABLE_CAT => $catalog, TABLE_SCHEM => $schema, TABLE_NAME => $table, COLUMN_NAME => $row->{field}, NULLABLE => ($row->{null} eq 'YES') ? 1 : 0, IS_NULLABLE => ($row->{null} eq 'YES') ? "YES" : "NO", TYPE_NAME => uc($basetype), COLUMN_DEF => $row->{default}, ORDINAL_POSITION => ++$ordinal_pos, mariadb_is_pri_key => ($row->{key} eq 'PRI'), mariadb_type_name => $row->{type}, mariadb_is_auto_increment => ($row->{extra} =~ /auto_increment/i ? 1 : 0), }; # # This code won't deal with a pathological case where a value # contains a single quote followed by a comma, and doesn't unescape # any escaped values. But who would use those in an enum or set? # my @type_params= ($typemod && index($typemod,"'")>=0) ? ("$typemod," =~ /'(.*?)',/g) # assume all are quoted : split /,/, $typemod||''; # no quotes, plain list s/''/'/g for @type_params; # undo doubling of quotes my @type_attr= split / /, $attr||''; $info->{DATA_TYPE}= SQL_VARCHAR(); if ($basetype =~ /^(char|varchar|\w*text|\w*blob)/) { $info->{DATA_TYPE}= SQL_CHAR() if $basetype eq 'char'; if ($type_params[0]) { $info->{COLUMN_SIZE} = $type_params[0]; } else { $info->{COLUMN_SIZE} = 65535; $info->{COLUMN_SIZE} = 255 if $basetype =~ /^tiny/; $info->{COLUMN_SIZE} = 16777215 if $basetype =~ /^medium/; $info->{COLUMN_SIZE} = 4294967295 if $basetype =~ /^long/; } } elsif ($basetype =~ /^(binary|varbinary)/) { $info->{COLUMN_SIZE} = $type_params[0]; # SQL_BINARY & SQL_VARBINARY are tempting here but don't match the # semantics for mysql (not hex). SQL_CHAR & SQL_VARCHAR are correct here. $info->{DATA_TYPE} = ($basetype eq 'binary') ? SQL_CHAR() : SQL_VARCHAR(); } elsif ($basetype =~ /^(enum|set)/) { if ($basetype eq 'set') { $info->{COLUMN_SIZE} = length(join ",", @type_params); } else { my $max_len = 0; length($_) > $max_len and $max_len = length($_) for @type_params; $info->{COLUMN_SIZE} = $max_len; } $info->{"mariadb_values"} = \@type_params; } elsif ($basetype =~ /int/ || $basetype eq 'bit' ) { # big/medium/small/tiny etc + unsigned? $info->{DATA_TYPE} = SQL_INTEGER(); $info->{NUM_PREC_RADIX} = 10; $info->{COLUMN_SIZE} = $type_params[0]; } elsif ($basetype =~ /^decimal/) { $info->{DATA_TYPE} = SQL_DECIMAL(); $info->{NUM_PREC_RADIX} = 10; $info->{COLUMN_SIZE} = $type_params[0]; $info->{DECIMAL_DIGITS} = $type_params[1]; } elsif ($basetype =~ /^(float|double)/) { $info->{DATA_TYPE} = ($basetype eq 'float') ? SQL_FLOAT() : SQL_DOUBLE(); $info->{NUM_PREC_RADIX} = 2; $info->{COLUMN_SIZE} = ($basetype eq 'float') ? 32 : 64; } elsif ($basetype =~ /date|time/) { # date/datetime/time/timestamp if ($basetype eq 'time' or $basetype eq 'date') { #$info->{DATA_TYPE} = ($basetype eq 'time') ? SQL_TYPE_TIME() : SQL_TYPE_DATE(); $info->{DATA_TYPE} = ($basetype eq 'time') ? SQL_TIME() : SQL_DATE(); $info->{COLUMN_SIZE} = ($basetype eq 'time') ? 8 : 10; } else { # datetime/timestamp #$info->{DATA_TYPE} = SQL_TYPE_TIMESTAMP(); $info->{DATA_TYPE} = SQL_TIMESTAMP(); $info->{SQL_DATA_TYPE} = SQL_DATETIME(); $info->{SQL_DATETIME_SUB} = $info->{DATA_TYPE} - ($info->{SQL_DATA_TYPE} * 10); $info->{COLUMN_SIZE} = ($basetype eq 'datetime') ? 19 : $type_params[0] || 14; } $info->{DECIMAL_DIGITS}= 0; # no fractional seconds } elsif ($basetype eq 'year') { # no close standard so treat as int $info->{DATA_TYPE} = SQL_INTEGER(); $info->{NUM_PREC_RADIX} = 10; $info->{COLUMN_SIZE} = 4; } else { return $dbh->DBI::set_err($ER_BAD_FIELD_ERROR, "column_info: unrecognized column type '$basetype' of $table_id.$row->{field} treated as varchar"); } $info->{SQL_DATA_TYPE} ||= $info->{DATA_TYPE}; } my $sponge = DBI->connect("DBI:Sponge:", '','') or return $dbh->DBI::set_err($DBI::err, "DBI::Sponge: $DBI::errstr"); my $sth = $sponge->prepare("column_info $table", { rows => [ map { [ @{$_}{@names} ] } map { $col_info{$_} } @fields ], NUM_OF_FIELDS => scalar @names, NAME => \@names, }) or return $dbh->DBI::set_err($sponge->err(), $sponge->errstr()); return $sth; } sub primary_key_info { my ($dbh, $catalog, $schema, $table) = @_; return unless $dbh->func('_async_check'); local $dbh->{mariadb_server_prepare} = 0; my $table_id = $dbh->quote_identifier($catalog, $schema, $table); my @names = qw( TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME KEY_SEQ PK_NAME ); my %col_info; local $dbh->{FetchHashKeyName} = 'NAME_lc'; my $desc_sth = $dbh->prepare("SHOW KEYS FROM $table_id"); my $desc= $dbh->selectall_arrayref($desc_sth, { Columns=>{} }); my $ordinal_pos = 0; for my $row (grep { $_->{key_name} eq 'PRIMARY'} @$desc) { $col_info{ $row->{column_name} }= { TABLE_CAT => $catalog, TABLE_SCHEM => $schema, TABLE_NAME => $table, COLUMN_NAME => $row->{column_name}, KEY_SEQ => $row->{seq_in_index}, PK_NAME => $row->{key_name}, }; } my $sponge = DBI->connect("DBI:Sponge:", '','') or return $dbh->DBI::set_err($DBI::err, "DBI::Sponge: $DBI::errstr"); my $sth= $sponge->prepare("primary_key_info $table", { rows => [ map { [ @{$_}{@names} ] } sort { $a->{KEY_SEQ} <=> $b->{KEY_SEQ} } values %col_info ], NUM_OF_FIELDS => scalar @names, NAME => \@names, }) or return $dbh->DBI::set_err($sponge->err(), $sponge->errstr()); return $sth; } sub foreign_key_info { my ($dbh, $pk_catalog, $pk_schema, $pk_table, $fk_catalog, $fk_schema, $fk_table, ) = @_; return unless $dbh->func('_async_check'); # INFORMATION_SCHEMA.KEY_COLUMN_USAGE was added in 5.0.6 return if $dbh->FETCH('mariadb_serverversion') < 50006; my $sql = <<'EOF'; SELECT NULL AS PKTABLE_CAT, A.REFERENCED_TABLE_SCHEMA AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME, A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_CATALOG AS FKTABLE_CAT, A.TABLE_SCHEMA AS FKTABLE_SCHEM, A.TABLE_NAME AS FKTABLE_NAME, A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ, NULL AS UPDATE_RULE, NULL AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME, NULL AS PK_NAME, NULL AS DEFERABILITY, NULL AS UNIQUE_OR_PRIMARY FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE A, INFORMATION_SCHEMA.TABLE_CONSTRAINTS B WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME AND A.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND B.CONSTRAINT_TYPE IS NOT NULL EOF my @where; my @bind; # catalogs are not yet supported by MySQL # if (defined $pk_catalog) { # push @where, 'A.REFERENCED_TABLE_CATALOG = ?'; # push @bind, $pk_catalog; # } if (defined $pk_schema) { push @where, 'A.REFERENCED_TABLE_SCHEMA = ?'; push @bind, $pk_schema; } if (defined $pk_table) { push @where, 'A.REFERENCED_TABLE_NAME = ?'; push @bind, $pk_table; } # if (defined $fk_catalog) { # push @where, 'A.TABLE_CATALOG = ?'; # push @bind, $fk_schema; # } if (defined $fk_schema) { push @where, 'A.TABLE_SCHEMA = ?'; push @bind, $fk_schema; } if (defined $fk_table) { push @where, 'A.TABLE_NAME = ?'; push @bind, $fk_table; } if (@where) { $sql .= ' AND '; $sql .= join ' AND ', @where; } $sql .= " ORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"; local $dbh->{FetchHashKeyName} = 'NAME_uc'; my $sth = $dbh->prepare($sql); $sth->execute(@bind); return $sth; } # #86030: PATCH: adding statistics_info support # Thank you to David Dick http://search.cpan.org/~ddick/ sub statistics_info { my ($dbh, $catalog, $schema, $table, $unique_only, $quick, ) = @_; return unless $dbh->func('_async_check'); # INFORMATION_SCHEMA.KEY_COLUMN_USAGE was added in 5.0.6 return if $dbh->FETCH('mariadb_serverversion') < 50006; my $sql = <<'EOF'; SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME AS TABLE_NAME, NON_UNIQUE AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, INDEX_NAME AS INDEX_NAME, LCASE(INDEX_TYPE) AS TYPE, SEQ_IN_INDEX AS ORDINAL_POSITION, COLUMN_NAME AS COLUMN_NAME, COLLATION AS ASC_OR_DESC, CARDINALITY AS CARDINALITY, NULL AS PAGES, NULL AS FILTER_CONDITION FROM INFORMATION_SCHEMA.STATISTICS EOF my @where; my @bind; # catalogs are not yet supported by MySQL # if (defined $catalog) { # push @where, 'TABLE_CATALOG = ?'; # push @bind, $catalog; # } if (defined $schema) { push @where, 'TABLE_SCHEMA = ?'; push @bind, $schema; } if (defined $table) { push @where, 'TABLE_NAME = ?'; push @bind, $table; } if (@where) { $sql .= ' WHERE '; $sql .= join ' AND ', @where; } $sql .= " ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION"; local $dbh->{FetchHashKeyName} = 'NAME_uc'; my $sth = $dbh->prepare($sql); $sth->execute(@bind); return $sth; } #################### # get_info() # SQL_DRIVER_VER should be formatted as ##.##.#### my $odbc_driver_ver = $DBD::MariaDB::VERSION; $odbc_driver_ver .= '_00' if $odbc_driver_ver =~ /^\d+\.\d+$/; $odbc_driver_ver = sprintf("%02u.%02u.%04u", split(/[\._]/, $odbc_driver_ver)); my @odbc_keywords = qw( BIGINT BLOB DEFAULT KEYS LIMIT LONGBLOB MEDIMUMBLOB MEDIUMINT MEDIUMTEXT PROCEDURE REGEXP RLIKE SHOW TABLES TINYBLOB TINYTEXT UNIQUE UNSIGNED ZEROFILL ); my %odbc_info_constants = ( 20 => 'N', # SQL_ACCESSIBLE_PROCEDURES 19 => 'Y', # SQL_ACCESSIBLE_TABLES 116 => 0, # SQL_ACTIVE_ENVIRONMENTS 169 => 127, # SQL_AGGREGATE_FUNCTIONS 117 => 0, # SQL_ALTER_DOMAIN 86 => 3, # SQL_ALTER_TABLE 10021 => 2, # SQL_ASYNC_MODE 120 => 2, # SQL_BATCH_ROW_COUNT 121 => 2, # SQL_BATCH_SUPPORT 82 => 0, # SQL_BOOKMARK_PERSISTENCE 114 => 1, # SQL_CATALOG_LOCATION 10003 => 'Y', # SQL_CATALOG_NAME 41 => '.', # SQL_CATALOG_NAME_SEPARATOR 42 => 'database', # SQL_CATALOG_TERM 92 => 29, # SQL_CATALOG_USAGE 10004 => '', # SQL_COLLATION_SEQ 87 => 'Y', # SQL_COLUMN_ALIAS 22 => 0, # SQL_CONCAT_NULL_BEHAVIOR 53 => 259071, # SQL_CONVERT_BIGINT 54 => 0, # SQL_CONVERT_BINARY 55 => 259071, # SQL_CONVERT_BIT 56 => 259071, # SQL_CONVERT_CHAR 57 => 259071, # SQL_CONVERT_DATE 58 => 259071, # SQL_CONVERT_DECIMAL 59 => 259071, # SQL_CONVERT_DOUBLE 60 => 259071, # SQL_CONVERT_FLOAT 48 => 0, # SQL_CONVERT_FUNCTIONS # 173 => undef, # SQL_CONVERT_GUID 61 => 259071, # SQL_CONVERT_INTEGER 123 => 0, # SQL_CONVERT_INTERVAL_DAY_TIME 124 => 0, # SQL_CONVERT_INTERVAL_YEAR_MONTH 71 => 0, # SQL_CONVERT_LONGVARBINARY 62 => 259071, # SQL_CONVERT_LONGVARCHAR 63 => 259071, # SQL_CONVERT_NUMERIC 64 => 259071, # SQL_CONVERT_REAL 65 => 259071, # SQL_CONVERT_SMALLINT 66 => 259071, # SQL_CONVERT_TIME 67 => 259071, # SQL_CONVERT_TIMESTAMP 68 => 259071, # SQL_CONVERT_TINYINT 69 => 0, # SQL_CONVERT_VARBINARY 70 => 259071, # SQL_CONVERT_VARCHAR 122 => 0, # SQL_CONVERT_WCHAR 125 => 0, # SQL_CONVERT_WLONGVARCHAR 126 => 0, # SQL_CONVERT_WVARCHAR 74 => 1, # SQL_CORRELATION_NAME 127 => 0, # SQL_CREATE_ASSERTION 128 => 0, # SQL_CREATE_CHARACTER_SET 129 => 0, # SQL_CREATE_COLLATION 130 => 0, # SQL_CREATE_DOMAIN 131 => 0, # SQL_CREATE_SCHEMA 132 => 1045, # SQL_CREATE_TABLE 133 => 0, # SQL_CREATE_TRANSLATION 134 => 0, # SQL_CREATE_VIEW 23 => 2, # SQL_CURSOR_COMMIT_BEHAVIOR 24 => 2, # SQL_CURSOR_ROLLBACK_BEHAVIOR 10001 => 0, # SQL_CURSOR_SENSITIVITY 25 => 'N', # SQL_DATA_SOURCE_READ_ONLY 119 => 7, # SQL_DATETIME_LITERALS 170 => 3, # SQL_DDL_INDEX 26 => 2, # SQL_DEFAULT_TXN_ISOLATION 10002 => 'N', # SQL_DESCRIBE_PARAMETER # 171 => undef, # SQL_DM_VER 3 => 137076632, # SQL_DRIVER_HDBC # 135 => undef, # SQL_DRIVER_HDESC 4 => 137076088, # SQL_DRIVER_HENV # 76 => undef, # SQL_DRIVER_HLIB # 5 => undef, # SQL_DRIVER_HSTMT 6 => 'DBD/MariaDB.pm', # SQL_DRIVER_NAME 77 => '03.51', # SQL_DRIVER_ODBC_VER 7 => $odbc_driver_ver, # SQL_DRIVER_VER 136 => 0, # SQL_DROP_ASSERTION 137 => 0, # SQL_DROP_CHARACTER_SET 138 => 0, # SQL_DROP_COLLATION 139 => 0, # SQL_DROP_DOMAIN 140 => 0, # SQL_DROP_SCHEMA 141 => 7, # SQL_DROP_TABLE 142 => 0, # SQL_DROP_TRANSLATION 143 => 0, # SQL_DROP_VIEW 144 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES1 145 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES2 27 => 'Y', # SQL_EXPRESSIONS_IN_ORDERBY 8 => 63, # SQL_FETCH_DIRECTION 84 => 0, # SQL_FILE_USAGE 146 => 97863, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 147 => 6016, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 81 => 11, # SQL_GETDATA_EXTENSIONS 88 => 3, # SQL_GROUP_BY 28 => 4, # SQL_IDENTIFIER_CASE 29 => '`', # SQL_IDENTIFIER_QUOTE_CHAR 148 => 0, # SQL_INDEX_KEYWORDS 149 => 0, # SQL_INFO_SCHEMA_VIEWS 172 => 7, # SQL_INSERT_STATEMENT 73 => 'N', # SQL_INTEGRITY 150 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES1 151 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES2 89 => (join ',', @odbc_keywords), # SQL_KEYWORDS 113 => 'Y', # SQL_LIKE_ESCAPE_CLAUSE 78 => 0, # SQL_LOCK_TYPES # 20000 => undef, # SQL_MAXIMUM_STMT_OCTETS # 20001 => undef, # SQL_MAXIMUM_STMT_OCTETS_DATA # 20002 => undef, # SQL_MAXIMUM_STMT_OCTETS_SCHEMA 10022 => 1, # SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 112 => 0, # SQL_MAX_BINARY_LITERAL_LEN 34 => 64, # SQL_MAX_CATALOG_NAME_LEN 108 => 0, # SQL_MAX_CHAR_LITERAL_LEN 97 => 0, # SQL_MAX_COLUMNS_IN_GROUP_BY 98 => 32, # SQL_MAX_COLUMNS_IN_INDEX 99 => 0, # SQL_MAX_COLUMNS_IN_ORDER_BY 100 => 0, # SQL_MAX_COLUMNS_IN_SELECT 101 => 0, # SQL_MAX_COLUMNS_IN_TABLE 30 => 64, # SQL_MAX_COLUMN_NAME_LEN 1 => 0, # SQL_MAX_CONCURRENT_ACTIVITIES 31 => 18, # SQL_MAX_CURSOR_NAME_LEN 0 => 0, # SQL_MAX_DRIVER_CONNECTIONS 10005 => 64, # SQL_MAX_IDENTIFIER_LEN 102 => 500, # SQL_MAX_INDEX_SIZE 33 => 0, # SQL_MAX_PROCEDURE_NAME_LEN 104 => 0, # SQL_MAX_ROW_SIZE 103 => 'Y', # SQL_MAX_ROW_SIZE_INCLUDES_LONG 32 => 0, # SQL_MAX_SCHEMA_NAME_LEN 35 => 64, # SQL_MAX_TABLE_NAME_LEN 107 => 16, # SQL_MAX_USER_NAME_LEN 37 => 'Y', # SQL_MULTIPLE_ACTIVE_TXN 36 => 'Y', # SQL_MULT_RESULT_SETS 111 => 'N', # SQL_NEED_LONG_DATA_LEN 75 => 1, # SQL_NON_NULLABLE_COLUMNS 85 => 2, # SQL_NULL_COLLATION 49 => 16777215, # SQL_NUMERIC_FUNCTIONS 9 => 1, # SQL_ODBC_API_CONFORMANCE 152 => 2, # SQL_ODBC_INTERFACE_CONFORMANCE 12 => 1, # SQL_ODBC_SAG_CLI_CONFORMANCE 15 => 1, # SQL_ODBC_SQL_CONFORMANCE 10 => '03.80', # SQL_ODBC_VER 115 => 123, # SQL_OJ_CAPABILITIES 90 => 'Y', # SQL_ORDER_BY_COLUMNS_IN_SELECT 38 => 'Y', # SQL_OUTER_JOINS 153 => 2, # SQL_PARAM_ARRAY_ROW_COUNTS 154 => 3, # SQL_PARAM_ARRAY_SELECTS 80 => 3, # SQL_POSITIONED_STATEMENTS 79 => 31, # SQL_POS_OPERATIONS 21 => 'N', # SQL_PROCEDURES 40 => '', # SQL_PROCEDURE_TERM 93 => 3, # SQL_QUOTED_IDENTIFIER_CASE 11 => 'N', # SQL_ROW_UPDATES 39 => '', # SQL_SCHEMA_TERM 91 => 0, # SQL_SCHEMA_USAGE 43 => 7, # SQL_SCROLL_CONCURRENCY 44 => 17, # SQL_SCROLL_OPTIONS 14 => '\\', # SQL_SEARCH_PATTERN_ESCAPE 94 => ' !"#%&\'()*+,-.:;<=>?@[\]^`{|}~', # SQL_SPECIAL_CHARACTERS 155 => 7, # SQL_SQL92_DATETIME_FUNCTIONS 156 => 0, # SQL_SQL92_FOREIGN_KEY_DELETE_RULE 157 => 0, # SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 158 => 8160, # SQL_SQL92_GRANT 159 => 0, # SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 160 => 0, # SQL_SQL92_PREDICATES 161 => 466, # SQL_SQL92_RELATIONAL_JOIN_OPERATORS 162 => 32640, # SQL_SQL92_REVOKE 163 => 7, # SQL_SQL92_ROW_VALUE_CONSTRUCTOR 164 => 255, # SQL_SQL92_STRING_FUNCTIONS 165 => 0, # SQL_SQL92_VALUE_EXPRESSIONS 118 => 4, # SQL_SQL_CONFORMANCE 166 => 2, # SQL_STANDARD_CLI_CONFORMANCE 167 => 97863, # SQL_STATIC_CURSOR_ATTRIBUTES1 168 => 6016, # SQL_STATIC_CURSOR_ATTRIBUTES2 83 => 7, # SQL_STATIC_SENSITIVITY 50 => 491519, # SQL_STRING_FUNCTIONS 95 => 0, # SQL_SUBQUERIES 51 => 7, # SQL_SYSTEM_FUNCTIONS 45 => 'table', # SQL_TABLE_TERM 109 => 0, # SQL_TIMEDATE_ADD_INTERVALS 110 => 0, # SQL_TIMEDATE_DIFF_INTERVALS 52 => 106495, # SQL_TIMEDATE_FUNCTIONS 46 => 3, # SQL_TXN_CAPABLE 72 => 15, # SQL_TXN_ISOLATION_OPTION 96 => 0, # SQL_UNION 10000 => 1992, # SQL_XOPEN_CLI_YEAR ); my %odbc_info_subs = ( 2 => sub { "DBI:MariaDB:" . $_[0]->{Name} }, # SQL_DATA_SOURCE_NAME 17 => sub { ($_[0]->FETCH('mariadb_serverinfo') =~ /MariaDB|-maria-/) ? 'MariaDB' : 'MySQL' }, # SQL_DBMS_NAME 18 => sub { my $ver = $_[0]->FETCH('mariadb_serverversion'); sprintf("%02u.%02u.%02u00", $ver/10000, ($ver%10000)/100, $ver%100) }, # SQL_DBMS_VER 105 => sub { $_[0]->FETCH('mariadb_max_allowed_packet') }, # SQL_MAX_STATEMENT_LEN 106 => sub { $_[0]->FETCH('mariadb_serverversion') >= 50000 ? 63 : 31 }, # SQL_MAX_TABLES_IN_SELECT 13 => sub { $_[0]->FETCH('mariadb_hostinfo') }, # SQL_SERVER_NAME 47 => sub { $_[0]->{Username} }, # SQL_USER_NAME ); sub get_info { my ($dbh, $type) = @_; return $odbc_info_constants{$type} if exists $odbc_info_constants{$type}; return $odbc_info_subs{$type}->($dbh) if exists $odbc_info_subs{$type}; return undef; } BEGIN { my @needs_async_check = qw/begin_work/; foreach my $method (@needs_async_check) { no strict 'refs'; my $super = "SUPER::$method"; *$method = sub { my $h = shift; return unless $h->func('_async_check'); return $h->$super(@_); }; } } # ====== STATEMENT ====== package # hide from PAUSE DBD::MariaDB::st; use strict; BEGIN { my @needs_async_result = qw/fetchrow_hashref fetchall_hashref/; my @needs_async_check = qw/bind_param_array bind_col bind_columns execute_for_fetch/; foreach my $method (@needs_async_result) { no strict 'refs'; my $super = "SUPER::$method"; *$method = sub { my $sth = shift; if(defined $sth->mariadb_async_ready) { return unless $sth->mariadb_async_result; } return $sth->$super(@_); }; } foreach my $method (@needs_async_check) { no strict 'refs'; my $super = "SUPER::$method"; *$method = sub { my $h = shift; return unless $h->func('_async_check'); return $h->$super(@_); }; } } 1;