123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164 |
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2016 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Zeev Suraski <zeev@zend.com> |
- | Jouni Ahto <jouni.ahto@exdec.fi> |
- | Yasuo Ohgaki <yohgaki@php.net> |
- | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) |
- | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) |
- +----------------------------------------------------------------------+
- */
- /* $Id$ */
- #include <stdlib.h>
- #define PHP_PGSQL_PRIVATE 1
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #define SMART_STR_PREALLOC 512
- #include "php.h"
- #include "php_ini.h"
- #include "ext/standard/php_standard.h"
- #include "ext/standard/php_smart_str.h"
- #include "ext/ereg/php_regex.h"
- #ifdef PHP_WIN32
- # include "win32/time.h"
- #endif
- #undef PACKAGE_BUGREPORT
- #undef PACKAGE_NAME
- #undef PACKAGE_STRING
- #undef PACKAGE_TARNAME
- #undef PACKAGE_VERSION
- #include "php_pgsql.h"
- #include "php_globals.h"
- #include "zend_exceptions.h"
- #if HAVE_PGSQL
- #ifndef InvalidOid
- #define InvalidOid ((Oid) 0)
- #endif
- #define PGSQL_ASSOC 1<<0
- #define PGSQL_NUM 1<<1
- #define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM)
- #define PGSQL_STATUS_LONG 1
- #define PGSQL_STATUS_STRING 2
- #define PGSQL_MAX_LENGTH_OF_LONG 30
- #define PGSQL_MAX_LENGTH_OF_DOUBLE 60
- #if LONG_MAX < UINT_MAX
- #define PGSQL_RETURN_OID(oid) do { \
- if (oid > LONG_MAX) { \
- smart_str s = {0}; \
- smart_str_append_unsigned(&s, oid); \
- smart_str_0(&s); \
- RETURN_STRINGL(s.c, s.len, 0); \
- } \
- RETURN_LONG((long)oid); \
- } while(0)
- #else
- #define PGSQL_RETURN_OID(oid) (RETURN_LONG((long)oid))
- #endif
- #if HAVE_PQSETNONBLOCKING
- #define PQ_SETNONBLOCKING(pg_link, flag) PQsetnonblocking(pg_link, flag)
- #else
- #define PQ_SETNONBLOCKING(pg_link, flag) 0
- #endif
- #define CHECK_DEFAULT_LINK(x) if ((x) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No PostgreSQL link opened yet"); }
- #ifndef HAVE_PQFREEMEM
- #define PQfreemem free
- #endif
- ZEND_DECLARE_MODULE_GLOBALS(pgsql)
- static PHP_GINIT_FUNCTION(pgsql);
- /* {{{ arginfo */
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
- ZEND_ARG_INFO(0, connection_string)
- ZEND_ARG_INFO(0, connect_type)
- ZEND_ARG_INFO(0, host)
- ZEND_ARG_INFO(0, port)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, tty)
- ZEND_ARG_INFO(0, database)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_pconnect, 0, 0, 1)
- ZEND_ARG_INFO(0, connection_string)
- ZEND_ARG_INFO(0, host)
- ZEND_ARG_INFO(0, port)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, tty)
- ZEND_ARG_INFO(0, database)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect_poll, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #if HAVE_PQPARAMETERSTATUS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_parameter_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, param_name)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_close, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_dbname, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_error, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_options, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_port, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_tty, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_host, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_version, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_ping, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #if HAVE_PQEXECPARAMS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query_params, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQPREPARE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_prepare, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQEXECPREPARED
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_execute, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_rows, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_fields, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #if HAVE_PQCMDTUPLES
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_affected_rows, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #ifdef HAVE_PQFTABLE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_table, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_ARG_INFO(0, oid_only)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_name, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_size, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type_oid, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_num, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_name)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_result, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row_number)
- ZEND_ARG_INFO(0, field_name)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_row, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_assoc, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_array, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_object, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, class_name)
- ZEND_ARG_INFO(0, l)
- ZEND_ARG_INFO(0, ctor_params)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, column_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_seek, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, offset)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_prtlen, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, field_name_or_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_is_null, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, field_name_or_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_free_result, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_oid, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_trace, 0, 0, 1)
- ZEND_ARG_INFO(0, filename)
- ZEND_ARG_INFO(0, mode)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_untrace, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_create, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_id)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_unlink, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_open, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_ARG_INFO(0, mode)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_close, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, len)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_write, 0, 0, 2)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, buf)
- ZEND_ARG_INFO(0, len)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read_all, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_import, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, filename)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_export, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, objoid)
- ZEND_ARG_INFO(0, filename)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_seek, 0, 0, 2)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, offset)
- ZEND_ARG_INFO(0, whence)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_tell, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- #if HAVE_PG_LO_TRUNCATE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_truncate, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, size)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_error_verbosity, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, verbosity)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQCLIENTENCODING
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_client_encoding, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, encoding)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_client_encoding, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_end_copy, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_put_line, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_to, 0, 0, 2)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, table_name)
- ZEND_ARG_INFO(0, delimiter)
- ZEND_ARG_INFO(0, null_as)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_from, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, table_name)
- ZEND_ARG_INFO(0, rows)
- ZEND_ARG_INFO(0, delimiter)
- ZEND_ARG_INFO(0, null_as)
- ZEND_END_ARG_INFO()
- #if HAVE_PQESCAPE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_string, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_bytea, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_unescape_bytea, 0, 0, 1)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQESCAPE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_literal, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_identifier, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #if HAVE_PQRESULTERRORFIELD
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error_field, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, fieldcode)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #if HAVE_PGTRANSACTIONSTATUS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_transaction_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_reset, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_cancel_query, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_busy, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query, 0, 0, 2)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #if HAVE_PQSENDQUERYPARAMS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query_params, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSENDPREPARE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_prepare, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSENDQUERYPREPARED
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_execute, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_result, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_status, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_notify, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, e)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_pid, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_socket, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_consume_input, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_flush, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_meta_data, 0, 0, 2)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_convert, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, values)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_insert, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, values)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_update, 0, 0, 4)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, fields)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_delete, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_select, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- /* }}} */
- /* {{{ pgsql_functions[]
- */
- const zend_function_entry pgsql_functions[] = {
- /* connection functions */
- PHP_FE(pg_connect, arginfo_pg_connect)
- PHP_FE(pg_pconnect, arginfo_pg_pconnect)
- PHP_FE(pg_connect_poll, arginfo_pg_connect_poll)
- PHP_FE(pg_close, arginfo_pg_close)
- PHP_FE(pg_connection_status, arginfo_pg_connection_status)
- PHP_FE(pg_connection_busy, arginfo_pg_connection_busy)
- PHP_FE(pg_connection_reset, arginfo_pg_connection_reset)
- PHP_FE(pg_host, arginfo_pg_host)
- PHP_FE(pg_dbname, arginfo_pg_dbname)
- PHP_FE(pg_port, arginfo_pg_port)
- PHP_FE(pg_tty, arginfo_pg_tty)
- PHP_FE(pg_options, arginfo_pg_options)
- PHP_FE(pg_version, arginfo_pg_version)
- PHP_FE(pg_ping, arginfo_pg_ping)
- #if HAVE_PQPARAMETERSTATUS
- PHP_FE(pg_parameter_status, arginfo_pg_parameter_status)
- #endif
- #if HAVE_PGTRANSACTIONSTATUS
- PHP_FE(pg_transaction_status, arginfo_pg_transaction_status)
- #endif
- /* query functions */
- PHP_FE(pg_query, arginfo_pg_query)
- #if HAVE_PQEXECPARAMS
- PHP_FE(pg_query_params, arginfo_pg_query_params)
- #endif
- #if HAVE_PQPREPARE
- PHP_FE(pg_prepare, arginfo_pg_prepare)
- #endif
- #if HAVE_PQEXECPREPARED
- PHP_FE(pg_execute, arginfo_pg_execute)
- #endif
- PHP_FE(pg_send_query, arginfo_pg_send_query)
- #if HAVE_PQSENDQUERYPARAMS
- PHP_FE(pg_send_query_params, arginfo_pg_send_query_params)
- #endif
- #if HAVE_PQSENDPREPARE
- PHP_FE(pg_send_prepare, arginfo_pg_send_prepare)
- #endif
- #if HAVE_PQSENDQUERYPREPARED
- PHP_FE(pg_send_execute, arginfo_pg_send_execute)
- #endif
- PHP_FE(pg_cancel_query, arginfo_pg_cancel_query)
- /* result functions */
- PHP_FE(pg_fetch_result, arginfo_pg_fetch_result)
- PHP_FE(pg_fetch_row, arginfo_pg_fetch_row)
- PHP_FE(pg_fetch_assoc, arginfo_pg_fetch_assoc)
- PHP_FE(pg_fetch_array, arginfo_pg_fetch_array)
- PHP_FE(pg_fetch_object, arginfo_pg_fetch_object)
- PHP_FE(pg_fetch_all, arginfo_pg_fetch_all)
- PHP_FE(pg_fetch_all_columns, arginfo_pg_fetch_all_columns)
- #if HAVE_PQCMDTUPLES
- PHP_FE(pg_affected_rows,arginfo_pg_affected_rows)
- #endif
- PHP_FE(pg_get_result, arginfo_pg_get_result)
- PHP_FE(pg_result_seek, arginfo_pg_result_seek)
- PHP_FE(pg_result_status,arginfo_pg_result_status)
- PHP_FE(pg_free_result, arginfo_pg_free_result)
- PHP_FE(pg_last_oid, arginfo_pg_last_oid)
- PHP_FE(pg_num_rows, arginfo_pg_num_rows)
- PHP_FE(pg_num_fields, arginfo_pg_num_fields)
- PHP_FE(pg_field_name, arginfo_pg_field_name)
- PHP_FE(pg_field_num, arginfo_pg_field_num)
- PHP_FE(pg_field_size, arginfo_pg_field_size)
- PHP_FE(pg_field_type, arginfo_pg_field_type)
- PHP_FE(pg_field_type_oid, arginfo_pg_field_type_oid)
- PHP_FE(pg_field_prtlen, arginfo_pg_field_prtlen)
- PHP_FE(pg_field_is_null,arginfo_pg_field_is_null)
- #ifdef HAVE_PQFTABLE
- PHP_FE(pg_field_table, arginfo_pg_field_table)
- #endif
- /* async message function */
- PHP_FE(pg_get_notify, arginfo_pg_get_notify)
- PHP_FE(pg_socket, arginfo_pg_socket)
- PHP_FE(pg_consume_input,arginfo_pg_consume_input)
- PHP_FE(pg_flush, arginfo_pg_flush)
- PHP_FE(pg_get_pid, arginfo_pg_get_pid)
- /* error message functions */
- PHP_FE(pg_result_error, arginfo_pg_result_error)
- #if HAVE_PQRESULTERRORFIELD
- PHP_FE(pg_result_error_field, arginfo_pg_result_error_field)
- #endif
- PHP_FE(pg_last_error, arginfo_pg_last_error)
- PHP_FE(pg_last_notice, arginfo_pg_last_notice)
- /* copy functions */
- PHP_FE(pg_put_line, arginfo_pg_put_line)
- PHP_FE(pg_end_copy, arginfo_pg_end_copy)
- PHP_FE(pg_copy_to, arginfo_pg_copy_to)
- PHP_FE(pg_copy_from, arginfo_pg_copy_from)
- /* debug functions */
- PHP_FE(pg_trace, arginfo_pg_trace)
- PHP_FE(pg_untrace, arginfo_pg_untrace)
- /* large object functions */
- PHP_FE(pg_lo_create, arginfo_pg_lo_create)
- PHP_FE(pg_lo_unlink, arginfo_pg_lo_unlink)
- PHP_FE(pg_lo_open, arginfo_pg_lo_open)
- PHP_FE(pg_lo_close, arginfo_pg_lo_close)
- PHP_FE(pg_lo_read, arginfo_pg_lo_read)
- PHP_FE(pg_lo_write, arginfo_pg_lo_write)
- PHP_FE(pg_lo_read_all, arginfo_pg_lo_read_all)
- PHP_FE(pg_lo_import, arginfo_pg_lo_import)
- PHP_FE(pg_lo_export, arginfo_pg_lo_export)
- PHP_FE(pg_lo_seek, arginfo_pg_lo_seek)
- PHP_FE(pg_lo_tell, arginfo_pg_lo_tell)
- #if HAVE_PG_LO_TRUNCATE
- PHP_FE(pg_lo_truncate, arginfo_pg_lo_truncate)
- #endif
- /* utility functions */
- #if HAVE_PQESCAPE
- PHP_FE(pg_escape_string, arginfo_pg_escape_string)
- PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea)
- PHP_FE(pg_unescape_bytea, arginfo_pg_unescape_bytea)
- PHP_FE(pg_escape_literal, arginfo_pg_escape_literal)
- PHP_FE(pg_escape_identifier, arginfo_pg_escape_identifier)
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- PHP_FE(pg_set_error_verbosity, arginfo_pg_set_error_verbosity)
- #endif
- #if HAVE_PQCLIENTENCODING
- PHP_FE(pg_client_encoding, arginfo_pg_client_encoding)
- PHP_FE(pg_set_client_encoding, arginfo_pg_set_client_encoding)
- #endif
- /* misc function */
- PHP_FE(pg_meta_data, arginfo_pg_meta_data)
- PHP_FE(pg_convert, arginfo_pg_convert)
- PHP_FE(pg_insert, arginfo_pg_insert)
- PHP_FE(pg_update, arginfo_pg_update)
- PHP_FE(pg_delete, arginfo_pg_delete)
- PHP_FE(pg_select, arginfo_pg_select)
- /* aliases for downwards compatibility */
- PHP_FALIAS(pg_exec, pg_query, arginfo_pg_query)
- PHP_FALIAS(pg_getlastoid, pg_last_oid, arginfo_pg_last_oid)
- #if HAVE_PQCMDTUPLES
- PHP_FALIAS(pg_cmdtuples, pg_affected_rows, arginfo_pg_affected_rows)
- #endif
- PHP_FALIAS(pg_errormessage, pg_last_error, arginfo_pg_last_error)
- PHP_FALIAS(pg_numrows, pg_num_rows, arginfo_pg_num_rows)
- PHP_FALIAS(pg_numfields, pg_num_fields, arginfo_pg_num_fields)
- PHP_FALIAS(pg_fieldname, pg_field_name, arginfo_pg_field_name)
- PHP_FALIAS(pg_fieldsize, pg_field_size, arginfo_pg_field_size)
- PHP_FALIAS(pg_fieldtype, pg_field_type, arginfo_pg_field_type)
- PHP_FALIAS(pg_fieldnum, pg_field_num, arginfo_pg_field_num)
- PHP_FALIAS(pg_fieldprtlen, pg_field_prtlen, arginfo_pg_field_prtlen)
- PHP_FALIAS(pg_fieldisnull, pg_field_is_null, arginfo_pg_field_is_null)
- PHP_FALIAS(pg_freeresult, pg_free_result, arginfo_pg_free_result)
- PHP_FALIAS(pg_result, pg_fetch_result, arginfo_pg_get_result)
- PHP_FALIAS(pg_loreadall, pg_lo_read_all, arginfo_pg_lo_read_all)
- PHP_FALIAS(pg_locreate, pg_lo_create, arginfo_pg_lo_create)
- PHP_FALIAS(pg_lounlink, pg_lo_unlink, arginfo_pg_lo_unlink)
- PHP_FALIAS(pg_loopen, pg_lo_open, arginfo_pg_lo_open)
- PHP_FALIAS(pg_loclose, pg_lo_close, arginfo_pg_lo_close)
- PHP_FALIAS(pg_loread, pg_lo_read, arginfo_pg_lo_read)
- PHP_FALIAS(pg_lowrite, pg_lo_write, arginfo_pg_lo_write)
- PHP_FALIAS(pg_loimport, pg_lo_import, arginfo_pg_lo_import)
- PHP_FALIAS(pg_loexport, pg_lo_export, arginfo_pg_lo_export)
- #if HAVE_PQCLIENTENCODING
- PHP_FALIAS(pg_clientencoding, pg_client_encoding, arginfo_pg_client_encoding)
- PHP_FALIAS(pg_setclientencoding, pg_set_client_encoding, arginfo_pg_set_client_encoding)
- #endif
- PHP_FE_END
- };
- /* }}} */
- /* {{{ pgsql_module_entry
- */
- zend_module_entry pgsql_module_entry = {
- STANDARD_MODULE_HEADER,
- "pgsql",
- pgsql_functions,
- PHP_MINIT(pgsql),
- PHP_MSHUTDOWN(pgsql),
- PHP_RINIT(pgsql),
- PHP_RSHUTDOWN(pgsql),
- PHP_MINFO(pgsql),
- NO_VERSION_YET,
- PHP_MODULE_GLOBALS(pgsql),
- PHP_GINIT(pgsql),
- NULL,
- NULL,
- STANDARD_MODULE_PROPERTIES_EX
- };
- /* }}} */
- #ifdef COMPILE_DL_PGSQL
- ZEND_GET_MODULE(pgsql)
- #endif
- static int le_link, le_plink, le_result, le_lofp, le_string;
- /* Compatibility definitions */
- #ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
- #define pg_encoding_to_char(x) "SQL_ASCII"
- #endif
- #if !HAVE_PQESCAPE_CONN
- #define PQescapeStringConn(conn, to, from, len, error) PQescapeString(to, from, len)
- #endif
- #if HAVE_PQESCAPELITERAL
- #define PGSQLescapeLiteral(conn, str, len) PQescapeLiteral(conn, str, len)
- #define PGSQLescapeIdentifier(conn, str, len) PQescapeIdentifier(conn, str, len)
- #define PGSQLfree(a) PQfreemem(a)
- #else
- #define PGSQLescapeLiteral(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 0)
- #define PGSQLescapeLiteral2(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 1)
- #define PGSQLescapeIdentifier(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 0, 0)
- #define PGSQLfree(a) efree(a)
- /* emulate libpq's PQescapeInternal() 9.0 or later */
- static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) {
- char *result, *rp, *s;
- size_t tmp_len;
- if (!conn) {
- return NULL;
- }
- /* allocate enough memory */
- rp = result = (char *)safe_emalloc(len, 2, 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */
- if (escape_literal) {
- size_t new_len;
- if (safe) {
- char *tmp = (char *)safe_emalloc(len, 2, 1);
- *rp++ = '\'';
- /* PQescapeString does not escape \, but it handles multibyte chars safely.
- This escape is incompatible with PQescapeLiteral. */
- new_len = PQescapeStringConn(conn, tmp, str, len, NULL);
- strncpy(rp, tmp, new_len);
- efree(tmp);
- rp += new_len;
- } else {
- char *encoding;
- /* This is compatible with PQescapeLiteral, but it cannot handle multbyte chars
- such as SJIS, BIG5. Raise warning and return NULL by checking
- client_encoding. */
- encoding = (char *) pg_encoding_to_char(PQclientEncoding(conn));
- if (!strncmp(encoding, "SJIS", sizeof("SJIS")-1) ||
- !strncmp(encoding, "SHIFT_JIS_2004", sizeof("SHIFT_JIS_2004")-1) ||
- !strncmp(encoding, "BIG5", sizeof("BIG5")-1) ||
- !strncmp(encoding, "GB18030", sizeof("GB18030")-1) ||
- !strncmp(encoding, "GBK", sizeof("GBK")-1) ||
- !strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) ||
- !strncmp(encoding, "UHC", sizeof("UHC")-1) ) {
- TSRMLS_FETCH();
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding);
- }
- /* check backslashes */
- tmp_len = strspn(str, "\\");
- if (tmp_len != len) {
- /* add " E" for escaping slashes */
- *rp++ = ' ';
- *rp++ = 'E';
- }
- *rp++ = '\'';
- for (s = (char *)str; s - str < len; ++s) {
- if (*s == '\'' || *s == '\\') {
- *rp++ = *s;
- *rp++ = *s;
- } else {
- *rp++ = *s;
- }
- }
- }
- *rp++ = '\'';
- } else {
- /* Identifier escape. */
- *rp++ = '"';
- for (s = (char *)str; s - str < len; ++s) {
- if (*s == '"') {
- *rp++ = '"';
- *rp++ = '"';
- } else {
- *rp++ = *s;
- }
- }
- *rp++ = '"';
- }
- *rp = '\0';
- return result;
- }
- #endif
- /* {{{ _php_pgsql_trim_message */
- static char * _php_pgsql_trim_message(const char *message, int *len)
- {
- register int i = strlen(message)-1;
- if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') {
- --i;
- }
- while (i>0 && (message[i] == '\r' || message[i] == '\n')) {
- --i;
- }
- ++i;
- if (len) {
- *len = i;
- }
- return estrndup(message, i);
- }
- /* }}} */
- /* {{{ _php_pgsql_trim_result */
- static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf)
- {
- return *buf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
- }
- /* }}} */
- #define PQErrorMessageTrim(pgsql, buf) _php_pgsql_trim_result(pgsql, buf)
- #define PHP_PQ_ERROR(text, pgsql) { \
- char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \
- efree(msgbuf); \
- } \
- /* {{{ php_pgsql_set_default_link
- */
- static void php_pgsql_set_default_link(int id TSRMLS_DC)
- {
- zend_list_addref(id);
- if (PGG(default_link) != -1) {
- zend_list_delete(PGG(default_link));
- }
- PGG(default_link) = id;
- }
- /* }}} */
- /* {{{ _close_pgsql_link
- */
- static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
- {
- PGconn *link = (PGconn *)rsrc->ptr;
- PGresult *res;
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- PQfinish(link);
- PGG(num_links)--;
- }
- /* }}} */
- /* {{{ _close_pgsql_plink
- */
- static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
- {
- PGconn *link = (PGconn *)rsrc->ptr;
- PGresult *res;
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- PQfinish(link);
- PGG(num_persistent)--;
- PGG(num_links)--;
- }
- /* }}} */
- /* {{{ _php_pgsql_notice_handler
- */
- static void _php_pgsql_notice_handler(void *resource_id, const char *message)
- {
- php_pgsql_notice *notice;
- TSRMLS_FETCH();
- if (! PGG(ignore_notices)) {
- notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice));
- notice->message = _php_pgsql_trim_message(message, (int *)¬ice->len);
- if (PGG(log_notices)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", notice->message);
- }
- zend_hash_index_update(&PGG(notices), (ulong)resource_id, (void **)¬ice, sizeof(php_pgsql_notice *), NULL);
- }
- }
- /* }}} */
- #define PHP_PGSQL_NOTICE_PTR_DTOR (void (*)(void *))_php_pgsql_notice_ptr_dtor
- /* {{{ _php_pgsql_notice_dtor
- */
- static void _php_pgsql_notice_ptr_dtor(void **ptr)
- {
- php_pgsql_notice *notice = (php_pgsql_notice *)*ptr;
- if (notice) {
- efree(notice->message);
- efree(notice);
- notice = NULL;
- }
- }
- /* }}} */
- /* {{{ _rollback_transactions
- */
- static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC)
- {
- PGconn *link;
- PGresult *res;
- int orig;
- if (Z_TYPE_P(rsrc) != le_plink)
- return 0;
- link = (PGconn *) rsrc->ptr;
- if (PQ_SETNONBLOCKING(link, 0)) {
- php_error_docref("ref.pgsql" TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- return -1;
- }
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
- if ((PQprotocolVersion(link) >= 3 && PQtransactionStatus(link) != PQTRANS_IDLE) || PQprotocolVersion(link) < 3)
- #endif
- {
- orig = PGG(ignore_notices);
- PGG(ignore_notices) = 1;
- #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
- res = PQexec(link,"ROLLBACK;");
- #else
- res = PQexec(link,"BEGIN;");
- PQclear(res);
- res = PQexec(link,"ROLLBACK;");
- #endif
- PQclear(res);
- PGG(ignore_notices) = orig;
- }
- return 0;
- }
- /* }}} */
- /* {{{ _free_ptr
- */
- static void _free_ptr(zend_rsrc_list_entry *rsrc TSRMLS_DC)
- {
- pgLofp *lofp = (pgLofp *)rsrc->ptr;
- efree(lofp);
- }
- /* }}} */
- /* {{{ _free_result
- */
- static void _free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
- {
- pgsql_result_handle *pg_result = (pgsql_result_handle *)rsrc->ptr;
- PQclear(pg_result->result);
- efree(pg_result);
- }
- /* }}} */
- static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t len)
- {
- size_t i;
- /* Handle edge case. Cannot be a escaped string */
- if (len <= 2) {
- return FAILURE;
- }
- /* Detect double qoutes */
- if (identifier[0] == '"' && identifier[len-1] == '"') {
- /* Detect wrong format of " inside of escaped string */
- for (i = 1; i < len-1; i++) {
- if (identifier[i] == '"' && (identifier[++i] != '"' || i == len-1)) {
- return FAILURE;
- }
- }
- } else {
- return FAILURE;
- }
- /* Escaped properly */
- return SUCCESS;
- }
- /* {{{ PHP_INI
- */
- PHP_INI_BEGIN()
- STD_PHP_INI_BOOLEAN( "pgsql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_persistent, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_ENTRY_EX("pgsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_pgsql_globals, pgsql_globals, display_link_numbers)
- STD_PHP_INI_ENTRY_EX("pgsql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_pgsql_globals, pgsql_globals, display_link_numbers)
- STD_PHP_INI_BOOLEAN( "pgsql.auto_reset_persistent", "0", PHP_INI_SYSTEM, OnUpdateBool, auto_reset_persistent, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_BOOLEAN( "pgsql.ignore_notice", "0", PHP_INI_ALL, OnUpdateBool, ignore_notices, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpdateBool, log_notices, zend_pgsql_globals, pgsql_globals)
- PHP_INI_END()
- /* }}} */
- /* {{{ PHP_GINIT_FUNCTION
- */
- static PHP_GINIT_FUNCTION(pgsql)
- {
- memset(pgsql_globals, 0, sizeof(zend_pgsql_globals));
- /* Initilize notice message hash at MINIT only */
- zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0);
- }
- /* }}} */
- /* {{{ PHP_MINIT_FUNCTION
- */
- PHP_MINIT_FUNCTION(pgsql)
- {
- REGISTER_INI_ENTRIES();
- le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number);
- le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number);
- le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number);
- le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number);
- le_string = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql string", module_number);
- #if HAVE_PG_CONFIG_H
- /* PG_VERSION - libpq version */
- REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", PG_VERSION, CONST_CS | CONST_PERSISTENT);
- REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", PG_VERSION_STR, CONST_CS | CONST_PERSISTENT);
- #endif
- /* For connection option */
- REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT);
- /* For pg_fetch_array() */
- REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT);
- /* For pg_connection_status() */
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_STARTED", CONNECTION_STARTED, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_CS | CONST_PERSISTENT);
- #ifdef CONNECTION_SSL_STARTUP
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_CS | CONST_PERSISTENT);
- #endif
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_CS | CONST_PERSISTENT);
- /* For pg_connect_poll() */
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_READING", PGRES_POLLING_READING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_WRITING", PGRES_POLLING_WRITING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_OK", PGRES_POLLING_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_ACTIVE", PGRES_POLLING_ACTIVE, CONST_CS | CONST_PERSISTENT);
- #if HAVE_PGTRANSACTIONSTATUS
- /* For pg_transaction_status() */
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_IDLE", PQTRANS_IDLE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_ACTIVE", PQTRANS_ACTIVE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INTRANS", PQTRANS_INTRANS, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INERROR", PQTRANS_INERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_UNKNOWN", PQTRANS_UNKNOWN, CONST_CS | CONST_PERSISTENT);
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- /* For pg_set_error_verbosity() */
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_TERSE", PQERRORS_TERSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_DEFAULT", PQERRORS_DEFAULT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_VERBOSE", PQERRORS_VERBOSE, CONST_CS | CONST_PERSISTENT);
- #endif
- /* For lo_seek() */
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
- /* For pg_result_status() return value type */
- REGISTER_LONG_CONSTANT("PGSQL_STATUS_LONG", PGSQL_STATUS_LONG, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_STATUS_STRING", PGSQL_STATUS_STRING, CONST_CS | CONST_PERSISTENT);
- /* For pg_result_status() return value */
- REGISTER_LONG_CONSTANT("PGSQL_EMPTY_QUERY", PGRES_EMPTY_QUERY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COMMAND_OK", PGRES_COMMAND_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TUPLES_OK", PGRES_TUPLES_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COPY_OUT", PGRES_COPY_OUT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COPY_IN", PGRES_COPY_IN, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_BAD_RESPONSE", PGRES_BAD_RESPONSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NONFATAL_ERROR", PGRES_NONFATAL_ERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_FATAL_ERROR", PGRES_FATAL_ERROR, CONST_CS | CONST_PERSISTENT);
- #if HAVE_PQRESULTERRORFIELD
- /* For pg_result_error_field() field codes */
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SEVERITY", PG_DIAG_SEVERITY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SQLSTATE", PG_DIAG_SQLSTATE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_PRIMARY", PG_DIAG_MESSAGE_PRIMARY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_DETAIL", PG_DIAG_MESSAGE_DETAIL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_HINT", PG_DIAG_MESSAGE_HINT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_STATEMENT_POSITION", PG_DIAG_STATEMENT_POSITION, CONST_CS | CONST_PERSISTENT);
- #ifdef PG_DIAG_INTERNAL_POSITION
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_POSITION", PG_DIAG_INTERNAL_POSITION, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_INTERNAL_QUERY
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_QUERY", PG_DIAG_INTERNAL_QUERY, CONST_CS | CONST_PERSISTENT);
- #endif
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONTEXT", PG_DIAG_CONTEXT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FILE", PG_DIAG_SOURCE_FILE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_LINE", PG_DIAG_SOURCE_LINE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FUNCTION", PG_DIAG_SOURCE_FUNCTION, CONST_CS | CONST_PERSISTENT);
- #endif
- /* pg_convert options */
- REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_DEFAULT", PGSQL_CONV_IGNORE_DEFAULT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONV_FORCE_NULL", PGSQL_CONV_FORCE_NULL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_NOT_NULL", PGSQL_CONV_IGNORE_NOT_NULL, CONST_CS | CONST_PERSISTENT);
- /* pg_insert/update/delete/select options */
- REGISTER_LONG_CONSTANT("PGSQL_DML_ESCAPE", PGSQL_DML_ESCAPE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_NO_CONV", PGSQL_DML_NO_CONV, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MSHUTDOWN_FUNCTION
- */
- PHP_MSHUTDOWN_FUNCTION(pgsql)
- {
- UNREGISTER_INI_ENTRIES();
- zend_hash_destroy(&PGG(notices));
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_RINIT_FUNCTION
- */
- PHP_RINIT_FUNCTION(pgsql)
- {
- PGG(default_link)=-1;
- PGG(num_links) = PGG(num_persistent);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_RSHUTDOWN_FUNCTION
- */
- PHP_RSHUTDOWN_FUNCTION(pgsql)
- {
- /* clean up notice messages */
- zend_hash_clean(&PGG(notices));
- /* clean up persistent connection */
- zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions TSRMLS_CC);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MINFO_FUNCTION
- */
- PHP_MINFO_FUNCTION(pgsql)
- {
- char buf[256];
- php_info_print_table_start();
- php_info_print_table_header(2, "PostgreSQL Support", "enabled");
- #if HAVE_PG_CONFIG_H
- php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION);
- php_info_print_table_row(2, "PostgreSQL(libpq) ", PG_VERSION_STR);
- #ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
- php_info_print_table_row(2, "Multibyte character support", "enabled");
- #else
- php_info_print_table_row(2, "Multibyte character support", "disabled");
- #endif
- #if defined(USE_SSL) || defined(USE_OPENSSL)
- php_info_print_table_row(2, "SSL support", "enabled");
- #else
- php_info_print_table_row(2, "SSL support", "disabled");
- #endif
- #endif /* HAVE_PG_CONFIG_H */
- snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent));
- php_info_print_table_row(2, "Active Persistent Links", buf);
- snprintf(buf, sizeof(buf), "%ld", PGG(num_links));
- php_info_print_table_row(2, "Active Links", buf);
- php_info_print_table_end();
- DISPLAY_INI_ENTRIES();
- }
- /* }}} */
- /* {{{ php_pgsql_do_connect
- */
- static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
- {
- char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL;
- PGconn *pgsql;
- smart_str str = {0};
- zval **args[5];
- int i, connect_type = 0;
- PGresult *pg_result;
- if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5
- || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- smart_str_appends(&str, "pgsql");
- for (i = 0; i < ZEND_NUM_ARGS(); i++) {
- /* make sure that the PGSQL_CONNECT_FORCE_NEW bit is not part of the hash so that subsequent connections
- * can re-use this connection. Bug #39979
- */
- if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE_PP(args[i]) == IS_LONG) {
- if (Z_LVAL_PP(args[1]) == PGSQL_CONNECT_FORCE_NEW) {
- continue;
- } else if (Z_LVAL_PP(args[1]) & PGSQL_CONNECT_FORCE_NEW) {
- smart_str_append_long(&str, Z_LVAL_PP(args[1]) ^ PGSQL_CONNECT_FORCE_NEW);
- }
- }
- convert_to_string_ex(args[i]);
- smart_str_appendc(&str, '_');
- smart_str_appendl(&str, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i]));
- }
- smart_str_0(&str);
- if (ZEND_NUM_ARGS() == 1) { /* new style, using connection string */
- connstring = Z_STRVAL_PP(args[0]);
- } else if (ZEND_NUM_ARGS() == 2 ) { /* Safe to add conntype_option, since 2 args was illegal */
- connstring = Z_STRVAL_PP(args[0]);
- convert_to_long_ex(args[1]);
- connect_type = Z_LVAL_PP(args[1]);
- } else {
- host = Z_STRVAL_PP(args[0]);
- port = Z_STRVAL_PP(args[1]);
- dbname = Z_STRVAL_PP(args[ZEND_NUM_ARGS()-1]);
- switch (ZEND_NUM_ARGS()) {
- case 5:
- tty = Z_STRVAL_PP(args[3]);
- /* fall through */
- case 4:
- options = Z_STRVAL_PP(args[2]);
- break;
- }
- }
- if (persistent && PGG(allow_persistent)) {
- zend_rsrc_list_entry *le;
- /* try to find if we already have this link in our persistent list */
- if (zend_hash_find(&EG(persistent_list), str.c, str.len+1, (void **) &le)==FAILURE) { /* we don't */
- zend_rsrc_list_entry new_le;
- if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Cannot create new link. Too many open links (%ld)", PGG(num_links));
- goto err;
- }
- if (PGG(max_persistent)!=-1 && PGG(num_persistent)>=PGG(max_persistent)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Cannot create new link. Too many open persistent links (%ld)", PGG(num_persistent));
- goto err;
- }
- /* create the link */
- if (connstring) {
- pgsql=PQconnectdb(connstring);
- } else {
- pgsql=PQsetdb(host,port,options,tty,dbname);
- }
- if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql)
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- /* hash it up */
- Z_TYPE(new_le) = le_plink;
- new_le.ptr = pgsql;
- if (zend_hash_update(&EG(persistent_list), str.c, str.len+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
- goto err;
- }
- PGG(num_links)++;
- PGG(num_persistent)++;
- } else { /* we do */
- if (Z_TYPE_P(le) != le_plink) {
- RETURN_FALSE;
- }
- /* ensure that the link did not die */
- if (PGG(auto_reset_persistent) & 1) {
- /* need to send & get something from backend to
- make sure we catch CONNECTION_BAD every time */
- PGresult *pg_result;
- pg_result = PQexec(le->ptr, "select 1");
- PQclear(pg_result);
- }
- if (PQstatus(le->ptr)==CONNECTION_BAD) { /* the link died */
- if (le->ptr == NULL) {
- if (connstring) {
- le->ptr=PQconnectdb(connstring);
- } else {
- le->ptr=PQsetdb(host,port,options,tty,dbname);
- }
- }
- else {
- PQreset(le->ptr);
- }
- if (le->ptr==NULL || PQstatus(le->ptr)==CONNECTION_BAD) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"PostgreSQL link lost, unable to reconnect");
- zend_hash_del(&EG(persistent_list),str.c,str.len+1);
- goto err;
- }
- }
- pgsql = (PGconn *) le->ptr;
- #if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
- if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 7.2) {
- #else
- if (atof(PG_VERSION) >= 7.2) {
- #endif
- pg_result = PQexec(pgsql, "RESET ALL;");
- PQclear(pg_result);
- }
- }
- ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink);
- } else { /* Non persistent connection */
- zend_rsrc_list_entry *index_ptr,new_index_ptr;
- /* first we check the hash for the hashed_details key. if it exists,
- * it should point us to the right offset where the actual pgsql link sits.
- * if it doesn't, open a new pgsql link, add it to the resource list,
- * and add a pointer to it with hashed_details as the key.
- */
- if (!(connect_type & PGSQL_CONNECT_FORCE_NEW)
- && zend_hash_find(&EG(regular_list),str.c,str.len+1,(void **) &index_ptr)==SUCCESS) {
- int type;
- ulong link;
- void *ptr;
- if (Z_TYPE_P(index_ptr) != le_index_ptr) {
- RETURN_FALSE;
- }
- link = (ulong) index_ptr->ptr;
- ptr = zend_list_find(link,&type); /* check if the link is still there */
- if (ptr && (type==le_link || type==le_plink)) {
- Z_LVAL_P(return_value) = link;
- zend_list_addref(link);
- php_pgsql_set_default_link(link TSRMLS_CC);
- Z_TYPE_P(return_value) = IS_RESOURCE;
- goto cleanup;
- } else {
- zend_hash_del(&EG(regular_list),str.c,str.len+1);
- }
- }
- if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links));
- goto err;
- }
- /* Non-blocking connect */
- if (connect_type & PGSQL_CONNECT_ASYNC) {
- if (connstring) {
- pgsql = PQconnectStart(connstring);
- if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql);
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection string required for async connections");
- goto err;
- }
- } else {
- if (connstring) {
- pgsql = PQconnectdb(connstring);
- } else {
- pgsql = PQsetdb(host,port,options,tty,dbname);
- }
- if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql);
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- }
- /* add it to the list */
- ZEND_REGISTER_RESOURCE(return_value, pgsql, le_link);
- /* add it to the hash */
- new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
- Z_TYPE(new_index_ptr) = le_index_ptr;
- if (zend_hash_update(&EG(regular_list),str.c,str.len+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
- goto err;
- }
- PGG(num_links)++;
- }
- /* set notice processor */
- if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) {
- PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)Z_RESVAL_P(return_value));
- }
- php_pgsql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
- cleanup:
- smart_str_free(&str);
- return;
- err:
- smart_str_free(&str);
- RETURN_FALSE;
- }
- /* }}} */
- #if 0
- /* {{{ php_pgsql_get_default_link
- */
- static int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
- {
- if (PGG(default_link)==-1) { /* no link opened yet, implicitly open one */
- ht = 0;
- php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
- }
- return PGG(default_link);
- }
- /* }}} */
- #endif
- /* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)
- Open a PostgreSQL connection */
- PHP_FUNCTION(pg_connect)
- {
- php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
- }
- /* }}} */
- /* {{{ proto resource pg_connect_poll(resource connection)
- Poll the status of an in-progress async PostgreSQL connection attempt*/
- PHP_FUNCTION(pg_connect_poll)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- return;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- ret = PQconnectPoll(pgsql);
- RETURN_LONG(ret);
- }
- /* }}} */
- /* {{{ proto resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database)
- Open a persistent PostgreSQL connection */
- PHP_FUNCTION(pg_pconnect)
- {
- php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
- }
- /* }}} */
- /* {{{ proto bool pg_close([resource connection])
- Close a PostgreSQL connection */
- PHP_FUNCTION(pg_close)
- {
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
- return;
- }
- if (argc == 0) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (id==-1) { /* explicit resource number */
- zend_list_delete(Z_RESVAL_P(pgsql_link));
- }
- if (id!=-1
- || (pgsql_link && Z_RESVAL_P(pgsql_link)==PGG(default_link))) {
- zend_list_delete(PGG(default_link));
- PGG(default_link) = -1;
- }
- RETURN_TRUE;
- }
- /* }}} */
- #define PHP_PG_DBNAME 1
- #define PHP_PG_ERROR_MESSAGE 2
- #define PHP_PG_OPTIONS 3
- #define PHP_PG_PORT 4
- #define PHP_PG_TTY 5
- #define PHP_PG_HOST 6
- #define PHP_PG_VERSION 7
- /* {{{ php_pgsql_get_link_info
- */
- static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
- {
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- char *msgbuf;
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
- return;
- }
- if (argc == 0) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- switch(entry_type) {
- case PHP_PG_DBNAME:
- Z_STRVAL_P(return_value) = PQdb(pgsql);
- break;
- case PHP_PG_ERROR_MESSAGE:
- RETURN_STRING(PQErrorMessageTrim(pgsql, &msgbuf), 0);
- return;
- case PHP_PG_OPTIONS:
- Z_STRVAL_P(return_value) = PQoptions(pgsql);
- break;
- case PHP_PG_PORT:
- Z_STRVAL_P(return_value) = PQport(pgsql);
- break;
- case PHP_PG_TTY:
- Z_STRVAL_P(return_value) = PQtty(pgsql);
- break;
- case PHP_PG_HOST:
- Z_STRVAL_P(return_value) = PQhost(pgsql);
- break;
- case PHP_PG_VERSION:
- array_init(return_value);
- add_assoc_string(return_value, "client", PG_VERSION, 1);
- #if HAVE_PQPROTOCOLVERSION
- add_assoc_long(return_value, "protocol", PQprotocolVersion(pgsql));
- #if HAVE_PQPARAMETERSTATUS
- if (PQprotocolVersion(pgsql) >= 3) {
- /* 8.0 or grater supports protorol version 3 */
- char *tmp;
- add_assoc_string(return_value, "server", (char*)PQparameterStatus(pgsql, "server_version"), 1);
- tmp = (char*)PQparameterStatus(pgsql, "server_encoding");
- add_assoc_string(return_value, "server_encoding", tmp, 1);
- tmp = (char*)PQparameterStatus(pgsql, "client_encoding");
- add_assoc_string(return_value, "client_encoding", tmp, 1);
- tmp = (char*)PQparameterStatus(pgsql, "is_superuser");
- add_assoc_string(return_value, "is_superuser", tmp, 1);
- tmp = (char*)PQparameterStatus(pgsql, "session_authorization");
- add_assoc_string(return_value, "session_authorization", tmp, 1);
- tmp = (char*)PQparameterStatus(pgsql, "DateStyle");
- add_assoc_string(return_value, "DateStyle", tmp, 1);
- tmp = (char*)PQparameterStatus(pgsql, "IntervalStyle");
- add_assoc_string(return_value, "IntervalStyle", tmp ? tmp : "", 1);
- tmp = (char*)PQparameterStatus(pgsql, "TimeZone");
- add_assoc_string(return_value, "TimeZone", tmp ? tmp : "", 1);
- tmp = (char*)PQparameterStatus(pgsql, "integer_datetimes");
- add_assoc_string(return_value, "integer_datetimes", tmp ? tmp : "", 1);
- tmp = (char*)PQparameterStatus(pgsql, "standard_conforming_strings");
- add_assoc_string(return_value, "standard_conforming_strings", tmp ? tmp : "", 1);
- tmp = (char*)PQparameterStatus(pgsql, "application_name");
- add_assoc_string(return_value, "application_name", tmp ? tmp : "", 1);
- }
- #endif
- #endif
- return;
- default:
- RETURN_FALSE;
- }
- if (Z_STRVAL_P(return_value)) {
- Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
- Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value));
- } else {
- Z_STRLEN_P(return_value) = 0;
- Z_STRVAL_P(return_value) = (char *) estrdup("");
- }
- Z_TYPE_P(return_value) = IS_STRING;
- }
- /* }}} */
- /* {{{ proto string pg_dbname([resource connection])
- Get the database name */
- PHP_FUNCTION(pg_dbname)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_DBNAME);
- }
- /* }}} */
- /* {{{ proto string pg_last_error([resource connection])
- Get the error message string */
- PHP_FUNCTION(pg_last_error)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_ERROR_MESSAGE);
- }
- /* }}} */
- /* {{{ proto string pg_options([resource connection])
- Get the options associated with the connection */
- PHP_FUNCTION(pg_options)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_OPTIONS);
- }
- /* }}} */
- /* {{{ proto int pg_port([resource connection])
- Return the port number associated with the connection */
- PHP_FUNCTION(pg_port)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_PORT);
- }
- /* }}} */
- /* {{{ proto string pg_tty([resource connection])
- Return the tty name associated with the connection */
- PHP_FUNCTION(pg_tty)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_TTY);
- }
- /* }}} */
- /* {{{ proto string pg_host([resource connection])
- Returns the host name associated with the connection */
- PHP_FUNCTION(pg_host)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_HOST);
- }
- /* }}} */
- /* {{{ proto array pg_version([resource connection])
- Returns an array with client, protocol and server version (when available) */
- PHP_FUNCTION(pg_version)
- {
- php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_VERSION);
- }
- /* }}} */
- #if HAVE_PQPARAMETERSTATUS
- /* {{{ proto string|false pg_parameter_status([resource connection,] string param_name)
- Returns the value of a server parameter */
- PHP_FUNCTION(pg_parameter_status)
- {
- zval *pgsql_link;
- int id;
- PGconn *pgsql;
- char *param;
- int len;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, ¶m, &len) == SUCCESS) {
- id = -1;
- } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", ¶m, &len) == SUCCESS) {
- pgsql_link = NULL;
- id = PGG(default_link);
- } else {
- RETURN_FALSE;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- param = (char*)PQparameterStatus(pgsql, param);
- if (param) {
- RETURN_STRING(param, 1);
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- #endif
- /* {{{ proto bool pg_ping([resource connection])
- Ping database. If connection is bad, try to reconnect. */
- PHP_FUNCTION(pg_ping)
- {
- zval *pgsql_link;
- int id;
- PGconn *pgsql;
- PGresult *res;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == SUCCESS) {
- id = -1;
- } else {
- pgsql_link = NULL;
- id = PGG(default_link);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- /* ping connection */
- res = PQexec(pgsql, "SELECT 1;");
- PQclear(res);
- /* check status. */
- if (PQstatus(pgsql) == CONNECTION_OK)
- RETURN_TRUE;
- /* reset connection if it's broken */
- PQreset(pgsql);
- if (PQstatus(pgsql) == CONNECTION_OK) {
- RETURN_TRUE;
- }
- RETURN_FALSE;
- }
- /* }}} */
- /* {{{ proto resource pg_query([resource connection,] string query)
- Execute a query */
- PHP_FUNCTION(pg_query)
- {
- zval *pgsql_link = NULL;
- char *query;
- int id = -1, query_len, argc = ZEND_NUM_ARGS();
- int leftover = 0;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- pgsql_result_handle *pg_result;
- if (argc == 1) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode");
- RETURN_FALSE;
- }
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- leftover = 1;
- }
- if (leftover) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first");
- }
- pgsql_result = PQexec(pgsql, query);
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQclear(pgsql_result);
- PQreset(pgsql);
- pgsql_result = PQexec(pgsql, query);
- }
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- switch (status) {
- case PGRES_EMPTY_QUERY:
- case PGRES_BAD_RESPONSE:
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- PQclear(pgsql_result);
- RETURN_FALSE;
- break;
- case PGRES_COMMAND_OK: /* successful command that did not return rows */
- default:
- if (pgsql_result) {
- pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pg_result->conn = pgsql;
- pg_result->result = pgsql_result;
- pg_result->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- break;
- }
- }
- /* }}} */
- #if HAVE_PQEXECPARAMS || HAVE_PQEXECPREPARED || HAVE_PQSENDQUERYPARAMS || HAVE_PQSENDQUERYPREPARED
- /* {{{ _php_pgsql_free_params */
- static void _php_pgsql_free_params(char **params, int num_params)
- {
- if (num_params > 0) {
- int i;
- for (i = 0; i < num_params; i++) {
- if (params[i]) {
- efree(params[i]);
- }
- }
- efree(params);
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQEXECPARAMS
- /* {{{ proto resource pg_query_params([resource connection,] string query, array params)
- Execute a query */
- PHP_FUNCTION(pg_query_params)
- {
- zval *pgsql_link = NULL;
- zval *pv_param_arr, **tmp;
- char *query;
- int query_len, id = -1, argc = ZEND_NUM_ARGS();
- int leftover = 0;
- int num_params = 0;
- char **params = NULL;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- pgsql_result_handle *pg_result;
- if (argc == 2) {
- if (zend_parse_parameters(argc TSRMLS_CC, "sa", &query, &query_len, &pv_param_arr) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode");
- RETURN_FALSE;
- }
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- leftover = 1;
- }
- if (leftover) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first");
- }
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr));
- num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr));
- if (num_params > 0) {
- int i = 0;
- params = (char **)safe_emalloc(sizeof(char *), num_params, 0);
- for(i = 0; i < num_params; i++) {
- if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- if (Z_TYPE_PP(tmp) == IS_NULL) {
- params[i] = NULL;
- } else {
- zval tmp_val = **tmp;
- zval_copy_ctor(&tmp_val);
- convert_to_cstring(&tmp_val);
- if (Z_TYPE(tmp_val) != IS_STRING) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
- zval_dtor(&tmp_val);
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
- zval_dtor(&tmp_val);
- }
- zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr));
- }
- }
- pgsql_result = PQexecParams(pgsql, query, num_params,
- NULL, (const char * const *)params, NULL, NULL, 0);
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQclear(pgsql_result);
- PQreset(pgsql);
- pgsql_result = PQexecParams(pgsql, query, num_params,
- NULL, (const char * const *)params, NULL, NULL, 0);
- }
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- _php_pgsql_free_params(params, num_params);
- switch (status) {
- case PGRES_EMPTY_QUERY:
- case PGRES_BAD_RESPONSE:
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- PQclear(pgsql_result);
- RETURN_FALSE;
- break;
- case PGRES_COMMAND_OK: /* successful command that did not return rows */
- default:
- if (pgsql_result) {
- pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pg_result->conn = pgsql;
- pg_result->result = pgsql_result;
- pg_result->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- break;
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQPREPARE
- /* {{{ proto resource pg_prepare([resource connection,] string stmtname, string query)
- Prepare a query for future execution */
- PHP_FUNCTION(pg_prepare)
- {
- zval *pgsql_link = NULL;
- char *query, *stmtname;
- int query_len, stmtname_len, id = -1, argc = ZEND_NUM_ARGS();
- int leftover = 0;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- pgsql_result_handle *pg_result;
- if (argc == 2) {
- if (zend_parse_parameters(argc TSRMLS_CC, "ss", &stmtname, &stmtname_len, &query, &query_len) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode");
- RETURN_FALSE;
- }
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- leftover = 1;
- }
- if (leftover) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first");
- }
- pgsql_result = PQprepare(pgsql, stmtname, query, 0, NULL);
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQclear(pgsql_result);
- PQreset(pgsql);
- pgsql_result = PQprepare(pgsql, stmtname, query, 0, NULL);
- }
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- switch (status) {
- case PGRES_EMPTY_QUERY:
- case PGRES_BAD_RESPONSE:
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- PQclear(pgsql_result);
- RETURN_FALSE;
- break;
- case PGRES_COMMAND_OK: /* successful command that did not return rows */
- default:
- if (pgsql_result) {
- pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pg_result->conn = pgsql;
- pg_result->result = pgsql_result;
- pg_result->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- break;
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQEXECPREPARED
- /* {{{ proto resource pg_execute([resource connection,] string stmtname, array params)
- Execute a prepared query */
- PHP_FUNCTION(pg_execute)
- {
- zval *pgsql_link = NULL;
- zval *pv_param_arr, **tmp;
- char *stmtname;
- int stmtname_len, id = -1, argc = ZEND_NUM_ARGS();
- int leftover = 0;
- int num_params = 0;
- char **params = NULL;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- pgsql_result_handle *pg_result;
- if (argc == 2) {
- if (zend_parse_parameters(argc TSRMLS_CC, "sa/", &stmtname, &stmtname_len, &pv_param_arr)==FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa/", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode");
- RETURN_FALSE;
- }
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- leftover = 1;
- }
- if (leftover) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first");
- }
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr));
- num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr));
- if (num_params > 0) {
- int i = 0;
- params = (char **)safe_emalloc(sizeof(char *), num_params, 0);
- for(i = 0; i < num_params; i++) {
- if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- if (Z_TYPE_PP(tmp) == IS_NULL) {
- params[i] = NULL;
- } else {
- zval tmp_val = **tmp;
- zval_copy_ctor(&tmp_val);
- convert_to_string(&tmp_val);
- if (Z_TYPE(tmp_val) != IS_STRING) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
- zval_dtor(&tmp_val);
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
- zval_dtor(&tmp_val);
- }
- zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr));
- }
- }
- pgsql_result = PQexecPrepared(pgsql, stmtname, num_params,
- (const char * const *)params, NULL, NULL, 0);
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQclear(pgsql_result);
- PQreset(pgsql);
- pgsql_result = PQexecPrepared(pgsql, stmtname, num_params,
- (const char * const *)params, NULL, NULL, 0);
- }
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- _php_pgsql_free_params(params, num_params);
- switch (status) {
- case PGRES_EMPTY_QUERY:
- case PGRES_BAD_RESPONSE:
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- PQclear(pgsql_result);
- RETURN_FALSE;
- break;
- case PGRES_COMMAND_OK: /* successful command that did not return rows */
- default:
- if (pgsql_result) {
- pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pg_result->conn = pgsql;
- pg_result->result = pgsql_result;
- pg_result->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- break;
- }
- }
- /* }}} */
- #endif
- #define PHP_PG_NUM_ROWS 1
- #define PHP_PG_NUM_FIELDS 2
- #define PHP_PG_CMD_TUPLES 3
- /* {{{ php_pgsql_get_result_info
- */
- static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
- {
- zval *result;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- switch (entry_type) {
- case PHP_PG_NUM_ROWS:
- Z_LVAL_P(return_value) = PQntuples(pgsql_result);
- break;
- case PHP_PG_NUM_FIELDS:
- Z_LVAL_P(return_value) = PQnfields(pgsql_result);
- break;
- case PHP_PG_CMD_TUPLES:
- #if HAVE_PQCMDTUPLES
- Z_LVAL_P(return_value) = atoi(PQcmdTuples(pgsql_result));
- #else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported under this build");
- Z_LVAL_P(return_value) = 0;
- #endif
- break;
- default:
- RETURN_FALSE;
- }
- Z_TYPE_P(return_value) = IS_LONG;
- }
- /* }}} */
- /* {{{ proto int pg_num_rows(resource result)
- Return the number of rows in the result */
- PHP_FUNCTION(pg_num_rows)
- {
- php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_ROWS);
- }
- /* }}} */
- /* {{{ proto int pg_num_fields(resource result)
- Return the number of fields in the result */
- PHP_FUNCTION(pg_num_fields)
- {
- php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_FIELDS);
- }
- /* }}} */
- #if HAVE_PQCMDTUPLES
- /* {{{ proto int pg_affected_rows(resource result)
- Returns the number of affected tuples */
- PHP_FUNCTION(pg_affected_rows)
- {
- php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_CMD_TUPLES);
- }
- /* }}} */
- #endif
- /* {{{ proto string pg_last_notice(resource connection)
- Returns the last notice set by the backend */
- PHP_FUNCTION(pg_last_notice)
- {
- zval *pgsql_link;
- PGconn *pg_link;
- int id = -1;
- php_pgsql_notice **notice;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- return;
- }
- /* Just to check if user passed valid resoruce */
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (zend_hash_index_find(&PGG(notices), Z_RESVAL_P(pgsql_link), (void **)¬ice) == FAILURE) {
- RETURN_FALSE;
- }
- RETURN_STRINGL((*notice)->message, (*notice)->len, 1);
- }
- /* }}} */
- /* {{{ get_field_name
- */
- static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC)
- {
- PGresult *result;
- smart_str str = {0};
- zend_rsrc_list_entry *field_type;
- char *ret=NULL;
- /* try to lookup the type in the resource list */
- smart_str_appends(&str, "pgsql_oid_");
- smart_str_append_unsigned(&str, oid);
- smart_str_0(&str);
- if (zend_hash_find(list,str.c,str.len+1,(void **) &field_type)==SUCCESS) {
- ret = estrdup((char *)field_type->ptr);
- } else { /* hash all oid's */
- int i,num_rows;
- int oid_offset,name_offset;
- char *tmp_oid, *end_ptr, *tmp_name;
- zend_rsrc_list_entry new_oid_entry;
- if ((result = PQexec(pgsql,"select oid,typname from pg_type")) == NULL || PQresultStatus(result) != PGRES_TUPLES_OK) {
- if (result) {
- PQclear(result);
- }
- smart_str_free(&str);
- return STR_EMPTY_ALLOC();
- }
- num_rows = PQntuples(result);
- oid_offset = PQfnumber(result,"oid");
- name_offset = PQfnumber(result,"typname");
- for (i=0; i<num_rows; i++) {
- if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) {
- continue;
- }
- str.len = 0;
- smart_str_appends(&str, "pgsql_oid_");
- smart_str_appends(&str, tmp_oid);
- smart_str_0(&str);
- if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) {
- continue;
- }
- Z_TYPE(new_oid_entry) = le_string;
- new_oid_entry.ptr = estrdup(tmp_name);
- zend_hash_update(list,str.c,str.len+1,(void *) &new_oid_entry, sizeof(zend_rsrc_list_entry), NULL);
- if (!ret && strtoul(tmp_oid, &end_ptr, 10)==oid) {
- ret = estrdup(tmp_name);
- }
- }
- PQclear(result);
- }
- smart_str_free(&str);
- return ret;
- }
- /* }}} */
- #ifdef HAVE_PQFTABLE
- /* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only])
- Returns the name of the table field belongs to, or table's oid if oid_only is true */
- PHP_FUNCTION(pg_field_table)
- {
- zval *result;
- pgsql_result_handle *pg_result;
- long fnum = -1;
- zend_bool return_oid = 0;
- Oid oid;
- smart_str hash_key = {0};
- char *table_name;
- zend_rsrc_list_entry *field_table;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|b", &result, &fnum, &return_oid) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- if (fnum < 0 || fnum >= PQnfields(pg_result->result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified");
- RETURN_FALSE;
- }
- oid = PQftable(pg_result->result, fnum);
- if (InvalidOid == oid) {
- RETURN_FALSE;
- }
- if (return_oid) {
- #if UINT_MAX > LONG_MAX /* Oid is unsigned int, we don't need this code, where LONG is wider */
- if (oid > LONG_MAX) {
- smart_str oidstr = {0};
- smart_str_append_unsigned(&oidstr, oid);
- smart_str_0(&oidstr);
- RETURN_STRINGL(oidstr.c, oidstr.len, 0);
- } else
- #endif
- RETURN_LONG((long)oid);
- }
- /* try to lookup the table name in the resource list */
- smart_str_appends(&hash_key, "pgsql_table_oid_");
- smart_str_append_unsigned(&hash_key, oid);
- smart_str_0(&hash_key);
- if (zend_hash_find(&EG(regular_list), hash_key.c, hash_key.len+1, (void **) &field_table) == SUCCESS) {
- smart_str_free(&hash_key);
- RETURN_STRING((char *)field_table->ptr, 1);
- } else { /* Not found, lookup by querying PostgreSQL system tables */
- PGresult *tmp_res;
- smart_str querystr = {0};
- zend_rsrc_list_entry new_field_table;
- smart_str_appends(&querystr, "select relname from pg_class where oid=");
- smart_str_append_unsigned(&querystr, oid);
- smart_str_0(&querystr);
- if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
- if (tmp_res) {
- PQclear(tmp_res);
- }
- smart_str_free(&querystr);
- smart_str_free(&hash_key);
- RETURN_FALSE;
- }
- smart_str_free(&querystr);
- if ((table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) {
- PQclear(tmp_res);
- smart_str_free(&hash_key);
- RETURN_FALSE;
- }
- Z_TYPE(new_field_table) = le_string;
- new_field_table.ptr = estrdup(table_name);
- zend_hash_update(&EG(regular_list), hash_key.c, hash_key.len+1, (void *) &new_field_table, sizeof(zend_rsrc_list_entry), NULL);
- smart_str_free(&hash_key);
- PQclear(tmp_res);
- RETURN_STRING(table_name, 1);
- }
- }
- /* }}} */
- #endif
- #define PHP_PG_FIELD_NAME 1
- #define PHP_PG_FIELD_SIZE 2
- #define PHP_PG_FIELD_TYPE 3
- #define PHP_PG_FIELD_TYPE_OID 4
- /* {{{ php_pgsql_get_field_info
- */
- static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
- {
- zval *result;
- long field;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- Oid oid;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (field < 0 || field >= PQnfields(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified");
- RETURN_FALSE;
- }
- switch (entry_type) {
- case PHP_PG_FIELD_NAME:
- Z_STRVAL_P(return_value) = PQfname(pgsql_result, field);
- Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
- Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value));
- Z_TYPE_P(return_value) = IS_STRING;
- break;
- case PHP_PG_FIELD_SIZE:
- Z_LVAL_P(return_value) = PQfsize(pgsql_result, field);
- Z_TYPE_P(return_value) = IS_LONG;
- break;
- case PHP_PG_FIELD_TYPE:
- Z_STRVAL_P(return_value) = get_field_name(pg_result->conn, PQftype(pgsql_result, field), &EG(regular_list) TSRMLS_CC);
- Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
- Z_TYPE_P(return_value) = IS_STRING;
- break;
- case PHP_PG_FIELD_TYPE_OID:
- oid = PQftype(pgsql_result, field);
- #if UINT_MAX > LONG_MAX
- if (oid > LONG_MAX) {
- smart_str s = {0};
- smart_str_append_unsigned(&s, oid);
- smart_str_0(&s);
- Z_STRVAL_P(return_value) = s.c;
- Z_STRLEN_P(return_value) = s.len;
- Z_TYPE_P(return_value) = IS_STRING;
- } else
- #endif
- {
- Z_LVAL_P(return_value) = (long)oid;
- Z_TYPE_P(return_value) = IS_LONG;
- }
- break;
- default:
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ proto string pg_field_name(resource result, int field_number)
- Returns the name of the field */
- PHP_FUNCTION(pg_field_name)
- {
- php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_NAME);
- }
- /* }}} */
- /* {{{ proto int pg_field_size(resource result, int field_number)
- Returns the internal size of the field */
- PHP_FUNCTION(pg_field_size)
- {
- php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_SIZE);
- }
- /* }}} */
- /* {{{ proto string pg_field_type(resource result, int field_number)
- Returns the type name for the given field */
- PHP_FUNCTION(pg_field_type)
- {
- php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_TYPE);
- }
- /* }}} */
- /* {{{ proto string pg_field_type_oid(resource result, int field_number)
- Returns the type oid for the given field */
- PHP_FUNCTION(pg_field_type_oid)
- {
- php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_TYPE_OID);
- }
- /* }}} */
- /* {{{ proto int pg_field_num(resource result, string field_name)
- Returns the field number of the named field */
- PHP_FUNCTION(pg_field_num)
- {
- zval *result;
- char *field;
- int field_len;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &result, &field, &field_len) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- Z_LVAL_P(return_value) = PQfnumber(pgsql_result, field);
- Z_TYPE_P(return_value) = IS_LONG;
- }
- /* }}} */
- /* {{{ proto mixed pg_fetch_result(resource result, [int row_number,] mixed field_name)
- Returns values from a result identifier */
- PHP_FUNCTION(pg_fetch_result)
- {
- zval *result, **field=NULL;
- long row;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- int field_offset, pgsql_row, argc = ZEND_NUM_ARGS();
- if (argc == 2) {
- if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) {
- return;
- }
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rlZ", &result, &row, &field) == FAILURE) {
- return;
- }
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (argc == 2) {
- if (pg_result->row < 0) {
- pg_result->row = 0;
- }
- pgsql_row = pg_result->row;
- if (pgsql_row >= PQntuples(pgsql_result)) {
- RETURN_FALSE;
- }
- } else {
- pgsql_row = row;
- if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld",
- row, Z_LVAL_P(result));
- RETURN_FALSE;
- }
- }
- switch(Z_TYPE_PP(field)) {
- case IS_STRING:
- field_offset = PQfnumber(pgsql_result, Z_STRVAL_PP(field));
- break;
- default:
- convert_to_long_ex(field);
- field_offset = Z_LVAL_PP(field);
- break;
- }
- if (field_offset<0 || field_offset>=PQnfields(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
- RETURN_FALSE;
- }
- if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) {
- Z_TYPE_P(return_value) = IS_NULL;
- } else {
- char *value = PQgetvalue(pgsql_result, pgsql_row, field_offset);
- int value_len = PQgetlength(pgsql_result, pgsql_row, field_offset);
- ZVAL_STRINGL(return_value, value, value_len, 1);
- }
- }
- /* }}} */
- /* {{{ void php_pgsql_fetch_hash */
- static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int into_object)
- {
- zval *result, *zrow = NULL;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- int i, num_fields, pgsql_row, use_row;
- long row = -1;
- char *field_name;
- zval *ctor_params = NULL;
- zend_class_entry *ce = NULL;
- if (into_object) {
- char *class_name = NULL;
- int class_name_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!sz", &result, &zrow, &class_name, &class_name_len, &ctor_params) == FAILURE) {
- return;
- }
- if (!class_name) {
- ce = zend_standard_class_def;
- } else {
- ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
- }
- if (!ce) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
- return;
- }
- result_type = PGSQL_ASSOC;
- } else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!l", &result, &zrow, &result_type) == FAILURE) {
- return;
- }
- }
- if (zrow == NULL) {
- row = -1;
- } else {
- convert_to_long(zrow);
- row = Z_LVAL_P(zrow);
- if (row < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The row parameter must be greater or equal to zero");
- RETURN_FALSE;
- }
- }
- use_row = ZEND_NUM_ARGS() > 1 && row != -1;
- if (!(result_type & PGSQL_BOTH)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (use_row) {
- pgsql_row = row;
- pg_result->row = pgsql_row;
- if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld",
- row, Z_LVAL_P(result));
- RETURN_FALSE;
- }
- } else {
- /* If 2nd param is NULL, use internal row counter to access next row */
- pgsql_row = pg_result->row;
- if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) {
- RETURN_FALSE;
- }
- pg_result->row++;
- }
- array_init(return_value);
- for (i = 0, num_fields = PQnfields(pgsql_result); i < num_fields; i++) {
- if (PQgetisnull(pgsql_result, pgsql_row, i)) {
- if (result_type & PGSQL_NUM) {
- add_index_null(return_value, i);
- }
- if (result_type & PGSQL_ASSOC) {
- field_name = PQfname(pgsql_result, i);
- add_assoc_null(return_value, field_name);
- }
- } else {
- char *element = PQgetvalue(pgsql_result, pgsql_row, i);
- if (element) {
- char *data;
- int data_len;
- int should_copy=0;
- const uint element_len = strlen(element);
- data = safe_estrndup(element, element_len);
- data_len = element_len;
- if (result_type & PGSQL_NUM) {
- add_index_stringl(return_value, i, data, data_len, should_copy);
- should_copy=1;
- }
- if (result_type & PGSQL_ASSOC) {
- field_name = PQfname(pgsql_result, i);
- add_assoc_stringl(return_value, field_name, data, data_len, should_copy);
- }
- }
- }
- }
- if (into_object) {
- zval dataset = *return_value;
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
- zval *retval_ptr;
- object_and_properties_init(return_value, ce, NULL);
- zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
- if (ce->constructor) {
- fci.size = sizeof(fci);
- fci.function_table = &ce->function_table;
- fci.function_name = NULL;
- fci.symbol_table = NULL;
- fci.object_ptr = return_value;
- fci.retval_ptr_ptr = &retval_ptr;
- fci.params = NULL;
- fci.param_count = 0;
- fci.no_separation = 1;
- if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
- if (zend_fcall_info_args(&fci, ctor_params TSRMLS_CC) == FAILURE) {
- /* Two problems why we throw exceptions here: PHP is typeless
- * and hence passing one argument that's not an array could be
- * by mistake and the other way round is possible, too. The
- * single value is an array. Also we'd have to make that one
- * argument passed by reference.
- */
- zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
- return;
- }
- }
- fcc.initialized = 1;
- fcc.function_handler = ce->constructor;
- fcc.calling_scope = EG(scope);
- fcc.called_scope = Z_OBJCE_P(return_value);
- fcc.object_ptr = return_value;
- if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
- zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
- } else {
- if (retval_ptr) {
- zval_ptr_dtor(&retval_ptr);
- }
- }
- if (fci.params) {
- efree(fci.params);
- }
- } else if (ctor_params) {
- zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
- }
- }
- }
- /* }}} */
- /* {{{ proto array pg_fetch_row(resource result [, int row [, int result_type]])
- Get a row as an enumerated array */
- PHP_FUNCTION(pg_fetch_row)
- {
- php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_NUM, 0);
- }
- /* }}} */
- /* {{{ proto array pg_fetch_assoc(resource result [, int row])
- Fetch a row as an assoc array */
- PHP_FUNCTION(pg_fetch_assoc)
- {
- /* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when
- there is 3rd parameter */
- if (ZEND_NUM_ARGS() > 2)
- WRONG_PARAM_COUNT;
- php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 0);
- }
- /* }}} */
- /* {{{ proto array pg_fetch_array(resource result [, int row [, int result_type]])
- Fetch a row as an array */
- PHP_FUNCTION(pg_fetch_array)
- {
- php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_BOTH, 0);
- }
- /* }}} */
- /* {{{ proto object pg_fetch_object(resource result [, int row [, string class_name [, NULL|array ctor_params]]])
- Fetch a row as an object */
- PHP_FUNCTION(pg_fetch_object)
- {
- /* pg_fetch_object() allowed result_type used to be. 3rd parameter
- must be allowed for compatibility */
- php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 1);
- }
- /* }}} */
- /* {{{ proto array pg_fetch_all(resource result)
- Fetch all rows into array */
- PHP_FUNCTION(pg_fetch_all)
- {
- zval *result;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- array_init(return_value);
- if (php_pgsql_result2array(pgsql_result, return_value TSRMLS_CC) == FAILURE) {
- zval_dtor(return_value);
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ proto array pg_fetch_all_columns(resource result [, int column_number])
- Fetch all rows into array */
- PHP_FUNCTION(pg_fetch_all_columns)
- {
- zval *result;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- unsigned long colno=0;
- int pg_numrows, pg_row;
- size_t num_fields;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &colno) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- num_fields = PQnfields(pgsql_result);
- if (colno >= num_fields || colno < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column number '%ld'", colno);
- RETURN_FALSE;
- }
- array_init(return_value);
- if ((pg_numrows = PQntuples(pgsql_result)) <= 0) {
- return;
- }
- for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
- if (PQgetisnull(pgsql_result, pg_row, colno)) {
- add_next_index_null(return_value);
- } else {
- add_next_index_string(return_value, PQgetvalue(pgsql_result, pg_row, colno), 1);
- }
- }
- }
- /* }}} */
- /* {{{ proto bool pg_result_seek(resource result, int offset)
- Set internal row offset */
- PHP_FUNCTION(pg_result_seek)
- {
- zval *result;
- long row;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &row) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- if (row < 0 || row >= PQntuples(pg_result->result)) {
- RETURN_FALSE;
- }
- /* seek to offset */
- pg_result->row = row;
- RETURN_TRUE;
- }
- /* }}} */
- #define PHP_PG_DATA_LENGTH 1
- #define PHP_PG_DATA_ISNULL 2
- /* {{{ php_pgsql_data_info
- */
- static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
- {
- zval *result, **field;
- long row;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- int field_offset, pgsql_row, argc = ZEND_NUM_ARGS();
- if (argc == 2) {
- if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) {
- return;
- }
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rlZ", &result, &row, &field) == FAILURE) {
- return;
- }
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (argc == 2) {
- if (pg_result->row < 0) {
- pg_result->row = 0;
- }
- pgsql_row = pg_result->row;
- if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) {
- RETURN_FALSE;
- }
- } else {
- pgsql_row = row;
- if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld",
- row, Z_LVAL_P(result));
- RETURN_FALSE;
- }
- }
- switch(Z_TYPE_PP(field)) {
- case IS_STRING:
- convert_to_string_ex(field);
- field_offset = PQfnumber(pgsql_result, Z_STRVAL_PP(field));
- break;
- default:
- convert_to_long_ex(field);
- field_offset = Z_LVAL_PP(field);
- break;
- }
- if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
- RETURN_FALSE;
- }
- switch (entry_type) {
- case PHP_PG_DATA_LENGTH:
- Z_LVAL_P(return_value) = PQgetlength(pgsql_result, pgsql_row, field_offset);
- break;
- case PHP_PG_DATA_ISNULL:
- Z_LVAL_P(return_value) = PQgetisnull(pgsql_result, pgsql_row, field_offset);
- break;
- }
- Z_TYPE_P(return_value) = IS_LONG;
- }
- /* }}} */
- /* {{{ proto int pg_field_prtlen(resource result, [int row,] mixed field_name_or_number)
- Returns the printed length */
- PHP_FUNCTION(pg_field_prtlen)
- {
- php_pgsql_data_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_DATA_LENGTH);
- }
- /* }}} */
- /* {{{ proto int pg_field_is_null(resource result, [int row,] mixed field_name_or_number)
- Test if a field is NULL */
- PHP_FUNCTION(pg_field_is_null)
- {
- php_pgsql_data_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_DATA_ISNULL);
- }
- /* }}} */
- /* {{{ proto bool pg_free_result(resource result)
- Free result memory */
- PHP_FUNCTION(pg_free_result)
- {
- zval *result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- if (Z_LVAL_P(result) == 0) {
- RETURN_FALSE;
- }
- zend_list_delete(Z_RESVAL_P(result));
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto string pg_last_oid(resource result)
- Returns the last object identifier */
- PHP_FUNCTION(pg_last_oid)
- {
- zval *result;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- #ifdef HAVE_PQOIDVALUE
- Oid oid;
- #endif
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- #ifdef HAVE_PQOIDVALUE
- oid = PQoidValue(pgsql_result);
- if (oid == InvalidOid) {
- RETURN_FALSE;
- }
- PGSQL_RETURN_OID(oid);
- #else
- Z_STRVAL_P(return_value) = (char *) PQoidStatus(pgsql_result);
- if (Z_STRVAL_P(return_value)) {
- RETURN_STRING(Z_STRVAL_P(return_value), 1);
- }
- RETURN_STRING("", 1);
- #endif
- }
- /* }}} */
- /* {{{ proto bool pg_trace(string filename [, string mode [, resource connection]])
- Enable tracing a PostgreSQL connection */
- PHP_FUNCTION(pg_trace)
- {
- char *z_filename, *mode = "w";
- int z_filename_len, mode_len;
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- FILE *fp = NULL;
- php_stream *stream;
- id = PGG(default_link);
- if (zend_parse_parameters(argc TSRMLS_CC, "p|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) {
- return;
- }
- if (argc < 3) {
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- stream = php_stream_open_wrapper(z_filename, mode, REPORT_ERRORS, NULL);
- if (!stream) {
- RETURN_FALSE;
- }
- if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) {
- php_stream_close(stream);
- RETURN_FALSE;
- }
- php_stream_auto_cleanup(stream);
- PQtrace(pgsql, fp);
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto bool pg_untrace([resource connection])
- Disable tracing of a PostgreSQL connection */
- PHP_FUNCTION(pg_untrace)
- {
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
- return;
- }
- if (argc == 0) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- PQuntrace(pgsql);
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto mixed pg_lo_create([resource connection],[mixed large_object_oid])
- Create a large object */
- PHP_FUNCTION(pg_lo_create)
- {
- zval *pgsql_link = NULL, *oid = NULL;
- PGconn *pgsql;
- Oid pgsql_oid, wanted_oid = InvalidOid;
- int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) {
- return;
- }
- if ((argc == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) {
- oid = pgsql_link;
- pgsql_link = NULL;
- }
- if (pgsql_link == NULL) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- if (id == -1) {
- RETURN_FALSE;
- }
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (oid) {
- #ifndef HAVE_PG_LO_CREATE
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL");
- #else
- switch (Z_TYPE_P(oid)) {
- case IS_STRING:
- {
- char *end_ptr;
- wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10);
- if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- }
- break;
- case IS_LONG:
- if (Z_LVAL_P(oid) < (long)InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- wanted_oid = (Oid)Z_LVAL_P(oid);
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- if ((pgsql_oid = lo_create(pgsql, wanted_oid)) == InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object");
- RETURN_FALSE;
- }
- PGSQL_RETURN_OID(pgsql_oid);
- #endif
- }
- if ((pgsql_oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object");
- RETURN_FALSE;
- }
- PGSQL_RETURN_OID(pgsql_oid);
- }
- /* }}} */
- /* {{{ proto bool pg_lo_unlink([resource connection,] string large_object_oid)
- Delete a large object */
- PHP_FUNCTION(pg_lo_unlink)
- {
- zval *pgsql_link = NULL;
- long oid_long;
- char *oid_string, *end_ptr;
- int oid_strlen;
- PGconn *pgsql;
- Oid oid;
- int id = -1;
- int argc = ZEND_NUM_ARGS();
- /* accept string type since Oid type is unsigned int */
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rs", &pgsql_link, &oid_string, &oid_strlen) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rl", &pgsql_link, &oid_long) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "s", &oid_string, &oid_strlen) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "l", &oid_long) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID is specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments");
- RETURN_FALSE;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (lo_unlink(pgsql, oid) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete PostgreSQL large object %u", oid);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto resource pg_lo_open([resource connection,] int large_object_oid, string mode)
- Open a large object and return fd */
- PHP_FUNCTION(pg_lo_open)
- {
- zval *pgsql_link = NULL;
- long oid_long;
- char *oid_string, *end_ptr, *mode_string;
- int oid_strlen, mode_strlen;
- PGconn *pgsql;
- Oid oid;
- int id = -1, pgsql_mode=0, pgsql_lofd;
- int create=0;
- pgLofp *pgsql_lofp;
- int argc = ZEND_NUM_ARGS();
- /* accept string type since Oid is unsigned int */
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rss", &pgsql_link, &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rls", &pgsql_link, &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "ss", &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "ls", &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments");
- RETURN_FALSE;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- /* r/w/+ is little bit more PHP-like than INV_READ/INV_WRITE and a lot of
- faster to type. Unfortunately, doesn't behave the same way as fopen()...
- (Jouni)
- */
- if (strchr(mode_string, 'r') == mode_string) {
- pgsql_mode |= INV_READ;
- if (strchr(mode_string, '+') == mode_string+1) {
- pgsql_mode |= INV_WRITE;
- }
- }
- if (strchr(mode_string, 'w') == mode_string) {
- pgsql_mode |= INV_WRITE;
- create = 1;
- if (strchr(mode_string, '+') == mode_string+1) {
- pgsql_mode |= INV_READ;
- }
- }
- pgsql_lofp = (pgLofp *) emalloc(sizeof(pgLofp));
- if ((pgsql_lofd = lo_open(pgsql, oid, pgsql_mode)) == -1) {
- if (create) {
- if ((oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == 0) {
- efree(pgsql_lofp);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create PostgreSQL large object");
- RETURN_FALSE;
- } else {
- if ((pgsql_lofd = lo_open(pgsql, oid, pgsql_mode)) == -1) {
- if (lo_unlink(pgsql, oid) == -1) {
- efree(pgsql_lofp);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Something is really messed up! Your database is badly corrupted in a way NOT related to PHP");
- RETURN_FALSE;
- }
- efree(pgsql_lofp);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open PostgreSQL large object");
- RETURN_FALSE;
- } else {
- pgsql_lofp->conn = pgsql;
- pgsql_lofp->lofd = pgsql_lofd;
- Z_LVAL_P(return_value) = zend_list_insert(pgsql_lofp, le_lofp TSRMLS_CC);
- Z_TYPE_P(return_value) = IS_LONG;
- }
- }
- } else {
- efree(pgsql_lofp);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open PostgreSQL large object");
- RETURN_FALSE;
- }
- } else {
- pgsql_lofp->conn = pgsql;
- pgsql_lofp->lofd = pgsql_lofd;
- ZEND_REGISTER_RESOURCE(return_value, pgsql_lofp, le_lofp);
- }
- }
- /* }}} */
- /* {{{ proto bool pg_lo_close(resource large_object)
- Close a large object */
- PHP_FUNCTION(pg_lo_close)
- {
- zval *pgsql_lofp;
- pgLofp *pgsql;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_lofp) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_lofp, -1, "PostgreSQL large object", le_lofp);
- if (lo_close((PGconn *)pgsql->conn, pgsql->lofd) < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to close PostgreSQL large object descriptor %d", pgsql->lofd);
- RETVAL_FALSE;
- } else {
- RETVAL_TRUE;
- }
- zend_list_delete(Z_RESVAL_P(pgsql_lofp));
- return;
- }
- /* }}} */
- #define PGSQL_LO_READ_BUF_SIZE 8192
- /* {{{ proto string pg_lo_read(resource large_object [, int len])
- Read a large object */
- PHP_FUNCTION(pg_lo_read)
- {
- zval *pgsql_id;
- long len;
- int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes, argc = ZEND_NUM_ARGS();
- char *buf;
- pgLofp *pgsql;
- if (zend_parse_parameters(argc TSRMLS_CC, "r|l", &pgsql_id, &len) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- if (argc > 1) {
- buf_len = len;
- }
- buf = (char *) safe_emalloc(sizeof(char), (buf_len+1), 0);
- if ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, buf_len))<0) {
- efree(buf);
- RETURN_FALSE;
- }
- buf[nbytes] = '\0';
- RETURN_STRINGL(buf, nbytes, 0);
- }
- /* }}} */
- /* {{{ proto int pg_lo_write(resource large_object, string buf [, int len])
- Write a large object */
- PHP_FUNCTION(pg_lo_write)
- {
- zval *pgsql_id;
- char *str;
- long z_len;
- int str_len, nbytes;
- int len;
- pgLofp *pgsql;
- int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &pgsql_id, &str, &str_len, &z_len) == FAILURE) {
- return;
- }
- if (argc > 2) {
- if (z_len > str_len) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write more than buffer size %d. Tried to write %ld", str_len, z_len);
- RETURN_FALSE;
- }
- if (z_len < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Buffer size must be larger than 0, but %ld was specified", z_len);
- RETURN_FALSE;
- }
- len = z_len;
- }
- else {
- len = str_len;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, str, len)) == -1) {
- RETURN_FALSE;
- }
- RETURN_LONG(nbytes);
- }
- /* }}} */
- /* {{{ proto int pg_lo_read_all(resource large_object)
- Read a large object and send straight to browser */
- PHP_FUNCTION(pg_lo_read_all)
- {
- zval *pgsql_id;
- int tbytes;
- volatile int nbytes;
- char buf[PGSQL_LO_READ_BUF_SIZE];
- pgLofp *pgsql;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_id) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- tbytes = 0;
- while ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, PGSQL_LO_READ_BUF_SIZE))>0) {
- PHPWRITE(buf, nbytes);
- tbytes += nbytes;
- }
- RETURN_LONG(tbytes);
- }
- /* }}} */
- /* {{{ proto int pg_lo_import([resource connection, ] string filename [, mixed oid])
- Import large object direct from filesystem */
- PHP_FUNCTION(pg_lo_import)
- {
- zval *pgsql_link = NULL, *oid = NULL;
- char *file_in;
- int id = -1, name_len;
- int argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- Oid returned_oid;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rp|z", &pgsql_link, &file_in, &name_len, &oid) == SUCCESS) {
- ;
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "p|z", &file_in, &name_len, &oid) == SUCCESS) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- /* old calling convention, deprecated since PHP 4.2 */
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "pr", &file_in, &name_len, &pgsql_link ) == SUCCESS) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Old API is used");
- }
- else {
- WRONG_PARAM_COUNT;
- }
- if (php_check_open_basedir(file_in TSRMLS_CC)) {
- RETURN_FALSE;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (oid) {
- #ifndef HAVE_PG_LO_IMPORT_WITH_OID
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing not supported");
- #else
- Oid wanted_oid;
- switch (Z_TYPE_P(oid)) {
- case IS_STRING:
- {
- char *end_ptr;
- wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10);
- if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- }
- break;
- case IS_LONG:
- if (Z_LVAL_P(oid) < (long)InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- wanted_oid = (Oid)Z_LVAL_P(oid);
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid OID value passed");
- RETURN_FALSE;
- }
- returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid);
- if (returned_oid == InvalidOid) {
- RETURN_FALSE;
- }
- PGSQL_RETURN_OID(returned_oid);
- #endif
- }
- returned_oid = lo_import(pgsql, file_in);
- if (returned_oid == InvalidOid) {
- RETURN_FALSE;
- }
- PGSQL_RETURN_OID(returned_oid);
- }
- /* }}} */
- /* {{{ proto bool pg_lo_export([resource connection, ] int objoid, string filename)
- Export large object direct to filesystem */
- PHP_FUNCTION(pg_lo_export)
- {
- zval *pgsql_link = NULL;
- char *file_out, *oid_string, *end_ptr;
- int oid_strlen;
- int id = -1, name_len;
- long oid_long;
- Oid oid;
- PGconn *pgsql;
- int argc = ZEND_NUM_ARGS();
- /* allow string to handle large OID value correctly */
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rlp", &pgsql_link, &oid_long, &file_out, &name_len) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "rss", &pgsql_link, &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "lp", &oid_long, &file_out, &name_len) == SUCCESS) {
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "sp", &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "spr", &oid_string, &oid_strlen, &file_out, &name_len, &pgsql_link) == SUCCESS) {
- oid = (Oid)strtoul(oid_string, &end_ptr, 10);
- if ((oid_string+oid_strlen) != end_ptr) {
- /* wrong integer format */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed");
- RETURN_FALSE;
- }
- }
- else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC,
- "lpr", &oid_long, &file_out, &name_len, &pgsql_link) == SUCCESS) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Old API is used");
- if (oid_long <= InvalidOid) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid OID specified");
- RETURN_FALSE;
- }
- oid = (Oid)oid_long;
- }
- else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 2 or 3 arguments");
- RETURN_FALSE;
- }
- if (php_check_open_basedir(file_out TSRMLS_CC)) {
- RETURN_FALSE;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (lo_export(pgsql, oid, file_out) == -1) {
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto bool pg_lo_seek(resource large_object, int offset [, int whence])
- Seeks position of large object */
- PHP_FUNCTION(pg_lo_seek)
- {
- zval *pgsql_id = NULL;
- long result, offset = 0, whence = SEEK_CUR;
- pgLofp *pgsql;
- int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rl|l", &pgsql_id, &offset, &whence) == FAILURE) {
- return;
- }
- if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid whence parameter");
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- #if HAVE_PG_LO64
- if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) {
- result = lo_lseek64((PGconn *)pgsql->conn, pgsql->lofd, offset, whence);
- } else {
- result = lo_lseek((PGconn *)pgsql->conn, pgsql->lofd, offset, whence);
- }
- #else
- result = lo_lseek((PGconn *)pgsql->conn, pgsql->lofd, offset, whence);
- #endif
- if (result > -1) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ proto int pg_lo_tell(resource large_object)
- Returns current position of large object */
- PHP_FUNCTION(pg_lo_tell)
- {
- zval *pgsql_id = NULL;
- long offset = 0;
- pgLofp *pgsql;
- int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "r", &pgsql_id) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- #if HAVE_PG_LO64
- if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) {
- offset = lo_tell64((PGconn *)pgsql->conn, pgsql->lofd);
- } else {
- offset = lo_tell((PGconn *)pgsql->conn, pgsql->lofd);
- }
- #else
- offset = lo_tell((PGconn *)pgsql->conn, pgsql->lofd);
- #endif
- RETURN_LONG(offset);
- }
- /* }}} */
- #if HAVE_PG_LO_TRUNCATE
- /* {{{ proto bool pg_lo_truncate(resource large_object, int size)
- Truncate large object to size */
- PHP_FUNCTION(pg_lo_truncate)
- {
- zval *pgsql_id = NULL;
- size_t size;
- pgLofp *pgsql;
- int argc = ZEND_NUM_ARGS();
- int result;
- if (zend_parse_parameters(argc TSRMLS_CC, "rl", &pgsql_id, &size) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp);
- #if HAVE_PG_LO64
- if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) {
- result = lo_truncate64((PGconn *)pgsql->conn, pgsql->lofd, size);
- } else {
- result = lo_truncate((PGconn *)pgsql->conn, pgsql->lofd, size);
- }
- #else
- result = lo_truncate((PGconn *)pgsql->conn, pgsql->lofd, size);
- #endif
- if (!result) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- /* {{{ proto int pg_set_error_verbosity([resource connection,] int verbosity)
- Set error verbosity */
- PHP_FUNCTION(pg_set_error_verbosity)
- {
- zval *pgsql_link = NULL;
- long verbosity;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- if (argc == 1) {
- if (zend_parse_parameters(argc TSRMLS_CC, "l", &verbosity) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rl", &pgsql_link, &verbosity) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (verbosity & (PQERRORS_TERSE|PQERRORS_DEFAULT|PQERRORS_VERBOSE)) {
- Z_LVAL_P(return_value) = PQsetErrorVerbosity(pgsql, verbosity);
- Z_TYPE_P(return_value) = IS_LONG;
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- #endif
- #ifdef HAVE_PQCLIENTENCODING
- /* {{{ proto int pg_set_client_encoding([resource connection,] string encoding)
- Set client encoding */
- PHP_FUNCTION(pg_set_client_encoding)
- {
- char *encoding;
- int encoding_len;
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- if (argc == 1) {
- if (zend_parse_parameters(argc TSRMLS_CC, "s", &encoding, &encoding_len) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &encoding, &encoding_len) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- Z_LVAL_P(return_value) = PQsetClientEncoding(pgsql, encoding);
- Z_TYPE_P(return_value) = IS_LONG;
- }
- /* }}} */
- /* {{{ proto string pg_client_encoding([resource connection])
- Get the current client encoding */
- PHP_FUNCTION(pg_client_encoding)
- {
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
- return;
- }
- if (argc == 0) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- /* Just do the same as found in PostgreSQL sources... */
- Z_STRVAL_P(return_value) = (char *) pg_encoding_to_char(PQclientEncoding(pgsql));
- Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
- Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value));
- Z_TYPE_P(return_value) = IS_STRING;
- }
- /* }}} */
- #endif
- #if !HAVE_PQGETCOPYDATA
- #define COPYBUFSIZ 8192
- #endif
- /* {{{ proto bool pg_end_copy([resource connection])
- Sync with backend. Completes the Copy command */
- PHP_FUNCTION(pg_end_copy)
- {
- zval *pgsql_link = NULL;
- int id = -1, argc = ZEND_NUM_ARGS();
- PGconn *pgsql;
- int result = 0;
- if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
- return;
- }
- if (argc == 0) {
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- result = PQendcopy(pgsql);
- if (result!=0) {
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto bool pg_put_line([resource connection,] string query)
- Send null-terminated string to backend server*/
- PHP_FUNCTION(pg_put_line)
- {
- char *query;
- zval *pgsql_link = NULL;
- int query_len, id = -1;
- PGconn *pgsql;
- int result = 0, argc = ZEND_NUM_ARGS();
- if (argc == 1) {
- if (zend_parse_parameters(argc TSRMLS_CC, "s", &query, &query_len) == FAILURE) {
- return;
- }
- id = PGG(default_link);
- CHECK_DEFAULT_LINK(id);
- } else {
- if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) {
- return;
- }
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- result = PQputline(pgsql, query);
- if (result==EOF) {
- PHP_PQ_ERROR("Query failed: %s", pgsql);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ proto array pg_copy_to(resource connection, string table_name [, string delimiter [, string null_as]])
- Copy table to array */
- PHP_FUNCTION(pg_copy_to)
- {
- zval *pgsql_link;
- char *table_name, *pg_delim = NULL, *pg_null_as = NULL;
- int table_name_len, pg_delim_len, pg_null_as_len, free_pg_null = 0;
- char *query;
- int id = -1;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- int copydone = 0;
- #if !HAVE_PQGETCOPYDATA
- char copybuf[COPYBUFSIZ];
- #endif
- char *csv = (char *)NULL;
- int ret;
- int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rs|ss",
- &pgsql_link, &table_name, &table_name_len,
- &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (!pg_delim) {
- pg_delim = "\t";
- }
- if (!pg_null_as) {
- pg_null_as = safe_estrdup("\\\\N");
- free_pg_null = 1;
- }
- spprintf(&query, 0, "COPY %s TO STDOUT DELIMITER E'%c' NULL AS E'%s'", table_name, *pg_delim, pg_null_as);
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- }
- pgsql_result = PQexec(pgsql, query);
- if (free_pg_null) {
- efree(pg_null_as);
- }
- efree(query);
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- switch (status) {
- case PGRES_COPY_OUT:
- if (pgsql_result) {
- PQclear(pgsql_result);
- array_init(return_value);
- #if HAVE_PQGETCOPYDATA
- while (!copydone)
- {
- ret = PQgetCopyData(pgsql, &csv, 0);
- switch (ret) {
- case -1:
- copydone = 1;
- break;
- case 0:
- case -2:
- PHP_PQ_ERROR("getline failed: %s", pgsql);
- RETURN_FALSE;
- break;
- default:
- add_next_index_string(return_value, csv, 1);
- PQfreemem(csv);
- break;
- }
- }
- #else
- while (!copydone)
- {
- if ((ret = PQgetline(pgsql, copybuf, COPYBUFSIZ))) {
- PHP_PQ_ERROR("getline failed: %s", pgsql);
- RETURN_FALSE;
- }
- if (copybuf[0] == '\\' &&
- copybuf[1] == '.' &&
- copybuf[2] == '\0')
- {
- copydone = 1;
- }
- else
- {
- if (csv == (char *)NULL) {
- csv = estrdup(copybuf);
- } else {
- csv = (char *)erealloc(csv, strlen(csv) + sizeof(char)*(COPYBUFSIZ+1));
- strcat(csv, copybuf);
- }
- switch (ret)
- {
- case EOF:
- copydone = 1;
- case 0:
- add_next_index_string(return_value, csv, 1);
- efree(csv);
- csv = (char *)NULL;
- break;
- case 1:
- break;
- }
- }
- }
- if (PQendcopy(pgsql)) {
- PHP_PQ_ERROR("endcopy failed: %s", pgsql);
- RETURN_FALSE;
- }
- #endif
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- }
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- break;
- default:
- PQclear(pgsql_result);
- PHP_PQ_ERROR("Copy command failed: %s", pgsql);
- RETURN_FALSE;
- break;
- }
- }
- /* }}} */
- /* {{{ proto bool pg_copy_from(resource connection, string table_name , array rows [, string delimiter [, string null_as]])
- Copy table from array */
- PHP_FUNCTION(pg_copy_from)
- {
- zval *pgsql_link = NULL, *pg_rows;
- zval **tmp;
- char *table_name, *pg_delim = NULL, *pg_null_as = NULL;
- int table_name_len, pg_delim_len, pg_null_as_len;
- int pg_null_as_free = 0;
- char *query;
- HashPosition pos;
- int id = -1;
- PGconn *pgsql;
- PGresult *pgsql_result;
- ExecStatusType status;
- int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa|ss",
- &pgsql_link, &table_name, &table_name_len, &pg_rows,
- &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (!pg_delim) {
- pg_delim = "\t";
- }
- if (!pg_null_as) {
- pg_null_as = safe_estrdup("\\\\N");
- pg_null_as_free = 1;
- }
- spprintf(&query, 0, "COPY %s FROM STDIN DELIMITER E'%c' NULL AS E'%s'", table_name, *pg_delim, pg_null_as);
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- }
- pgsql_result = PQexec(pgsql, query);
- if (pg_null_as_free) {
- efree(pg_null_as);
- }
- efree(query);
- if (pgsql_result) {
- status = PQresultStatus(pgsql_result);
- } else {
- status = (ExecStatusType) PQstatus(pgsql);
- }
- switch (status) {
- case PGRES_COPY_IN:
- if (pgsql_result) {
- int command_failed = 0;
- PQclear(pgsql_result);
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pg_rows), &pos);
- #if HAVE_PQPUTCOPYDATA
- while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
- zval *value;
- ALLOC_ZVAL(value);
- INIT_PZVAL_COPY(value, *tmp);
- zval_copy_ctor(value);
- convert_to_string_ex(&value);
- query = (char *)emalloc(Z_STRLEN_P(value) + 2);
- strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2);
- if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') {
- strlcat(query, "\n", Z_STRLEN_P(value) + 2);
- }
- if (PQputCopyData(pgsql, query, strlen(query)) != 1) {
- efree(query);
- zval_dtor(value);
- efree(value);
- PHP_PQ_ERROR("copy failed: %s", pgsql);
- RETURN_FALSE;
- }
- efree(query);
- zval_dtor(value);
- efree(value);
- zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos);
- }
- if (PQputCopyEnd(pgsql, NULL) != 1) {
- PHP_PQ_ERROR("putcopyend failed: %s", pgsql);
- RETURN_FALSE;
- }
- #else
- while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
- zval *value;
- ALLOC_ZVAL(value);
- INIT_PZVAL_COPY(value, *tmp);
- zval_copy_ctor(value);
- convert_to_string_ex(&value);
- query = (char *)emalloc(Z_STRLEN_P(value) + 2);
- strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2);
- if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') {
- strlcat(query, "\n", Z_STRLEN_P(value) + 2);
- }
- if (PQputline(pgsql, query)==EOF) {
- efree(query);
- zval_dtor(value);
- efree(value);
- PHP_PQ_ERROR("copy failed: %s", pgsql);
- RETURN_FALSE;
- }
- efree(query);
- zval_dtor(value);
- efree(value);
- zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos);
- }
- if (PQputline(pgsql, "\\.\n") == EOF) {
- PHP_PQ_ERROR("putline failed: %s", pgsql);
- RETURN_FALSE;
- }
- if (PQendcopy(pgsql)) {
- PHP_PQ_ERROR("endcopy failed: %s", pgsql);
- RETURN_FALSE;
- }
- #endif
- while ((pgsql_result = PQgetResult(pgsql))) {
- if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
- PHP_PQ_ERROR("Copy command failed: %s", pgsql);
- command_failed = 1;
- }
- PQclear(pgsql_result);
- }
- if (command_failed) {
- RETURN_FALSE;
- }
- } else {
- PQclear(pgsql_result);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- break;
- default:
- PQclear(pgsql_result);
- PHP_PQ_ERROR("Copy command failed: %s", pgsql);
- RETURN_FALSE;
- break;
- }
- }
- /* }}} */
- #ifdef HAVE_PQESCAPE
- /* {{{ proto string pg_escape_string([resource connection,] string data)
- Escape string for text/char type */
- PHP_FUNCTION(pg_escape_string)
- {
- char *from = NULL, *to = NULL;
- zval *pgsql_link;
- #ifdef HAVE_PQESCAPE_CONN
- PGconn *pgsql;
- #endif
- int to_len;
- int from_len;
- int id = -1;
- switch (ZEND_NUM_ARGS()) {
- case 1:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) {
- return;
- }
- pgsql_link = NULL;
- id = PGG(default_link);
- break;
- default:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) {
- return;
- }
- break;
- }
- to = (char *) safe_emalloc_string(from_len, 2, 1);
- #ifdef HAVE_PQESCAPE_CONN
- if (pgsql_link != NULL || id != -1) {
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL);
- } else
- #endif
- to_len = (int) PQescapeString(to, from, (size_t)from_len);
- RETURN_STRINGL(to, to_len, 0);
- }
- /* }}} */
- /* {{{ proto string pg_escape_bytea([resource connection,] string data)
- Escape binary for bytea type */
- PHP_FUNCTION(pg_escape_bytea)
- {
- char *from = NULL, *to = NULL;
- size_t to_len;
- int from_len, id = -1;
- #ifdef HAVE_PQESCAPE_BYTEA_CONN
- PGconn *pgsql;
- #endif
- zval *pgsql_link;
- switch (ZEND_NUM_ARGS()) {
- case 1:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) {
- return;
- }
- pgsql_link = NULL;
- id = PGG(default_link);
- break;
- default:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) {
- return;
- }
- break;
- }
- #ifdef HAVE_PQESCAPE_BYTEA_CONN
- if (pgsql_link != NULL || id != -1) {
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)from, (size_t)from_len, &to_len);
- } else
- #endif
- to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len);
- RETVAL_STRINGL_CHECK(to, to_len-1, 1); /* to_len includes additional '\0' */
- PQfreemem(to);
- }
- /* }}} */
- #if !HAVE_PQUNESCAPEBYTEA
- /* PQunescapeBytea() from PostgreSQL 7.3 to provide bytea unescape feature to 7.2 users.
- Renamed to php_pgsql_unescape_bytea() */
- /*
- * PQunescapeBytea - converts the null terminated string representation
- * of a bytea, strtext, into binary, filling a buffer. It returns a
- * pointer to the buffer which is NULL on error, and the size of the
- * buffer in retbuflen. The pointer may subsequently be used as an
- * argument to the function free(3). It is the reverse of PQescapeBytea.
- *
- * The following transformations are reversed:
- * '\0' == ASCII 0 == \000
- * '\'' == ASCII 39 == \'
- * '\\' == ASCII 92 == \\
- *
- * States:
- * 0 normal 0->1->2->3->4
- * 1 \ 1->5
- * 2 \0 1->6
- * 3 \00
- * 4 \000
- * 5 \'
- * 6 \\
- */
- static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen)
- {
- size_t buflen;
- unsigned char *buffer,
- *sp,
- *bp;
- unsigned int state = 0;
- if (strtext == NULL)
- return NULL;
- buflen = strlen(strtext); /* will shrink, also we discover if
- * strtext */
- buffer = (unsigned char *) emalloc(buflen); /* isn't NULL terminated */
- for (bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
- {
- switch (state)
- {
- case 0:
- if (*sp == '\\')
- state = 1;
- *bp = *sp;
- break;
- case 1:
- if (*sp == '\'') /* state=5 */
- { /* replace \' with 39 */
- bp--;
- *bp = '\'';
- buflen--;
- state = 0;
- }
- else if (*sp == '\\') /* state=6 */
- { /* replace \\ with 92 */
- bp--;
- *bp = '\\';
- buflen--;
- state = 0;
- }
- else
- {
- if (isdigit(*sp))
- state = 2;
- else
- state = 0;
- *bp = *sp;
- }
- break;
- case 2:
- if (isdigit(*sp))
- state = 3;
- else
- state = 0;
- *bp = *sp;
- break;
- case 3:
- if (isdigit(*sp)) /* state=4 */
- {
- unsigned char *start, *end, buf[4]; /* 000 + '\0' */
- bp -= 3;
- memcpy(buf, sp-2, 3);
- buf[3] = '\0';
- start = buf;
- *bp = (unsigned char)strtoul(start, (char **)&end, 8);
- buflen -= 3;
- state = 0;
- }
- else
- {
- *bp = *sp;
- state = 0;
- }
- break;
- }
- }
- buffer = erealloc(buffer, buflen+1);
- buffer[buflen] = '\0';
- *retbuflen = buflen;
- return buffer;
- }
- #endif
- /* {{{ proto string pg_unescape_bytea(string data)
- Unescape binary for bytea type */
- PHP_FUNCTION(pg_unescape_bytea)
- {
- char *from = NULL, *to = NULL, *tmp = NULL;
- size_t to_len;
- int from_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
- &from, &from_len) == FAILURE) {
- return;
- }
- #if HAVE_PQUNESCAPEBYTEA
- tmp = (char *)PQunescapeBytea((unsigned char*)from, &to_len);
- to = estrndup(tmp, to_len);
- PQfreemem(tmp);
- #else
- to = (char *)php_pgsql_unescape_bytea((unsigned char*)from, &to_len);
- #endif
- if (!to) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invalid parameter");
- RETURN_FALSE;
- }
- RETVAL_STRINGL(to, to_len, 0);
- }
- /* }}} */
- #endif
- #ifdef HAVE_PQESCAPE
- static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_literal) {
- char *from = NULL, *to = NULL;
- zval *pgsql_link = NULL;
- PGconn *pgsql;
- int from_len;
- int id = -1;
- char *tmp;
- switch (ZEND_NUM_ARGS()) {
- case 1:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) {
- return;
- }
- pgsql_link = NULL;
- id = PGG(default_link);
- break;
- default:
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &from, &from_len) == FAILURE) {
- return;
- }
- break;
- }
- if (pgsql_link == NULL && id == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get default pgsql link");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (pgsql == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get pgsql link");
- RETURN_FALSE;
- }
- if (escape_literal) {
- tmp = PGSQLescapeLiteral(pgsql, from, (size_t)from_len);
- } else {
- tmp = PGSQLescapeIdentifier(pgsql, from, (size_t)from_len);
- }
- if (!tmp) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape");
- RETURN_FALSE;
- }
- to = estrdup(tmp);
- PGSQLfree(tmp);
- RETVAL_STRINGL_CHECK(to, strlen(to), 0);
- }
- /* {{{ proto string pg_escape_literal([resource connection,] string data)
- Escape parameter as string literal (i.e. parameter) */
- PHP_FUNCTION(pg_escape_literal)
- {
- php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
- }
- /* }}} */
- /* {{{ proto string pg_escape_identifier([resource connection,] string data)
- Escape identifier (i.e. table name, field name) */
- PHP_FUNCTION(pg_escape_identifier)
- {
- php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
- }
- /* }}} */
- #endif
- /* {{{ proto string pg_result_error(resource result)
- Get error message associated with result */
- PHP_FUNCTION(pg_result_error)
- {
- zval *result;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- char *err = NULL;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &result) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (!pgsql_result) {
- RETURN_FALSE;
- }
- err = (char *)PQresultErrorMessage(pgsql_result);
- RETURN_STRING(err,1);
- }
- /* }}} */
- #if HAVE_PQRESULTERRORFIELD
- /* {{{ proto string pg_result_error_field(resource result, int fieldcode)
- Get error message field associated with result */
- PHP_FUNCTION(pg_result_error_field)
- {
- zval *result;
- long fieldcode;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- char *field = NULL;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rl",
- &result, &fieldcode) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (!pgsql_result) {
- RETURN_FALSE;
- }
- if (fieldcode & (PG_DIAG_SEVERITY|PG_DIAG_SQLSTATE|PG_DIAG_MESSAGE_PRIMARY|PG_DIAG_MESSAGE_DETAIL
- |PG_DIAG_MESSAGE_HINT|PG_DIAG_STATEMENT_POSITION
- #if PG_DIAG_INTERNAL_POSITION
- |PG_DIAG_INTERNAL_POSITION
- #endif
- #if PG_DIAG_INTERNAL_QUERY
- |PG_DIAG_INTERNAL_QUERY
- #endif
- |PG_DIAG_CONTEXT|PG_DIAG_SOURCE_FILE|PG_DIAG_SOURCE_LINE
- |PG_DIAG_SOURCE_FUNCTION)) {
- field = (char *)PQresultErrorField(pgsql_result, fieldcode);
- if (field == NULL) {
- RETURN_NULL();
- } else {
- RETURN_STRING(field, 1);
- }
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- #endif
- /* {{{ proto int pg_connection_status(resource connection)
- Get connection status */
- PHP_FUNCTION(pg_connection_status)
- {
- zval *pgsql_link = NULL;
- int id = -1;
- PGconn *pgsql;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- RETURN_LONG(PQstatus(pgsql));
- }
- /* }}} */
- #if HAVE_PGTRANSACTIONSTATUS
- /* {{{ proto int pg_transaction_status(resource connection)
- Get transaction status */
- PHP_FUNCTION(pg_transaction_status)
- {
- zval *pgsql_link = NULL;
- int id = -1;
- PGconn *pgsql;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- RETURN_LONG(PQtransactionStatus(pgsql));
- }
- #endif
- /* }}} */
- /* {{{ proto bool pg_connection_reset(resource connection)
- Reset connection (reconnect) */
- PHP_FUNCTION(pg_connection_reset)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- PQreset(pgsql);
- if (PQstatus(pgsql) == CONNECTION_BAD) {
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- #define PHP_PG_ASYNC_IS_BUSY 1
- #define PHP_PG_ASYNC_REQUEST_CANCEL 2
- /* {{{ php_pgsql_flush_query
- */
- static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC)
- {
- PGresult *res;
- int leftover = 0;
- if (PQ_SETNONBLOCKING(pgsql, 1)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to nonblocking mode");
- return -1;
- }
- while ((res = PQgetResult(pgsql))) {
- PQclear(res);
- leftover++;
- }
- PQ_SETNONBLOCKING(pgsql, 0);
- return leftover;
- }
- /* }}} */
- /* {{{ php_pgsql_do_async
- */
- static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- PGresult *pgsql_result;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (PQ_SETNONBLOCKING(pgsql, 1)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- switch(entry_type) {
- case PHP_PG_ASYNC_IS_BUSY:
- PQconsumeInput(pgsql);
- Z_LVAL_P(return_value) = PQisBusy(pgsql);
- Z_TYPE_P(return_value) = IS_LONG;
- break;
- case PHP_PG_ASYNC_REQUEST_CANCEL:
- Z_LVAL_P(return_value) = PQrequestCancel(pgsql);
- Z_TYPE_P(return_value) = IS_LONG;
- while ((pgsql_result = PQgetResult(pgsql))) {
- PQclear(pgsql_result);
- }
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "PostgreSQL module error, please report this error");
- break;
- }
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- }
- convert_to_boolean_ex(&return_value);
- }
- /* }}} */
- /* {{{ proto bool pg_cancel_query(resource connection)
- Cancel request */
- PHP_FUNCTION(pg_cancel_query)
- {
- php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_ASYNC_REQUEST_CANCEL);
- }
- /* }}} */
- /* {{{ proto bool pg_connection_busy(resource connection)
- Get connection is busy or not */
- PHP_FUNCTION(pg_connection_busy)
- {
- php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_ASYNC_IS_BUSY);
- }
- /* }}} */
- static int _php_pgsql_link_has_results(PGconn *pgsql)
- {
- PGresult *result;
- while ((result = PQgetResult(pgsql))) {
- PQclear(result);
- return 1;
- }
- return 0;
- }
- /* {{{ proto bool pg_send_query(resource connection, string query)
- Send asynchronous query */
- PHP_FUNCTION(pg_send_query)
- {
- zval *pgsql_link;
- char *query;
- int len;
- int id = -1;
- PGconn *pgsql;
- int is_non_blocking;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &len) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- is_non_blocking = PQisnonblocking(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- if (_php_pgsql_link_has_results(pgsql)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,
- "There are results on this connection. Call pg_get_result() until it returns FALSE");
- }
- if (is_non_blocking) {
- if (!PQsendQuery(pgsql, query)) {
- RETURN_FALSE;
- }
- ret = PQflush(pgsql);
- } else {
- if (!PQsendQuery(pgsql, query)) {
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQreset(pgsql);
- }
- if (!PQsendQuery(pgsql, query)) {
- RETURN_FALSE;
- }
- }
- /* Wait to finish sending buffer */
- while ((ret = PQflush(pgsql))) {
- if (ret == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer");
- break;
- }
- usleep(10000);
- }
- if (PQ_SETNONBLOCKING(pgsql, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- }
- }
- if (ret == 0) {
- RETURN_TRUE;
- } else if (ret == -1) {
- RETURN_FALSE;
- } else {
- RETURN_LONG(0);
- }
- }
- /* }}} */
- #if HAVE_PQSENDQUERYPARAMS
- /* {{{ proto bool pg_send_query_params(resource connection, string query, array params)
- Send asynchronous parameterized query */
- PHP_FUNCTION(pg_send_query_params)
- {
- zval *pgsql_link, *pv_param_arr, **tmp;
- int num_params = 0;
- char **params = NULL;
- char *query;
- int query_len, id = -1;
- PGconn *pgsql;
- int is_non_blocking;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa/", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) {
- return;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- is_non_blocking = PQisnonblocking(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- if (_php_pgsql_link_has_results(pgsql)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,
- "There are results on this connection. Call pg_get_result() until it returns FALSE");
- }
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr));
- num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr));
- if (num_params > 0) {
- int i = 0;
- params = (char **)safe_emalloc(sizeof(char *), num_params, 0);
- for(i = 0; i < num_params; i++) {
- if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- if (Z_TYPE_PP(tmp) == IS_NULL) {
- params[i] = NULL;
- } else {
- zval tmp_val = **tmp;
- zval_copy_ctor(&tmp_val);
- convert_to_string(&tmp_val);
- if (Z_TYPE(tmp_val) != IS_STRING) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
- zval_dtor(&tmp_val);
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
- zval_dtor(&tmp_val);
- }
- zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr));
- }
- }
- if (PQsendQueryParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0)) {
- _php_pgsql_free_params(params, num_params);
- } else if (is_non_blocking) {
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- } else {
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQreset(pgsql);
- }
- if (!PQsendQueryParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0)) {
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- }
- if (is_non_blocking) {
- ret = PQflush(pgsql);
- } else {
- /* Wait to finish sending buffer */
- while ((ret = PQflush(pgsql))) {
- if (ret == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer");
- break;
- }
- usleep(10000);
- }
- if (PQ_SETNONBLOCKING(pgsql, 0) != 0) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- }
- }
- if (ret == 0) {
- RETURN_TRUE;
- } else if (ret == -1) {
- RETURN_FALSE;
- } else {
- RETURN_LONG(0);
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQSENDPREPARE
- /* {{{ proto bool pg_send_prepare(resource connection, string stmtname, string query)
- Asynchronously prepare a query for future execution */
- PHP_FUNCTION(pg_send_prepare)
- {
- zval *pgsql_link;
- char *query, *stmtname;
- int stmtname_len, query_len, id = -1;
- PGconn *pgsql;
- int is_non_blocking;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) {
- return;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- is_non_blocking = PQisnonblocking(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- if (_php_pgsql_link_has_results(pgsql)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,
- "There are results on this connection. Call pg_get_result() until it returns FALSE");
- }
- if (!PQsendPrepare(pgsql, stmtname, query, 0, NULL)) {
- if (is_non_blocking) {
- RETURN_FALSE;
- } else {
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQreset(pgsql);
- }
- if (!PQsendPrepare(pgsql, stmtname, query, 0, NULL)) {
- RETURN_FALSE;
- }
- }
- }
- if (is_non_blocking) {
- ret = PQflush(pgsql);
- } else {
- /* Wait to finish sending buffer */
- while ((ret = PQflush(pgsql))) {
- if (ret == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer");
- break;
- }
- usleep(10000);
- }
- if (PQ_SETNONBLOCKING(pgsql, 0) != 0) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- }
- }
- if (ret == 0) {
- RETURN_TRUE;
- } else if (ret == -1) {
- RETURN_FALSE;
- } else {
- RETURN_LONG(0);
- }
- }
- /* }}} */
- #endif
- #if HAVE_PQSENDQUERYPREPARED
- /* {{{ proto bool pg_send_execute(resource connection, string stmtname, array params)
- Executes prevriously prepared stmtname asynchronously */
- PHP_FUNCTION(pg_send_execute)
- {
- zval *pgsql_link;
- zval *pv_param_arr, **tmp;
- int num_params = 0;
- char **params = NULL;
- char *stmtname;
- int stmtname_len, id = -1;
- PGconn *pgsql;
- int is_non_blocking;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) {
- return;
- }
- if (pgsql_link == NULL && id == -1) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- is_non_blocking = PQisnonblocking(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- if (_php_pgsql_link_has_results(pgsql)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,
- "There are results on this connection. Call pg_get_result() until it returns FALSE");
- }
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr));
- num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr));
- if (num_params > 0) {
- int i = 0;
- params = (char **)safe_emalloc(sizeof(char *), num_params, 0);
- for (i = 0; i < num_params; i++) {
- if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- if (Z_TYPE_PP(tmp) == IS_NULL) {
- params[i] = NULL;
- } else {
- zval tmp_val = **tmp;
- zval_copy_ctor(&tmp_val);
- convert_to_string(&tmp_val);
- if (Z_TYPE(tmp_val) != IS_STRING) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
- zval_dtor(&tmp_val);
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
- zval_dtor(&tmp_val);
- }
- zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr));
- }
- }
- if (PQsendQueryPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0)) {
- _php_pgsql_free_params(params, num_params);
- } else if (is_non_blocking) {
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- } else {
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
- PQreset(pgsql);
- }
- if (!PQsendQueryPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0)) {
- _php_pgsql_free_params(params, num_params);
- RETURN_FALSE;
- }
- }
- if (is_non_blocking) {
- ret = PQflush(pgsql);
- } else {
- /* Wait to finish sending buffer */
- while ((ret = PQflush(pgsql))) {
- if (ret == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer");
- break;
- }
- usleep(10000);
- }
- if (PQ_SETNONBLOCKING(pgsql, 0) != 0) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
- }
- }
- if (ret == 0) {
- RETURN_TRUE;
- } else if (ret == -1) {
- RETURN_FALSE;
- } else {
- RETURN_LONG(0);
- }
- }
- /* }}} */
- #endif
- /* {{{ proto resource pg_get_result(resource connection)
- Get asynchronous query result */
- PHP_FUNCTION(pg_get_result)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- pgsql_result = PQgetResult(pgsql);
- if (!pgsql_result) {
- /* no result */
- RETURN_FALSE;
- }
- pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pg_result->conn = pgsql;
- pg_result->result = pgsql_result;
- pg_result->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
- }
- /* }}} */
- /* {{{ proto mixed pg_result_status(resource result[, long result_type])
- Get status of query result */
- PHP_FUNCTION(pg_result_status)
- {
- zval *result;
- long result_type = PGSQL_STATUS_LONG;
- ExecStatusType status;
- PGresult *pgsql_result;
- pgsql_result_handle *pg_result;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l",
- &result, &result_type) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
- pgsql_result = pg_result->result;
- if (result_type == PGSQL_STATUS_LONG) {
- status = PQresultStatus(pgsql_result);
- RETURN_LONG((int)status);
- }
- else if (result_type == PGSQL_STATUS_STRING) {
- RETURN_STRING(PQcmdStatus(pgsql_result), 1);
- }
- else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Optional 2nd parameter should be PGSQL_STATUS_LONG or PGSQL_STATUS_STRING");
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ proto array pg_get_notify([resource connection[, result_type]])
- Get asynchronous notification */
- PHP_FUNCTION(pg_get_notify)
- {
- zval *pgsql_link;
- int id = -1;
- long result_type = PGSQL_ASSOC;
- PGconn *pgsql;
- PGnotify *pgsql_notify;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l",
- &pgsql_link, &result_type) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (!(result_type & PGSQL_BOTH)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type");
- RETURN_FALSE;
- }
- PQconsumeInput(pgsql);
- pgsql_notify = PQnotifies(pgsql);
- if (!pgsql_notify) {
- /* no notify message */
- RETURN_FALSE;
- }
- array_init(return_value);
- if (result_type & PGSQL_NUM) {
- add_index_string(return_value, 0, pgsql_notify->relname, 1);
- add_index_long(return_value, 1, pgsql_notify->be_pid);
- #if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
- if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) {
- #else
- if (atof(PG_VERSION) >= 9.0) {
- #endif
- #if HAVE_PQPARAMETERSTATUS
- add_index_string(return_value, 2, pgsql_notify->extra, 1);
- #endif
- }
- }
- if (result_type & PGSQL_ASSOC) {
- add_assoc_string(return_value, "message", pgsql_notify->relname, 1);
- add_assoc_long(return_value, "pid", pgsql_notify->be_pid);
- #if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
- if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) {
- #else
- if (atof(PG_VERSION) >= 9.0) {
- #endif
- #if HAVE_PQPARAMETERSTATUS
- add_assoc_string(return_value, "payload", pgsql_notify->extra, 1);
- #endif
- }
- }
- PQfreemem(pgsql_notify);
- }
- /* }}} */
- /* {{{ proto int pg_get_pid([resource connection)
- Get backend(server) pid */
- PHP_FUNCTION(pg_get_pid)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r",
- &pgsql_link) == FAILURE) {
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- RETURN_LONG(PQbackendPID(pgsql));
- }
- /* }}} */
- static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
- {
- return 0;
- }
- static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
- {
- return 0;
- }
- static int php_pgsql_fd_close(php_stream *stream, int close_handle TSRMLS_DC)
- {
- return EOF;
- }
- static int php_pgsql_fd_flush(php_stream *stream TSRMLS_DC)
- {
- return FAILURE;
- }
- static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC)
- {
- PGconn *pgsql = (PGconn *) stream->abstract;
- switch (option) {
- case PHP_STREAM_OPTION_BLOCKING:
- return PQ_SETNONBLOCKING(pgsql, value);
- default:
- return FAILURE;
- }
- }
- static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret TSRMLS_DC)
- {
- PGconn *pgsql = (PGconn *) stream->abstract;
- int fd_number;
- switch (cast_as) {
- case PHP_STREAM_AS_FD_FOR_SELECT:
- case PHP_STREAM_AS_FD:
- case PHP_STREAM_AS_SOCKETD:
- if (ret) {
- fd_number = PQsocket(pgsql);
- if (fd_number == -1) {
- return FAILURE;
- }
- *(php_socket_t *)ret = fd_number;
- return SUCCESS;
- }
- default:
- return FAILURE;
- }
- }
- /* {{{ proto resource pg_socket(resource)
- Get a read-only handle to the socket underlying the pgsql connection */
- PHP_FUNCTION(pg_socket)
- {
- zval *pgsql_link;
- php_stream *stream;
- PGconn *pgsql;
- int id = -1;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- stream = php_stream_alloc(&php_stream_pgsql_fd_ops, pgsql, NULL, "r");
- if (stream) {
- php_stream_to_zval(stream, return_value);
- return;
- }
- RETURN_FALSE;
- }
- /* }}} */
- /* {{{ proto bool pg_consume_input(resource)
- Reads input on the connection */
- PHP_FUNCTION(pg_consume_input)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- RETURN_BOOL(PQconsumeInput(pgsql));
- }
- /* }}} */
- /* {{{ proto mixed pg_flush(resource)
- Flush outbound query data on the connection */
- PHP_FUNCTION(pg_flush)
- {
- zval *pgsql_link;
- int id = -1;
- PGconn *pgsql;
- int ret;
- int is_non_blocking;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- is_non_blocking = PQisnonblocking(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
- RETURN_FALSE;
- }
- ret = PQflush(pgsql);
- if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 0) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed resetting connection to blocking mode");
- }
- switch (ret) {
- case 0: RETURN_TRUE; break;
- case 1: RETURN_LONG(0); break;
- default: RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ php_pgsql_meta_data
- * TODO: Add meta_data cache for better performance
- */
- PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended TSRMLS_DC)
- {
- PGresult *pg_result;
- char *src, *tmp_name, *tmp_name2 = NULL;
- char *escaped;
- smart_str querystr = {0};
- size_t new_len;
- int i, num_rows;
- zval *elem;
- if (!*table_name) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The table name must be specified");
- return FAILURE;
- }
- src = estrdup(table_name);
- tmp_name = php_strtok_r(src, ".", &tmp_name2);
- if (!tmp_name) {
- efree(src);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The table name must be specified");
- return FAILURE;
- }
- if (!tmp_name2 || !*tmp_name2) {
- /* Default schema */
- tmp_name2 = tmp_name;
- tmp_name = "public";
- }
- if (extended) {
- smart_str_appends(&querystr,
- "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims, t.typtype, "
- "d.description "
- "FROM pg_class as c "
- " JOIN pg_attribute a ON (a.attrelid = c.oid) "
- " JOIN pg_type t ON (a.atttypid = t.oid) "
- " JOIN pg_namespace n ON (c.relnamespace = n.oid) "
- " LEFT JOIN pg_description d ON (d.objoid=a.attrelid AND d.objsubid=a.attnum AND c.oid=d.objoid) "
- "WHERE a.attnum > 0 AND c.relname = '");
- } else {
- smart_str_appends(&querystr,
- "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotnull, a.atthasdef, a.attndims, t.typtype "
- "FROM pg_class as c "
- " JOIN pg_attribute a ON (a.attrelid = c.oid) "
- " JOIN pg_type t ON (a.atttypid = t.oid) "
- " JOIN pg_namespace n ON (c.relnamespace = n.oid) "
- "WHERE a.attnum > 0 AND c.relname = '");
- }
- escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1);
- new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), NULL);
- if (new_len) {
- smart_str_appendl(&querystr, escaped, new_len);
- }
- efree(escaped);
- smart_str_appends(&querystr, "' AND n.nspname = '");
- escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1);
- new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), NULL);
- if (new_len) {
- smart_str_appendl(&querystr, escaped, new_len);
- }
- efree(escaped);
- smart_str_appends(&querystr, "' ORDER BY a.attnum;");
- smart_str_0(&querystr);
- efree(src);
- pg_result = PQexec(pg_link, querystr.c);
- if (PQresultStatus(pg_result) != PGRES_TUPLES_OK || (num_rows = PQntuples(pg_result)) == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Table '%s' doesn't exists", table_name);
- smart_str_free(&querystr);
- PQclear(pg_result);
- return FAILURE;
- }
- smart_str_free(&querystr);
- for (i = 0; i < num_rows; i++) {
- char *name;
- MAKE_STD_ZVAL(elem);
- array_init(elem);
- /* pg_attribute.attnum */
- add_assoc_long(elem, "num", atoi(PQgetvalue(pg_result,i,1)));
- /* pg_type.typname */
- add_assoc_string(elem, "type", PQgetvalue(pg_result,i,2), 1);
- /* pg_attribute.attlen */
- add_assoc_long(elem, "len", atoi(PQgetvalue(pg_result,i,3)));
- /* pg_attribute.attnonull */
- add_assoc_bool(elem, "not null", !strcmp(PQgetvalue(pg_result,i,4), "t"));
- /* pg_attribute.atthasdef */
- add_assoc_bool(elem, "has default", !strcmp(PQgetvalue(pg_result,i,5), "t"));
- /* pg_attribute.attndims */
- add_assoc_long(elem, "array dims", atoi(PQgetvalue(pg_result,i,6)));
- /* pg_type.typtype */
- add_assoc_bool(elem, "is enum", !strcmp(PQgetvalue(pg_result,i,7), "e"));
- if (extended) {
- /* pg_type.typtype */
- add_assoc_bool(elem, "is base", !strcmp(PQgetvalue(pg_result,i,7), "b"));
- add_assoc_bool(elem, "is composite", !strcmp(PQgetvalue(pg_result,i,7), "c"));
- add_assoc_bool(elem, "is pesudo", !strcmp(PQgetvalue(pg_result,i,7), "p"));
- /* pg_description.description */
- add_assoc_string(elem, "description", PQgetvalue(pg_result,i,8), 1);
- }
- /* pg_attribute.attname */
- name = PQgetvalue(pg_result,i,0);
- add_assoc_zval(meta, name, elem);
- }
- PQclear(pg_result);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ proto array pg_meta_data(resource db, string table [, bool extended])
- Get meta_data */
- PHP_FUNCTION(pg_meta_data)
- {
- zval *pgsql_link;
- char *table_name;
- uint table_name_len;
- zend_bool extended=0;
- PGconn *pgsql;
- int id = -1;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b",
- &pgsql_link, &table_name, &table_name_len, &extended) == FAILURE) {
- return;
- }
- ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- array_init(return_value);
- if (php_pgsql_meta_data(pgsql, table_name, return_value, extended TSRMLS_CC) == FAILURE) {
- zval_dtor(return_value); /* destroy array */
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ php_pgsql_get_data_type
- */
- static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t len)
- {
- /* This is stupid way to do. I'll fix it when I decied how to support
- user defined types. (Yasuo) */
- /* boolean */
- if (!strcmp(type_name, "bool")|| !strcmp(type_name, "boolean"))
- return PG_BOOL;
- /* object id */
- if (!strcmp(type_name, "oid"))
- return PG_OID;
- /* integer */
- if (!strcmp(type_name, "int2") || !strcmp(type_name, "smallint"))
- return PG_INT2;
- if (!strcmp(type_name, "int4") || !strcmp(type_name, "integer"))
- return PG_INT4;
- if (!strcmp(type_name, "int8") || !strcmp(type_name, "bigint"))
- return PG_INT8;
- /* real and other */
- if (!strcmp(type_name, "float4") || !strcmp(type_name, "real"))
- return PG_FLOAT4;
- if (!strcmp(type_name, "float8") || !strcmp(type_name, "double precision"))
- return PG_FLOAT8;
- if (!strcmp(type_name, "numeric"))
- return PG_NUMERIC;
- if (!strcmp(type_name, "money"))
- return PG_MONEY;
- /* character */
- if (!strcmp(type_name, "text"))
- return PG_TEXT;
- if (!strcmp(type_name, "bpchar") || !strcmp(type_name, "character"))
- return PG_CHAR;
- if (!strcmp(type_name, "varchar") || !strcmp(type_name, "character varying"))
- return PG_VARCHAR;
- /* time and interval */
- if (!strcmp(type_name, "abstime"))
- return PG_UNIX_TIME;
- if (!strcmp(type_name, "reltime"))
- return PG_UNIX_TIME_INTERVAL;
- if (!strcmp(type_name, "tinterval"))
- return PG_UNIX_TIME_INTERVAL;
- if (!strcmp(type_name, "date"))
- return PG_DATE;
- if (!strcmp(type_name, "time"))
- return PG_TIME;
- if (!strcmp(type_name, "time with time zone") || !strcmp(type_name, "timetz"))
- return PG_TIME_WITH_TIMEZONE;
- if (!strcmp(type_name, "timestamp without time zone") || !strcmp(type_name, "timestamp"))
- return PG_TIMESTAMP;
- if (!strcmp(type_name, "timestamp with time zone") || !strcmp(type_name, "timestamptz"))
- return PG_TIMESTAMP_WITH_TIMEZONE;
- if (!strcmp(type_name, "interval"))
- return PG_INTERVAL;
- /* binary */
- if (!strcmp(type_name, "bytea"))
- return PG_BYTEA;
- /* network */
- if (!strcmp(type_name, "cidr"))
- return PG_CIDR;
- if (!strcmp(type_name, "inet"))
- return PG_INET;
- if (!strcmp(type_name, "macaddr"))
- return PG_MACADDR;
- /* bit */
- if (!strcmp(type_name, "bit"))
- return PG_BIT;
- if (!strcmp(type_name, "bit varying"))
- return PG_VARBIT;
- /* geometric */
- if (!strcmp(type_name, "line"))
- return PG_LINE;
- if (!strcmp(type_name, "lseg"))
- return PG_LSEG;
- if (!strcmp(type_name, "box"))
- return PG_BOX;
- if (!strcmp(type_name, "path"))
- return PG_PATH;
- if (!strcmp(type_name, "point"))
- return PG_POINT;
- if (!strcmp(type_name, "polygon"))
- return PG_POLYGON;
- if (!strcmp(type_name, "circle"))
- return PG_CIRCLE;
- return PG_UNKNOWN;
- }
- /* }}} */
- /* {{{ php_pgsql_convert_match
- * test field value with regular expression specified.
- */
- static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , int icase TSRMLS_DC)
- {
- regex_t re;
- regmatch_t *subs;
- int regopt = REG_EXTENDED;
- int regerr, ret = SUCCESS;
- int i;
- /* Check invalid chars for POSIX regex */
- for (i = 0; i < str_len; i++) {
- if (str[i] == '\n' ||
- str[i] == '\r' ||
- str[i] == '\0' ) {
- return FAILURE;
- }
- }
- if (icase) {
- regopt |= REG_ICASE;
- }
- regerr = regcomp(&re, regex, regopt);
- if (regerr) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot compile regex");
- regfree(&re);
- return FAILURE;
- }
- subs = (regmatch_t *)ecalloc(sizeof(regmatch_t), re.re_nsub+1);
- regerr = regexec(&re, str, re.re_nsub+1, subs, 0);
- if (regerr == REG_NOMATCH) {
- ret = FAILURE;
- }
- else if (regerr) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot exec regex");
- ret = FAILURE;
- }
- regfree(&re);
- efree(subs);
- return ret;
- }
- /* }}} */
- /* {{{ php_pgsql_add_quote
- * add quotes around string.
- */
- static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC)
- {
- smart_str str = {0};
- assert(Z_TYPE_P(src) == IS_STRING);
- assert(should_free == 1 || should_free == 0);
- smart_str_appendc(&str, 'E');
- smart_str_appendc(&str, '\'');
- smart_str_appendl(&str, Z_STRVAL_P(src), Z_STRLEN_P(src));
- smart_str_appendc(&str, '\'');
- smart_str_0(&str);
- if (should_free) {
- efree(Z_STRVAL_P(src));
- }
- Z_STRVAL_P(src) = str.c;
- Z_STRLEN_P(src) = str.len;
- return SUCCESS;
- }
- /* }}} */
- #define PGSQL_CONV_CHECK_IGNORE() \
- if (!err && Z_TYPE_P(new_val) == IS_STRING && !strcmp(Z_STRVAL_P(new_val), "NULL")) { \
- /* if new_value is string "NULL" and field has default value, remove element to use default value */ \
- if (!(opt & PGSQL_CONV_IGNORE_DEFAULT) && Z_BVAL_PP(has_default)) { \
- zval_dtor(new_val); \
- FREE_ZVAL(new_val); \
- skip_field = 1; \
- } \
- /* raise error if it's not null and cannot be ignored */ \
- else if (!(opt & PGSQL_CONV_IGNORE_NOT_NULL) && Z_BVAL_PP(not_null)) { \
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected NULL for 'NOT NULL' field '%s'", field ); \
- err = 1; \
- } \
- }
- /* {{{ php_pgsql_convert
- * check and convert array values (fieldname=>vlaue pair) for sql
- */
- PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, ulong opt TSRMLS_DC)
- {
- HashPosition pos;
- char *field = NULL;
- uint field_len = -1;
- ulong num_idx = -1;
- zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val;
- int key_type, err = 0, skip_field;
- php_pgsql_data_type data_type;
- assert(pg_link != NULL);
- assert(Z_TYPE_P(values) == IS_ARRAY);
- assert(Z_TYPE_P(result) == IS_ARRAY);
- assert(!(opt & ~PGSQL_CONV_OPTS));
- if (!table_name) {
- return FAILURE;
- }
- MAKE_STD_ZVAL(meta);
- array_init(meta);
- /* table_name is escaped by php_pgsql_meta_data */
- if (php_pgsql_meta_data(pg_link, table_name, meta, 0 TSRMLS_CC) == FAILURE) {
- zval_dtor(meta);
- FREE_ZVAL(meta);
- return FAILURE;
- }
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos)) {
- skip_field = 0;
- new_val = NULL;
- if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTENT) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get array key type");
- err = 1;
- }
- if (!err && key_type == HASH_KEY_IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values");
- err = 1;
- }
- if (!err && key_type == HASH_KEY_NON_EXISTENT) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values");
- err = 1;
- }
- if (!err && zend_hash_find(Z_ARRVAL_P(meta), field, field_len, (void **)&def) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid field name (%s) in values", field);
- err = 1;
- }
- if (!err && zend_hash_find(Z_ARRVAL_PP(def), "type", sizeof("type"), (void **)&type) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'type'");
- err = 1;
- }
- if (!err && zend_hash_find(Z_ARRVAL_PP(def), "not null", sizeof("not null"), (void **)¬_null) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'not null'");
- err = 1;
- }
- if (!err && zend_hash_find(Z_ARRVAL_PP(def), "has default", sizeof("has default"), (void **)&has_default) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'has default'");
- err = 1;
- }
- if (!err && zend_hash_find(Z_ARRVAL_PP(def), "is enum", sizeof("is enum"), (void **)&is_enum) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'is enum'");
- err = 1;
- }
- if (!err && (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scalar values as field values");
- err = 1;
- }
- if (err) {
- break; /* break out for() */
- }
- ALLOC_INIT_ZVAL(new_val);
- if (Z_BVAL_PP(is_enum)) {
- /* enums need to be treated like strings */
- data_type = PG_TEXT;
- }
- else {
- data_type = php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type));
- }
- switch(data_type)
- {
- case PG_BOOL:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRING(new_val, "NULL", 1);
- }
- else {
- if (!strcmp(Z_STRVAL_PP(val), "t") || !strcmp(Z_STRVAL_PP(val), "T") ||
- !strcmp(Z_STRVAL_PP(val), "y") || !strcmp(Z_STRVAL_PP(val), "Y") ||
- !strcmp(Z_STRVAL_PP(val), "true") || !strcmp(Z_STRVAL_PP(val), "True") ||
- !strcmp(Z_STRVAL_PP(val), "yes") || !strcmp(Z_STRVAL_PP(val), "Yes") ||
- !strcmp(Z_STRVAL_PP(val), "1")) {
- ZVAL_STRINGL(new_val, "'t'", sizeof("'t'")-1, 1);
- }
- else if (!strcmp(Z_STRVAL_PP(val), "f") || !strcmp(Z_STRVAL_PP(val), "F") ||
- !strcmp(Z_STRVAL_PP(val), "n") || !strcmp(Z_STRVAL_PP(val), "N") ||
- !strcmp(Z_STRVAL_PP(val), "false") || !strcmp(Z_STRVAL_PP(val), "False") ||
- !strcmp(Z_STRVAL_PP(val), "no") || !strcmp(Z_STRVAL_PP(val), "No") ||
- !strcmp(Z_STRVAL_PP(val), "0")) {
- ZVAL_STRINGL(new_val, "'f'", sizeof("'f'")-1, 1);
- }
- else {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected invalid value (%s) for PostgreSQL %s field (%s)", Z_STRVAL_PP(val), Z_STRVAL_PP(type), field);
- err = 1;
- }
- }
- break;
- case IS_LONG:
- case IS_BOOL:
- if (Z_LVAL_PP(val)) {
- ZVAL_STRINGL(new_val, "'t'", sizeof("'t'")-1, 1);
- }
- else {
- ZVAL_STRINGL(new_val, "'f'", sizeof("'f'")-1, 1);
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_OID:
- case PG_INT2:
- case PG_INT4:
- case PG_INT8:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* FIXME: better regex must be used */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- }
- }
- break;
- case IS_DOUBLE:
- ZVAL_DOUBLE(new_val, Z_DVAL_PP(val));
- convert_to_long_ex(&new_val);
- break;
- case IS_LONG:
- ZVAL_LONG(new_val, Z_LVAL_PP(val));
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for pgsql '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_NUMERIC:
- case PG_MONEY:
- case PG_FLOAT4:
- case PG_FLOAT8:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* better regex? */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$", 0 TSRMLS_CC) == FAILURE) {
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[+-]{0,1}(inf)(inity){0,1}$", 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- } else {
- ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- else {
- ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1);
- }
- }
- break;
- case IS_LONG:
- ZVAL_LONG(new_val, Z_LVAL_PP(val));
- break;
- case IS_DOUBLE:
- ZVAL_DOUBLE(new_val, Z_DVAL_PP(val));
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- /* Exotic types are handled as string also.
- Please feel free to add more valitions. Invalid query fails
- at execution anyway. */
- case PG_TEXT:
- case PG_CHAR:
- case PG_VARCHAR:
- /* bit */
- case PG_BIT:
- case PG_VARBIT:
- /* geometric */
- case PG_LINE:
- case PG_LSEG:
- case PG_POINT:
- case PG_BOX:
- case PG_PATH:
- case PG_POLYGON:
- case PG_CIRCLE:
- /* unknown. JSON, Array etc */
- case PG_UNKNOWN:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- if (opt & PGSQL_CONV_FORCE_NULL) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- } else {
- ZVAL_STRINGL(new_val, "''", sizeof("''")-1, 1);
- }
- }
- else {
- char *tmp;
- /* PostgreSQL ignores \0 */
- Z_TYPE_P(new_val) = IS_STRING;
- tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1);
- /* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */
- Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL);
- Z_STRVAL_P(new_val) = tmp;
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- break;
- case IS_LONG:
- ZVAL_LONG(new_val, Z_LVAL_PP(val));
- convert_to_string_ex(&new_val);
- break;
- case IS_DOUBLE:
- ZVAL_DOUBLE(new_val, Z_DVAL_PP(val));
- convert_to_string_ex(&new_val);
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_UNIX_TIME:
- case PG_UNIX_TIME_INTERVAL:
- /* these are the actallay a integer */
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* better regex? */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- convert_to_long_ex(&new_val);
- }
- }
- break;
- case IS_DOUBLE:
- ZVAL_DOUBLE(new_val, Z_DVAL_PP(val));
- convert_to_long_ex(&new_val);
- break;
- case IS_LONG:
- ZVAL_LONG(new_val, Z_LVAL_PP(val));
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_CIDR:
- case PG_INET:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* better regex? IPV6 and IPV4 */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$", 0 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_TIME_WITH_TIMEZONE:
- case PG_TIMESTAMP:
- case PG_TIMESTAMP_WITH_TIMEZONE:
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- } else if (!strcasecmp(Z_STRVAL_PP(val), "now()")) {
- ZVAL_STRINGL(new_val, "NOW()", sizeof("NOW()")-1, 1);
- } else {
- /* better regex? */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- } else {
- ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_DATE:
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* FIXME: better regex must be used */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_TIME:
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- /* FIXME: better regex must be used */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- case PG_INTERVAL:
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRING(new_val, "NULL", 1);
- }
- else {
- /* From the Postgres docs:
- interval values can be written with the following syntax:
- [@] quantity unit [quantity unit...] [direction]
- Where: quantity is a number (possibly signed); unit is second, minute, hour,
- day, week, month, year, decade, century, millennium, or abbreviations or
- plurals of these units [note not *all* abbreviations] ; direction can be
- ago or empty. The at sign (@) is optional noise.
- ...
- Quantities of days, hours, minutes, and seconds can be specified without explicit
- unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10
- sec'.
- */
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val),
- "^(@?[ \\t]+)?("
- /* Textual time units and their abbreviations: */
- "(([-+]?[ \\t]+)?"
- "[0-9]+(\\.[0-9]*)?[ \\t]*"
- "(millenniums|millennia|millennium|mil|mils|"
- "centuries|century|cent|c|"
- "decades|decade|dec|decs|"
- "years|year|y|"
- "months|month|mon|"
- "weeks|week|w|"
- "days|day|d|"
- "hours|hour|hr|hrs|h|"
- "minutes|minute|mins|min|m|"
- "seconds|second|secs|sec|s))+|"
- /* Textual time units plus (dd)* hh[:mm[:ss]] */
- "((([-+]?[ \\t]+)?"
- "[0-9]+(\\.[0-9]*)?[ \\t]*"
- "(millenniums|millennia|millennium|mil|mils|"
- "centuries|century|cent|c|"
- "decades|decade|dec|decs|"
- "years|year|y|"
- "months|month|mon|"
- "weeks|week|w|"
- "days|day|d))+"
- "([-+]?[ \\t]+"
- "([0-9]+[ \\t]+)+" /* dd */
- "(([0-9]{1,2}:){0,2}[0-9]{0,2})" /* hh:[mm:[ss]] */
- ")?))"
- "([ \\t]+ago)?$",
- 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRING(new_val, "NULL", 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- #ifdef HAVE_PQESCAPE
- case PG_BYTEA:
- switch (Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRING(new_val, "NULL", 1);
- }
- else {
- unsigned char *tmp;
- size_t to_len;
- smart_str s = {0};
- #ifdef HAVE_PQESCAPE_BYTEA_CONN
- tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_PP(val), Z_STRLEN_PP(val), &to_len);
- #else
- tmp = PQescapeBytea(Z_STRVAL_PP(val), (unsigned char *)Z_STRLEN_PP(val), &to_len);
- #endif
- Z_TYPE_P(new_val) = IS_STRING;
- Z_STRLEN_P(new_val) = to_len-1; /* PQescapeBytea's to_len includes additional '\0' */
- Z_STRVAL_P(new_val) = emalloc(to_len);
- memcpy(Z_STRVAL_P(new_val), tmp, to_len);
- PQfreemem(tmp);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- smart_str_appendl(&s, Z_STRVAL_P(new_val), Z_STRLEN_P(new_val));
- smart_str_0(&s);
- efree(Z_STRVAL_P(new_val));
- Z_STRVAL_P(new_val) = s.c;
- Z_STRLEN_P(new_val) = s.len;
- }
- break;
- case IS_LONG:
- ZVAL_LONG(new_val, Z_LVAL_PP(val));
- convert_to_string_ex(&new_val);
- break;
- case IS_DOUBLE:
- ZVAL_DOUBLE(new_val, Z_DVAL_PP(val));
- convert_to_string_ex(&new_val);
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- #endif
- case PG_MACADDR:
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (Z_STRLEN_PP(val) == 0) {
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- }
- else {
- if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) {
- err = 1;
- }
- else {
- ZVAL_STRINGL(new_val, Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1);
- php_pgsql_add_quotes(new_val, 1 TSRMLS_CC);
- }
- }
- break;
- case IS_NULL:
- ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1);
- break;
- default:
- err = 1;
- }
- PGSQL_CONV_CHECK_IGNORE();
- if (err) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field);
- }
- break;
- default:
- /* should not happen */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or system data type '%s' for '%s'. Report error", Z_STRVAL_PP(type), field);
- err = 1;
- break;
- } /* switch */
- if (err) {
- zval_dtor(new_val);
- FREE_ZVAL(new_val);
- break; /* break out for() */
- }
- /* If field is NULL and HAS DEFAULT, should be skipped */
- if (!skip_field) {
- char *escaped;
- size_t field_len = strlen(field);
- if (_php_pgsql_detect_identifier_escape(field, field_len) == SUCCESS) {
- add_assoc_zval(result, field, new_val);
- } else {
- escaped = PGSQLescapeIdentifier(pg_link, field, field_len);
- add_assoc_zval(result, escaped, new_val);
- PGSQLfree(escaped);
- }
- }
- } /* for */
- zval_dtor(meta);
- FREE_ZVAL(meta);
- if (err) {
- /* shouldn't destroy & free zval here */
- return FAILURE;
- }
- return SUCCESS;
- }
- /* }}} */
- /* {{{ proto array pg_convert(resource db, string table, array values[, int options])
- Check and convert values for PostgreSQL SQL statement */
- PHP_FUNCTION(pg_convert)
- {
- zval *pgsql_link, *values;
- char *table_name;
- int table_name_len;
- ulong option = 0;
- PGconn *pg_link;
- int id = -1;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
- "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) {
- return;
- }
- if (option & ~PGSQL_CONV_OPTS) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified");
- RETURN_FALSE;
- }
- if (!table_name_len) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Table name is invalid");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (php_pgsql_flush_query(pg_link TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection");
- }
- array_init(return_value);
- if (php_pgsql_convert(pg_link, table_name, values, return_value, option TSRMLS_CC) == FAILURE) {
- zval_dtor(return_value);
- RETURN_FALSE;
- }
- }
- /* }}} */
- static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, ulong opt TSRMLS_DC)
- {
- if (opt & PGSQL_DML_ASYNC) {
- if (PQsendQuery(pg_link, querystr->c)) {
- return 0;
- }
- }
- else {
- PGresult *pg_result;
- pg_result = PQexec(pg_link, querystr->c);
- if (PQresultStatus(pg_result) == expect) {
- PQclear(pg_result);
- return 0;
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", PQresultErrorMessage(pg_result));
- PQclear(pg_result);
- }
- }
- return -1;
- }
- static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table)
- {
- char *table_copy, *escaped, *tmp;
- const char *token;
- size_t len;
- /* schame.table should be "schame"."table" */
- table_copy = estrdup(table);
- token = php_strtok_r(table_copy, ".", &tmp);
- if (token == NULL) {
- token = table;
- }
- len = strlen(token);
- if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) {
- smart_str_appendl(querystr, token, len);
- } else {
- escaped = PGSQLescapeIdentifier(pg_link, token, len);
- smart_str_appends(querystr, escaped);
- PGSQLfree(escaped);
- }
- if (tmp && *tmp) {
- len = strlen(tmp);
- /* "schema"."table" format */
- if (_php_pgsql_detect_identifier_escape(tmp, len) == SUCCESS) {
- smart_str_appendc(querystr, '.');
- smart_str_appendl(querystr, tmp, len);
- } else {
- escaped = PGSQLescapeIdentifier(pg_link, tmp, len);
- smart_str_appendc(querystr, '.');
- smart_str_appends(querystr, escaped);
- PGSQLfree(escaped);
- }
- }
- efree(table_copy);
- }
- /* {{{ php_pgsql_insert
- */
- PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var_array, ulong opt, char **sql TSRMLS_DC)
- {
- zval **val, *converted = NULL;
- char buf[256];
- char *fld, *tmp;
- smart_str querystr = {0};
- int key_type, ret = FAILURE;
- uint fld_len;
- ulong num_idx;
- HashPosition pos;
- assert(pg_link != NULL);
- assert(table != NULL);
- assert(Z_TYPE_P(var_array) == IS_ARRAY);
- if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) {
- smart_str_appends(&querystr, "INSERT INTO ");
- build_tablename(&querystr, pg_link, table);
- smart_str_appends(&querystr, " DEFAULT VALUES");
- goto no_values;
- }
- /* convert input array if needed */
- if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) {
- MAKE_STD_ZVAL(converted);
- array_init(converted);
- if (php_pgsql_convert(pg_link, table, var_array, converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) {
- goto cleanup;
- }
- var_array = converted;
- }
- smart_str_appends(&querystr, "INSERT INTO ");
- build_tablename(&querystr, pg_link, table);
- smart_str_appends(&querystr, " (");
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos);
- while ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld,
- &fld_len, &num_idx, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
- if (key_type == HASH_KEY_IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted");
- goto cleanup;
- }
- if (opt & PGSQL_DML_ESCAPE) {
- tmp = PGSQLescapeIdentifier(pg_link, fld, fld_len);
- smart_str_appends(&querystr, tmp);
- PGSQLfree(tmp);
- } else {
- smart_str_appendl(&querystr, fld, fld_len - 1);
- }
- smart_str_appendc(&querystr, ',');
- zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos);
- }
- querystr.len--;
- smart_str_appends(&querystr, ") VALUES (");
- /* make values string */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos)) {
- /* we can avoid the key_type check here, because we tested it in the other loop */
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (opt & PGSQL_DML_ESCAPE) {
- size_t new_len;
- char *tmp;
- tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1);
- new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL);
- smart_str_appendc(&querystr, '\'');
- smart_str_appendl(&querystr, tmp, new_len);
- smart_str_appendc(&querystr, '\'');
- efree(tmp);
- } else {
- smart_str_appendl(&querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- }
- break;
- case IS_LONG:
- smart_str_append_long(&querystr, Z_LVAL_PP(val));
- break;
- case IS_DOUBLE:
- smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val)));
- break;
- case IS_NULL:
- smart_str_appendl(&querystr, "NULL", sizeof("NULL")-1);
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects scaler values. type = %d", Z_TYPE_PP(val));
- goto cleanup;
- break;
- }
- smart_str_appendc(&querystr, ',');
- }
- /* Remove the trailing "," */
- querystr.len--;
- smart_str_appends(&querystr, ");");
- no_values:
- smart_str_0(&querystr);
- if ((opt & (PGSQL_DML_EXEC|PGSQL_DML_ASYNC)) &&
- do_exec(&querystr, PGRES_COMMAND_OK, pg_link, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == 0) {
- ret = SUCCESS;
- }
- else if (opt & PGSQL_DML_STRING) {
- ret = SUCCESS;
- }
- cleanup:
- if (!(opt & PGSQL_DML_NO_CONV) && converted) {
- zval_dtor(converted);
- FREE_ZVAL(converted);
- }
- if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) {
- *sql = querystr.c;
- }
- else {
- smart_str_free(&querystr);
- }
- return ret;
- }
- /* }}} */
- /* {{{ proto mixed pg_insert(resource db, string table, array values[, int options])
- Insert values (filed=>value) to table */
- PHP_FUNCTION(pg_insert)
- {
- zval *pgsql_link, *values;
- char *table, *sql = NULL;
- int table_len;
- ulong option = PGSQL_DML_EXEC, return_sql;
- PGconn *pg_link;
- PGresult *pg_result;
- ExecStatusType status;
- pgsql_result_handle *pgsql_handle;
- int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l",
- &pgsql_link, &table, &table_len, &values, &option) == FAILURE) {
- return;
- }
- if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (php_pgsql_flush_query(pg_link TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection");
- }
- return_sql = option & PGSQL_DML_STRING;
- if (option & PGSQL_DML_EXEC) {
- /* return resource when executed */
- option = option & ~PGSQL_DML_EXEC;
- if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- pg_result = PQexec(pg_link, sql);
- if ((PGG(auto_reset_persistent) & 2) && PQstatus(pg_link) != CONNECTION_OK) {
- PQclear(pg_result);
- PQreset(pg_link);
- pg_result = PQexec(pg_link, sql);
- }
- efree(sql);
- if (pg_result) {
- status = PQresultStatus(pg_result);
- } else {
- status = (ExecStatusType) PQstatus(pg_link);
- }
- switch (status) {
- case PGRES_EMPTY_QUERY:
- case PGRES_BAD_RESPONSE:
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- PHP_PQ_ERROR("Query failed: %s", pg_link);
- PQclear(pg_result);
- RETURN_FALSE;
- break;
- case PGRES_COMMAND_OK: /* successful command that did not return rows */
- default:
- if (pg_result) {
- pgsql_handle = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
- pgsql_handle->conn = pg_link;
- pgsql_handle->result = pg_result;
- pgsql_handle->row = 0;
- ZEND_REGISTER_RESOURCE(return_value, pgsql_handle, le_result);
- return;
- } else {
- PQclear(pg_result);
- RETURN_FALSE;
- }
- break;
- }
- } else if (php_pgsql_insert(pg_link, table, values, option, &sql TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- if (return_sql) {
- RETURN_STRING(sql, 0);
- }
- RETURN_TRUE;
- }
- /* }}} */
- static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, HashTable *ht, int where_cond, const char *pad, int pad_len, ulong opt TSRMLS_DC)
- {
- HashPosition pos;
- uint fld_len;
- int key_type;
- ulong num_idx;
- char *fld, *tmp;
- char buf[256];
- zval **val;
- for (zend_hash_internal_pointer_reset_ex(ht, &pos);
- zend_hash_get_current_data_ex(ht, (void **)&val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht, &pos)) {
- key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos);
- if (key_type == HASH_KEY_IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted");
- return -1;
- }
- if (opt & PGSQL_DML_ESCAPE) {
- tmp = PGSQLescapeIdentifier(pg_link, fld, fld_len);
- smart_str_appends(querystr, tmp);
- PGSQLfree(tmp);
- } else {
- smart_str_appendl(querystr, fld, fld_len - 1);
- }
- if (where_cond && (Z_TYPE_PP(val) == IS_BOOL || (Z_TYPE_PP(val) == IS_STRING && !strcmp(Z_STRVAL_PP(val), "NULL")))) {
- smart_str_appends(querystr, " IS ");
- } else {
- smart_str_appendc(querystr, '=');
- }
- switch(Z_TYPE_PP(val)) {
- case IS_STRING:
- if (opt & PGSQL_DML_ESCAPE) {
- size_t new_len;
- tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1);
- new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL);
- smart_str_appendc(querystr, '\'');
- smart_str_appendl(querystr, tmp, new_len);
- smart_str_appendc(querystr, '\'');
- efree(tmp);
- } else {
- smart_str_appendl(querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
- }
- break;
- case IS_LONG:
- smart_str_append_long(querystr, Z_LVAL_PP(val));
- break;
- case IS_DOUBLE:
- smart_str_appendl(querystr, buf, MIN(snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val)), sizeof(buf)-1));
- break;
- case IS_NULL:
- smart_str_appendl(querystr, "NULL", sizeof("NULL")-1);
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects scaler values. type=%d", Z_TYPE_PP(val));
- return -1;
- }
- smart_str_appendl(querystr, pad, pad_len);
- }
- querystr->len -= pad_len;
- return 0;
- }
- /* {{{ php_pgsql_update
- */
- PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *var_array, zval *ids_array, ulong opt, char **sql TSRMLS_DC)
- {
- zval *var_converted = NULL, *ids_converted = NULL;
- smart_str querystr = {0};
- int ret = FAILURE;
- assert(pg_link != NULL);
- assert(table != NULL);
- assert(Z_TYPE_P(var_array) == IS_ARRAY);
- assert(Z_TYPE_P(ids_array) == IS_ARRAY);
- assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)));
- if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0
- || zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
- return FAILURE;
- }
- if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) {
- MAKE_STD_ZVAL(var_converted);
- array_init(var_converted);
- if (php_pgsql_convert(pg_link, table, var_array, var_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) {
- goto cleanup;
- }
- var_array = var_converted;
- MAKE_STD_ZVAL(ids_converted);
- array_init(ids_converted);
- if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) {
- goto cleanup;
- }
- ids_array = ids_converted;
- }
- smart_str_appends(&querystr, "UPDATE ");
- build_tablename(&querystr, pg_link, table);
- smart_str_appends(&querystr, " SET ");
- if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt TSRMLS_CC))
- goto cleanup;
- smart_str_appends(&querystr, " WHERE ");
- if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC))
- goto cleanup;
- smart_str_appendc(&querystr, ';');
- smart_str_0(&querystr);
- if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) {
- ret = SUCCESS;
- } else if (opt & PGSQL_DML_STRING) {
- ret = SUCCESS;
- }
- cleanup:
- if (var_converted) {
- zval_dtor(var_converted);
- FREE_ZVAL(var_converted);
- }
- if (ids_converted) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) {
- *sql = querystr.c;
- }
- else {
- smart_str_free(&querystr);
- }
- return ret;
- }
- /* }}} */
- /* {{{ proto mixed pg_update(resource db, string table, array fields, array ids[, int options])
- Update table using values (field=>value) and ids (id=>value) */
- PHP_FUNCTION(pg_update)
- {
- zval *pgsql_link, *values, *ids;
- char *table, *sql = NULL;
- int table_len;
- ulong option = PGSQL_DML_EXEC;
- PGconn *pg_link;
- int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rsaa|l",
- &pgsql_link, &table, &table_len, &values, &ids, &option) == FAILURE) {
- return;
- }
- if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (php_pgsql_flush_query(pg_link TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection");
- }
- if (php_pgsql_update(pg_link, table, values, ids, option, &sql TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- if (option & PGSQL_DML_STRING) {
- RETURN_STRING(sql, 0);
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ php_pgsql_delete
- */
- PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids_array, ulong opt, char **sql TSRMLS_DC)
- {
- zval *ids_converted = NULL;
- smart_str querystr = {0};
- int ret = FAILURE;
- assert(pg_link != NULL);
- assert(table != NULL);
- assert(Z_TYPE_P(ids_array) == IS_ARRAY);
- assert(!(opt & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)));
- if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
- return FAILURE;
- }
- if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) {
- MAKE_STD_ZVAL(ids_converted);
- array_init(ids_converted);
- if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) {
- goto cleanup;
- }
- ids_array = ids_converted;
- }
- smart_str_appends(&querystr, "DELETE FROM ");
- build_tablename(&querystr, pg_link, table);
- smart_str_appends(&querystr, " WHERE ");
- if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC))
- goto cleanup;
- smart_str_appendc(&querystr, ';');
- smart_str_0(&querystr);
- if ((opt & PGSQL_DML_EXEC) && do_exec(&querystr, PGRES_COMMAND_OK, pg_link, opt TSRMLS_CC) == 0) {
- ret = SUCCESS;
- } else if (opt & PGSQL_DML_STRING) {
- ret = SUCCESS;
- }
- cleanup:
- if (ids_converted) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) {
- *sql = querystr.c;
- }
- else {
- smart_str_free(&querystr);
- }
- return ret;
- }
- /* }}} */
- /* {{{ proto mixed pg_delete(resource db, string table, array ids[, int options])
- Delete records has ids (id=>value) */
- PHP_FUNCTION(pg_delete)
- {
- zval *pgsql_link, *ids;
- char *table, *sql = NULL;
- int table_len;
- ulong option = PGSQL_DML_EXEC;
- PGconn *pg_link;
- int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l",
- &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) {
- return;
- }
- if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (php_pgsql_flush_query(pg_link TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection");
- }
- if (php_pgsql_delete(pg_link, table, ids, option, &sql TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- if (option & PGSQL_DML_STRING) {
- RETURN_STRING(sql, 0);
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ php_pgsql_result2array
- */
- PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC)
- {
- zval *row;
- char *field_name;
- size_t num_fields;
- int pg_numrows, pg_row;
- uint i;
- assert(Z_TYPE_P(ret_array) == IS_ARRAY);
- if ((pg_numrows = PQntuples(pg_result)) <= 0) {
- return FAILURE;
- }
- for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
- MAKE_STD_ZVAL(row);
- array_init(row);
- add_index_zval(ret_array, pg_row, row);
- for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
- if (PQgetisnull(pg_result, pg_row, i)) {
- field_name = PQfname(pg_result, i);
- add_assoc_null(row, field_name);
- } else {
- char *element = PQgetvalue(pg_result, pg_row, i);
- if (element) {
- char *data;
- size_t data_len;
- const size_t element_len = strlen(element);
- data = safe_estrndup(element, element_len);
- data_len = element_len;
- field_name = PQfname(pg_result, i);
- add_assoc_stringl(row, field_name, data, data_len, 0);
- }
- }
- }
- }
- return SUCCESS;
- }
- /* }}} */
- /* {{{ php_pgsql_select
- */
- PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, ulong opt, char **sql TSRMLS_DC)
- {
- zval *ids_converted = NULL;
- smart_str querystr = {0};
- int ret = FAILURE;
- PGresult *pg_result;
- assert(pg_link != NULL);
- assert(table != NULL);
- assert(Z_TYPE_P(ids_array) == IS_ARRAY);
- assert(Z_TYPE_P(ret_array) == IS_ARRAY);
- assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)));
- if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) {
- return FAILURE;
- }
- if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) {
- MAKE_STD_ZVAL(ids_converted);
- array_init(ids_converted);
- if (php_pgsql_convert(pg_link, table, ids_array, ids_converted, (opt & PGSQL_CONV_OPTS) TSRMLS_CC) == FAILURE) {
- goto cleanup;
- }
- ids_array = ids_converted;
- }
- smart_str_appends(&querystr, "SELECT * FROM ");
- build_tablename(&querystr, pg_link, table);
- smart_str_appends(&querystr, " WHERE ");
- if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt TSRMLS_CC))
- goto cleanup;
- smart_str_appendc(&querystr, ';');
- smart_str_0(&querystr);
- pg_result = PQexec(pg_link, querystr.c);
- if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
- ret = php_pgsql_result2array(pg_result, ret_array TSRMLS_CC);
- } else {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed to execute '%s'", querystr.c);
- }
- PQclear(pg_result);
- cleanup:
- if (ids_converted) {
- zval_dtor(ids_converted);
- FREE_ZVAL(ids_converted);
- }
- if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) {
- *sql = querystr.c;
- }
- else {
- smart_str_free(&querystr);
- }
- return ret;
- }
- /* }}} */
- /* {{{ proto mixed pg_select(resource db, string table, array ids[, int options])
- Select records that has ids (id=>value) */
- PHP_FUNCTION(pg_select)
- {
- zval *pgsql_link, *ids;
- char *table, *sql = NULL;
- int table_len;
- ulong option = PGSQL_DML_EXEC;
- PGconn *pg_link;
- int id = -1, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l",
- &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) {
- return;
- }
- if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified");
- RETURN_FALSE;
- }
- ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
- if (php_pgsql_flush_query(pg_link TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection");
- }
- array_init(return_value);
- if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql TSRMLS_CC) == FAILURE) {
- zval_dtor(return_value);
- RETURN_FALSE;
- }
- if (option & PGSQL_DML_STRING) {
- zval_dtor(return_value);
- RETURN_STRING(sql, 0);
- }
- return;
- }
- /* }}} */
- #endif
- /*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
|