多数据源中间件标准版1.0

otlv4.h 1.1MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901
  1. // =================================================================================
  2. // ORACLE, ODBC and DB2/CLI Template Library, Version 4.0.436,
  3. // Copyright (C) 1996-2019, Sergei Kuchin (skuchin@gmail.com)
  4. //
  5. // This library is free software. Permission to use, copy, modify,
  6. // and/or distribute this software for any purpose with or without fee
  7. // is hereby granted, provided that the above copyright notice and
  8. // this permission notice appear in all copies.
  9. //
  10. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. //
  18. // a.k.a. as Open BSD license
  19. // (http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/share/misc/license.template
  20. // =================================================================================
  21. #ifndef OTL_H
  22. #define OTL_H
  23. #if defined(OTL_INCLUDE_0)
  24. #include "otl_include_0.h"
  25. #endif
  26. #define OTL_VERSION_NUMBER (0x0401B4L)
  27. #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)
  28. #define OTL_STD_STRING_VIEW_CLASS OTL_THIRD_PARTY_STRING_VIEW_CLASS
  29. #endif
  30. #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)
  31. #define OTL_STD_UNICODE_STRING_VIEW_CLASS OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS
  32. #endif
  33. #if defined(OTL_CPP_14_ON)
  34. #define OTL_CPP_11_ON
  35. #endif
  36. #if defined(OTL_CPP_17_ON)
  37. #define OTL_CPP_11_ON
  38. #define OTL_CPP_14_ON
  39. #endif
  40. #if defined(_MSC_VER) && (_MSC_VER==1600)
  41. #define OTL_CPP_11_ON
  42. #endif
  43. #if defined(_MSC_VER) && (_MSC_VER==1700)
  44. #define OTL_CPP_11_ON
  45. #endif
  46. #if defined(_MSC_VER) && (_MSC_VER==1800)
  47. #define OTL_CPP_11_ON
  48. #endif
  49. #if defined(_MSC_VER) && (_MSC_VER==1900) && !defined(_MSVC_LANG)
  50. // VC++ 2015 before update 3
  51. #if !defined(OTL_CPP_11_ON)
  52. #define OTL_CPP_11_ON
  53. #endif
  54. #endif
  55. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__<=407) && (__GNUC__*100+__GNUC_MINOR__>=404)
  56. #pragma GCC diagnostic ignored "-Wold-style-cast"
  57. #endif
  58. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=701)
  59. #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
  60. #endif
  61. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
  62. #pragma clang diagnostic push
  63. #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
  64. #endif
  65. // auto-detection of "std" compiler switches
  66. #if defined(_MSC_VER)
  67. // >= VC++ 2015 Update 3, and /std:c++14
  68. #if defined(_MSVC_LANG) && (_MSVC_LANG==201402L)
  69. #if !defined(OTL_CPP_11_ON)
  70. #define OTL_CPP_11_ON
  71. #endif
  72. #if !defined(OTL_CPP_14_ON)
  73. #define OTL_CPP_14_ON
  74. #endif
  75. #endif
  76. // >= VC++ 2015 Update 3, and /std:c++latest
  77. #if defined(_MSVC_LANG) && (_MSVC_LANG>201402L)
  78. #if !defined(OTL_CPP_11_ON)
  79. #define OTL_CPP_11_ON
  80. #endif
  81. #if !defined(OTL_CPP_14_ON)
  82. #define OTL_CPP_14_ON
  83. #endif
  84. #if !defined(OTL_CPP_17_ON) && defined(_MSC_VER) && (_MSC_VER>=1910)
  85. #define OTL_CPP_17_ON
  86. #endif
  87. #if defined(_MSC_VER) && (_MSC_VER>=1910)
  88. #define OTL_COMPILER_HAS_STD_OPTIONAL
  89. #endif
  90. #endif
  91. #endif
  92. #if defined(__clang__) || defined(__GNUC__)
  93. // clang or g++
  94. #if defined(__cplusplus) && (__cplusplus==201103L)
  95. // std=c++11 is used
  96. #if !defined(OTL_CPP_11_ON)
  97. #define OTL_CPP_11_ON
  98. #endif
  99. #elif defined(__cplusplus) && (__cplusplus==201402L)
  100. // std=c++14 is used
  101. #if !defined(OTL_CPP_11_ON)
  102. #define OTL_CPP_11_ON
  103. #endif
  104. #if !defined(OTL_CPP_14_ON)
  105. #define OTL_CPP_14_ON
  106. #endif
  107. #elif defined(__cplusplus) && (__cplusplus>201402L)
  108. // std=c++17 / std=c++1z is used
  109. #if !defined(OTL_CPP_11_ON)
  110. #define OTL_CPP_11_ON
  111. #endif
  112. #if !defined(OTL_CPP_14_ON)
  113. #define OTL_CPP_14_ON
  114. #endif
  115. #if !defined(OTL_CPP_17_ON)
  116. #define OTL_CPP_17_ON
  117. #endif
  118. #endif
  119. #endif
  120. #if defined(OTL_CPP_11_ON) && defined(OTL_FUNC_THROW_SPEC_ON)
  121. #error OTL_CPP_11_ON and OTL_FUNC_THROW_SPEC_ON cannot be used together
  122. #endif
  123. #if defined(_MSC_VER) && (_MSC_VER >= 1600)
  124. #pragma warning(disable : 28251)
  125. #endif
  126. #if defined(_MSC_VER) && (_MSC_VER >= 1900)
  127. #pragma warning(disable : 6385)
  128. #pragma warning(disable : 6386)
  129. #endif
  130. // enable C++ standard features
  131. #if defined(OTL_CPP_11_ON)
  132. #if !defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  133. #define OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  134. #endif
  135. #if !defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  136. #define OTL_ANSI_CPP_11_NULLPTR_SUPPORT
  137. #endif
  138. #if !(defined(_MSC_VER) && (_MSC_VER<1800))
  139. #if !defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES)
  140. #define OTL_ANSI_CPP_11_VARIADIC_TEMPLATES
  141. #endif
  142. #if !defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  143. #define OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED
  144. #endif
  145. #if !defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  146. #define OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT
  147. #endif
  148. #endif
  149. #if !defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  150. #define OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT
  151. #endif
  152. #endif
  153. #if defined(OTL_CPP_14_ON)
  154. #if !defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  155. #define OTL_MAKE_UNIQUE_IS_SUPPORTED
  156. #endif
  157. #endif
  158. #define OTL_ANSI_CPP_11_NOEXCEPT
  159. #if !defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) && !defined(__cplusplus_cli)
  160. // define nullptr as 0 only if C++/CLI is not used
  161. #define nullptr 0
  162. #endif
  163. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  164. #if defined(_MSC_VER) && (_MSC_VER>=1700) && (_MSC_VER<=1800)
  165. #undef OTL_ANSI_CPP_11_NOEXCEPT
  166. #define OTL_ANSI_CPP_11_NOEXCEPT _NOEXCEPT
  167. #elif defined(_MSC_VER) && (_MSC_VER==1600)
  168. #undef OTL_ANSI_CPP_11_NOEXCEPT
  169. #define OTL_ANSI_CPP_11_NOEXCEPT
  170. #else
  171. #undef OTL_ANSI_CPP_11_NOEXCEPT
  172. #define OTL_ANSI_CPP_11_NOEXCEPT noexcept(true)
  173. #define OTL_ANSI_CPP_11_NOEXCEPT_FALSE noexcept(false)
  174. #endif
  175. #endif
  176. #if defined(OTL_CPP_17_ON) && \
  177. (defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=700) || \
  178. defined(_MSVC_LANG) && (_MSVC_LANG>=201703L) && defined(_MSC_VER) && (_MSC_VER>=1913) || \
  179. defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 600))
  180. // using c++17 binary left fold expressions: g++ 7.0 or higher,
  181. // VC++2017 update 6 or higher, clang++ 6.0 or higher
  182. #define OTL_ANSI_CPP_17_FOLD_EXPRESSIONS
  183. #define OTL_ANSI_CPP_17_CONSTEXPR_IF
  184. #endif
  185. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__==404) && \
  186. defined(__GXX_EXPERIMENTAL_CXX0X__)
  187. // automatically enable some C++0X features for GNU C++ 4.4 when it's
  188. // used with -std=c++0x
  189. #if !defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  190. #define OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  191. #endif
  192. #if !defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES)
  193. #define OTL_ANSI_CPP_11_VARIADIC_TEMPLATES
  194. #endif
  195. #if !defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  196. #define OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED
  197. #endif
  198. #if !defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED)
  199. #define OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED
  200. #endif
  201. #if !defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  202. #define OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED
  203. #endif
  204. #endif
  205. #if defined(OTL_CPP_14_ON)
  206. // atomically enable support for std::tuples and std::arrays under
  207. // OTL_CPP_14_ON
  208. #if !defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED)
  209. #define OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED
  210. #endif
  211. #if !defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  212. #define OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED
  213. #endif
  214. #endif
  215. #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED)
  216. #include <tuple>
  217. #include <utility>
  218. template<typename streamType, typename Tuple, const size_t N>
  219. struct otl_tuple_helper{
  220. static void write(streamType& s, const Tuple& t){
  221. otl_tuple_helper<streamType,Tuple,N-1>::write(s,t);
  222. s<<std::get<N-1>(t);
  223. }
  224. static void read(streamType& s, Tuple& t){
  225. otl_tuple_helper<streamType,Tuple,N-1>::read(s,t);
  226. s>>std::get<N-1>(t);
  227. }
  228. };
  229. template<typename streamType, typename Tuple>
  230. struct otl_tuple_helper<streamType,Tuple,1>{
  231. static void write(streamType& s, const Tuple& t) {
  232. s<<std::get<0>(t);
  233. }
  234. static void read(streamType& s, Tuple& t) {
  235. s>>std::get<0>(t);
  236. }
  237. };
  238. #endif
  239. // C++11/14/17 attributes
  240. #if defined(OTL_CPP_11_ON)
  241. #if defined(_MSC_VER) && (_MSC_VER>=1900)
  242. #define OTL_NORETURN [[noreturn]]
  243. #elif defined(_MSC_VER) && (_MSC_VER<1900)
  244. #define OTL_NORETURN
  245. #else
  246. #define OTL_NORETURN [[noreturn]]
  247. #endif
  248. #else
  249. #define OTL_NORETURN
  250. #endif
  251. #if defined(OTL_CPP_14_ON)
  252. #define OTL_DEPRECATED [[deprecated]]
  253. #define OTL_DEPRECATED_WITH_ARG(x) [[deprecated(x)]]
  254. #else
  255. #define OTL_DEPRECATED
  256. #define OTL_DEPRECATED_WITH_ARG(x)
  257. #endif
  258. #if defined(OTL_CPP_17_ON)
  259. #define OTL_NODISCARD [[nodiscard]]
  260. #define OTL_FALLTHROUGH [[fallthrough]];
  261. #define OTL_MAYBE_UNUSED [[maybe_unused]]
  262. #else
  263. #define OTL_NODISCARD
  264. #define OTL_FALLTHROUGH
  265. #define OTL_MAYBE_UNUSED
  266. #endif
  267. #if defined(_MSC_VER) && (_MSC_VER >= 1400)
  268. #pragma warning(disable : 4351)
  269. #pragma warning(disable : 4290)
  270. #define OTL_STRCAT_S(dest, dest_sz, src) strcat_s(dest, dest_sz, src)
  271. #define OTL_STRCPY_S(dest, dest_sz, src) strcpy_s(dest, dest_sz, src)
  272. #define OTL_STRNCPY_S(dest, dest_sz, src, count) strncpy_s(dest, dest_sz, src, count)
  273. #define OTL_SPRINTF_S sprintf_s
  274. #else
  275. #ifndef OTL_STRCAT_S
  276. #define OTL_STRCAT_S(dest, dest_sz, src) ((void)(dest_sz),strcat(dest, src))
  277. #endif // OTL_STRCAT_S
  278. #ifndef OTL_STRCPY_S
  279. #define OTL_STRCPY_S(dest, dest_sz, src) ((void)(dest_sz),strcpy(dest, src))
  280. #endif // OTL_STRCPY_S
  281. #ifndef OTL_STRNCPY_S
  282. #define OTL_STRNCPY_S(dest, dest_sz, src, count) \
  283. ((void)(dest_sz),strncpy(dest, src, count))
  284. #endif // OTL_STRNCPY_S
  285. #ifndef OTL_SPRINTF_S
  286. #include <stdarg.h>
  287. #include <stdio.h>
  288. #if defined(__GNUC__)
  289. #define OTL_SPRINTF_S_ATTRIBUTE __attribute__ ((format (printf, 3, 4)))
  290. #else
  291. #define OTL_SPRINTF_S_ATTRIBUTE
  292. #endif
  293. int otl_sprintf_s(char* dest, size_t /* dest_sz */, const char* fmt, ...) OTL_SPRINTF_S_ATTRIBUTE;
  294. inline int otl_sprintf_s(char* dest, size_t /* dest_sz */, const char* fmt, ...){
  295. va_list vl;
  296. va_start(vl, fmt);
  297. int res = vsprintf(dest, fmt, vl);
  298. va_end(vl);
  299. return res;
  300. }
  301. #define OTL_SPRINTF_S otl_sprintf_s
  302. #endif // OTL_SPRINTF_S
  303. #endif
  304. #include <string.h>
  305. #include <ctype.h>
  306. #include <stdlib.h>
  307. #include <stdio.h>
  308. //======================= CONFIGURATION #DEFINEs ===========================
  309. // Uncomment the following line in order to include the OTL for ODBC:
  310. //#define OTL_ODBC
  311. // Uncomment the following line in order to include the OTL for
  312. // MySQL/MyODBC for MyODBC 2.5 (pretty old). Otherwise, use OTL_ODBC
  313. //#define OTL_ODBC_MYSQL
  314. // Uncomment the following line in order to include the OTL for DB2 CLI:
  315. //#define OTL_DB2_CLI
  316. // Uncomment the following line in order to include the OTL for
  317. // Oracle 8:
  318. //#define OTL_ORA8
  319. // Uncomment the following line in order to include the OTL for
  320. // Oracle 8i:
  321. //#define OTL_ORA8I
  322. // Uncomment the following line in order to include the OTL for
  323. // Oracle 9i:
  324. //#define OTL_ORA9I
  325. // Uncomment the following line in order to include the OTL for
  326. // Oracle 10g Release 1:
  327. //#define OTL_ORA10G
  328. // Uncomment the following line in order to include the OTL for
  329. // Oracle 10g Release 2:
  330. //#define OTL_ORA10G_R2
  331. // Uncomment the following line in order to include the OTL for
  332. // Oracle 11g Release 1
  333. //#define OTL_ORA11G
  334. // The macro definitions may be also turned on via C++ compiler command line
  335. // option, e.g.: -DOTL_ODBC, DOTL_ORA8, -DOTL_ORA8I,
  336. // -DOTL_ODBC_UNIX
  337. // -DOTL_ODBC_MYSQL, -DOTL_DB2_CLI
  338. // this #define is always defined
  339. #if !defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  340. #define OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON
  341. #endif
  342. #if !defined(OTL_STLPORT)
  343. #include <iostream>
  344. #include <iomanip>
  345. #define OTL_SETFILL std::setfill('0')
  346. #define OTL_SETW(s) std::setw(s.frac_precision)
  347. #else
  348. #endif
  349. #if !defined(OTL_TRACE_LEVEL)
  350. #define OTL_TRACE_FORMAT_TZ_DATETIME(s)
  351. #define OTL_TRACE_FORMAT_DATETIME(s)
  352. #else
  353. #if !defined(OTL_TRACE_FORMAT_DATETIME)
  354. #if !defined(OTL_LEGACY_TRACE_DATETIME_FORMAT_ON)
  355. #define OTL_TRACE_FORMAT_TZ_DATETIME(s) \
  356. s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \
  357. << ":" << s.second << "." \
  358. << OTL_SETFILL \
  359. << OTL_SETW(s) \
  360. << s.fraction << " " << s.tz_hour << ":" \
  361. << s.tz_minute
  362. #define OTL_TRACE_FORMAT_DATETIME(s) \
  363. s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \
  364. << ":" << s.second << "." \
  365. << OTL_SETFILL \
  366. << OTL_SETW(s) \
  367. << s.fraction
  368. #else
  369. #define OTL_TRACE_FORMAT_TZ_DATETIME(s) \
  370. s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \
  371. << ":" << s.second << "." \
  372. << s.fraction << " " << s.tz_hour << ":" \
  373. << s.tz_minute
  374. #define OTL_TRACE_FORMAT_DATETIME(s) \
  375. s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \
  376. << ":" << s.second << "." \
  377. << s.fraction
  378. #endif
  379. #endif
  380. #endif
  381. #if !defined(OTL_THROW)
  382. #define OTL_THROW(x) throw x
  383. #endif
  384. #if defined(_MSC_VER) && (_MSC_VER >= 1900) && defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  385. // vc++ 14 or higher
  386. #define OTL_THROWS_OTL_EXCEPTION noexcept(false)
  387. #define OTL_THROWS_OTL_EXCEPTION2 noexcept(false)
  388. #define OTL_THROWS_OTL_EXCEPTION3 noexcept(false)
  389. #define OTL_THROWS_OTL_EXCEPTION4 noexcept(false)
  390. #define OTL_NO_THROW noexcept(true)
  391. #endif
  392. #if defined(OTL_ORA11G)
  393. #if !defined(OTL_ORA10G_R2)
  394. #define OTL_ORA10G_R2
  395. #endif
  396. #if defined(OTL_UNICODE)
  397. #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES
  398. #endif
  399. #endif
  400. #if defined(OTL_ORA18C)
  401. #if !defined(OTL_ORA12C_R2)
  402. #define OTL_ORA12C_R2
  403. #endif
  404. #endif
  405. #if defined(OTL_ORA12C_R2)
  406. #if !defined(OTL_ORA12C)
  407. #define OTL_ORA12C
  408. #endif
  409. #endif
  410. #if defined(OTL_ORA12C)
  411. #if !defined(OTL_ORA11G_R2)
  412. #define OTL_ORA11G_R2
  413. #endif
  414. #if defined(OTL_UNICODE)
  415. #if !defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES)
  416. #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES
  417. #endif
  418. #endif
  419. #endif
  420. #if defined(OTL_ORA11G_R2)
  421. #if !defined(OTL_ORA10G_R2)
  422. #define OTL_ORA10G_R2
  423. #endif
  424. #if defined(OTL_UNICODE) && !defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES)
  425. #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES
  426. #endif
  427. #endif
  428. #if defined(OTL_STREAM_LEGACY_BUFFER_SIZE_TYPE)
  429. typedef short int otl_stream_buffer_size_type;
  430. #else
  431. typedef int otl_stream_buffer_size_type;
  432. #endif
  433. #if defined(OTL_ODBC_MULTI_MODE)
  434. #define OTL_ODBC
  435. #define OTL_ODBC_SQL_EXTENDED_FETCH_ON
  436. #endif
  437. #if defined(OTL_ODBC_MSSQL_2005)
  438. #define OTL_ODBC
  439. #endif
  440. #if defined(OTL_ODBC_MSSQL_2008)
  441. #define OTL_ODBC
  442. #define OTL_ODBC_MSSQL_2005
  443. #endif
  444. #if defined(OTL_IODBC_BSD)
  445. #define OTL_ODBC
  446. #define OTL_ODBC_UNIX
  447. #endif
  448. #if defined(OTL_ODBC_TIMESTEN_WIN)
  449. #define OTL_ODBC_TIMESTEN
  450. #define OTL_ODBC
  451. #define OTL_ODBC_SQL_EXTENDED_FETCH_ON
  452. #define ODBCVER 0x0250
  453. #include <timesten.h>
  454. #endif
  455. #if defined(OTL_ODBC_TIMESTEN_UNIX)
  456. #define OTL_ODBC_TIMESTEN
  457. #define OTL_ODBC
  458. #define OTL_ODBC_UNIX
  459. #define OTL_ODBC_SQL_EXTENDED_FETCH_ON
  460. #include <timesten.h>
  461. #endif
  462. #if defined(OTL_ODBC_ENTERPRISEDB)
  463. #define OTL_ODBC_POSTGRESQL
  464. #endif
  465. #if defined(OTL_ODBC_POSTGRESQL)
  466. #define OTL_ODBC
  467. #endif
  468. // Comment out this #define when using pre-ANSI C++ compiler
  469. #if !defined(OTL_ODBC_zOS) && !defined(OTL_ANSI_CPP)
  470. #define OTL_ANSI_CPP
  471. #endif
  472. #if defined(OTL_ODBC_zOS)
  473. #define OTL_ODBC_UNIX
  474. #define OTL_ODBC_SQL_EXTENDED_FETCH_ON
  475. #endif
  476. #if defined(OTL_ORA8I)
  477. #define OTL_ORA8
  478. #define OTL_ORA8_8I_REFCUR
  479. #define OTL_ORA8_8I_DESC_COLUMN_SCALE
  480. #endif
  481. #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)
  482. #define OTL_ORA9I
  483. #define OTL_ORA_NATIVE_TYPES
  484. #if defined(OTL_UNICODE)
  485. #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES
  486. #endif
  487. #endif
  488. #if defined(OTL_ORA9I)
  489. #define OTL_ORA8
  490. #define OTL_ORA8_8I_REFCUR
  491. #define OTL_ORA8_8I_DESC_COLUMN_SCALE
  492. #endif
  493. #if defined(OTL_ODBC_MYSQL)
  494. #define OTL_ODBC
  495. #endif
  496. #if defined(OTL_ODBC_XTG_IBASE6)
  497. #define OTL_ODBC
  498. #endif
  499. #define OTL_VALUE_TEMPLATE
  500. //#define OTL_ODBC_SQL_EXTENDED_FETCH_ON
  501. #if defined(OTL_ODBC_UNIX) && !defined(OTL_ODBC)
  502. #define OTL_ODBC
  503. #endif
  504. #if !defined(OTL_ORA11G_R2) && defined(OTL_ORA8) && defined(OTL_UBIGINT)
  505. #error OTL_UBIGINT is only supported for OTL_ORA11G_R2 or higher
  506. #endif
  507. #if defined(OTL_UBIGINT) && defined(OTL_BIGINT_TO_STR) && \
  508. defined(OTL_STR_TO_BIGINT)
  509. #error OTL_UBIGINT is not supported when OTL_BIGINT_TO_STR / \
  510. OTL_STR_TO_BIGINT are defined
  511. #endif
  512. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  513. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \
  514. !defined(OTL_NUMERIC_TYPE_1) && !defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  515. !defined(OTL_NUMERIC_TYPE_1_TO_STR) && !defined(OTL_NUMERIC_TYPE_1_ID)
  516. #error OTL_NUMERIC_TYPE_2 macros should be used after OTL_NUMERIC_TYPE_1 macros \
  517. are already defined
  518. #endif
  519. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  520. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \
  521. ((!defined(OTL_NUMERIC_TYPE_1) && !defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  522. !defined(OTL_NUMERIC_TYPE_1_TO_STR) && \
  523. !defined(OTL_NUMERIC_TYPE_1_ID)) || \
  524. (!defined(OTL_NUMERIC_TYPE_2) && !defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  525. !defined(OTL_NUMERIC_TYPE_2_TO_STR) && !defined(OTL_NUMERIC_TYPE_2_ID)))
  526. #error OTL_NUMERIC_TYPE_3 macros should be used after OTL_NUMERIC_TYPE_1 and \
  527. OTL_NUMERIC_TYPE_2 macros are already defined
  528. #endif
  529. #if defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON)
  530. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  531. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  532. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  533. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  534. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  535. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  536. #define OTL_CHECK_BIND_VARS \
  537. if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \
  538. strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \
  539. strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \
  540. strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \
  541. strcmp(type_arr, "TIMESTAMP") == 0 || \
  542. strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \
  543. strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \
  544. strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \
  545. strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \
  546. strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \
  547. strcmp(type_arr, "VARCHAR_LONG") == 0 || \
  548. strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \
  549. strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \
  550. strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \
  551. strcmp(type_arr, "REFCUR") == 0 || \
  552. strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0 || \
  553. strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0 || \
  554. strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) \
  555. ; \
  556. else \
  557. return 0;
  558. #else
  559. #define OTL_CHECK_BIND_VARS \
  560. if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \
  561. strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \
  562. strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \
  563. strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \
  564. strcmp(type_arr, "TIMESTAMP") == 0 || \
  565. strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \
  566. strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \
  567. strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \
  568. strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \
  569. strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \
  570. strcmp(type_arr, "VARCHAR_LONG") == 0 || \
  571. strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \
  572. strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \
  573. strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \
  574. strcmp(type_arr, "REFCUR") == 0 || \
  575. strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0 || \
  576. strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) \
  577. ; \
  578. else \
  579. return 0;
  580. #endif
  581. #else
  582. #define OTL_CHECK_BIND_VARS \
  583. if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \
  584. strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \
  585. strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \
  586. strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \
  587. strcmp(type_arr, "TIMESTAMP") == 0 || \
  588. strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \
  589. strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \
  590. strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \
  591. strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \
  592. strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \
  593. strcmp(type_arr, "VARCHAR_LONG") == 0 || \
  594. strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \
  595. strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \
  596. strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \
  597. strcmp(type_arr, "REFCUR") == 0 || \
  598. strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) \
  599. ; \
  600. else \
  601. return 0;
  602. #endif
  603. #else
  604. #define OTL_CHECK_BIND_VARS \
  605. if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \
  606. strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \
  607. strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \
  608. strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \
  609. strcmp(type_arr, "TIMESTAMP") == 0 || \
  610. strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \
  611. strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \
  612. strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \
  613. strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \
  614. strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \
  615. strcmp(type_arr, "VARCHAR_LONG") == 0 || \
  616. strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \
  617. strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \
  618. strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \
  619. strcmp(type_arr, "REFCUR") == 0) \
  620. ; \
  621. else \
  622. return 0;
  623. #endif
  624. #else
  625. #define OTL_CHECK_BIND_VARS
  626. #endif
  627. // ------------------- Namespace generation ------------------------
  628. #if defined(OTL_EXPLICIT_NAMESPACES)
  629. #if defined(OTL_DB2_CLI)
  630. #define OTL_ODBC_NAMESPACE_BEGIN namespace db2 {
  631. #define OTL_ODBC_NAMESPACE_PREFIX db2::
  632. #define OTL_ODBC_NAMESPACE_END }
  633. #else
  634. #define OTL_ODBC_NAMESPACE_BEGIN namespace odbc {
  635. #define OTL_ODBC_NAMESPACE_PREFIX odbc::
  636. #define OTL_ODBC_NAMESPACE_END }
  637. #endif
  638. #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle {
  639. #define OTL_ORA8_NAMESPACE_PREFIX oracle::
  640. #define OTL_ORA8_NAMESPACE_END }
  641. #else
  642. // Only one OTL is being intantiated
  643. #if defined(OTL_ODBC) && !defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \
  644. !defined(OTL_ODBC) && defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \
  645. !defined(OTL_ODBC) && !defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \
  646. !defined(OTL_ODBC) && !defined(OTL_ORA8) && defined(OTL_DB2_CLI)
  647. #define OTL_ODBC_NAMESPACE_BEGIN
  648. #define OTL_ODBC_NAMESPACE_PREFIX
  649. #define OTL_ODBC_NAMESPACE_END
  650. #define OTL_ORA8_NAMESPACE_BEGIN
  651. #define OTL_ORA8_NAMESPACE_PREFIX
  652. #define OTL_ORA8_NAMESPACE_END
  653. #endif
  654. // ================ Combinations of two OTLs =========================
  655. #if defined(OTL_ODBC) && defined(OTL_ORA8) && !defined(OTL_DB2_CLI)
  656. #define OTL_ODBC_NAMESPACE_BEGIN namespace odbc {
  657. #define OTL_ODBC_NAMESPACE_PREFIX odbc::
  658. #define OTL_ODBC_NAMESPACE_END }
  659. #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle {
  660. #define OTL_ORA8_NAMESPACE_PREFIX oracle::
  661. #define OTL_ORA8_NAMESPACE_END }
  662. #endif
  663. #if !defined(OTL_ODBC) && defined(OTL_ORA8) && defined(OTL_DB2_CLI)
  664. #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle {
  665. #define OTL_ORA8_NAMESPACE_PREFIX oracle::
  666. #define OTL_ORA8_NAMESPACE_END }
  667. #define OTL_ODBC_NAMESPACE_BEGIN namespace db2 {
  668. #define OTL_ODBC_NAMESPACE_PREFIX db2::
  669. #define OTL_ODBC_NAMESPACE_END }
  670. #endif
  671. #endif
  672. // -------------------- End of namespace generation -------------------
  673. // --------------------- Invalid combinations --------------------------
  674. #if defined(OTL_ORA_MAP_BIGINT_TO_LONG) && defined(OTL_BIGINT_TO_STR) && \
  675. defined(OTL_STR_TO_BIGINT)
  676. #error OTL_ORA_MAP_BIGINT_TO_LONG cannot be used when \
  677. OTL_BIGINT_TO_STR and OTL_STR_TO_BIGINT are defined
  678. #endif
  679. #if defined(OTL_STL) && defined(OTL_UNICODE_STRING_TYPE)
  680. #error Invalid combination: OTL_STL and OTL_UNICODE_STRING_TYPE
  681. #endif
  682. #if defined(OTL_ORA_UTF8) && !defined(OTL_ORA10G) && \
  683. !defined(OTL_ORA_10G_R2) && !defined(OTL_ORA9I)
  684. #error Invalid combination: OTL_ORA_UTF8 can only be used with OTL_ORA9I or higher
  685. #endif
  686. #if defined(OTL_ORA_UTF8) && defined(OTL_UNICODE)
  687. #error Invalid combination: OTL_ORA_UTF8 and OTL_UNICODE are mutually exclusive
  688. #endif
  689. #if defined(OTL_ODBC) && defined(OTL_DB2_CLI)
  690. #error Invalid combination: OTL_ODBC && OTL_DB2_CLI together
  691. #endif
  692. #if defined(OTL_ORA_OCI_ENV_CREATE) && \
  693. (!defined(OTL_ORA8I) && !defined(OTL_ORA9I) && !defined(OTL_ORA10G) && \
  694. !defined(OTL_ORA10G_R2))
  695. #error OTL_ORA_OCI_ENV_CREATE can be only defined when OTL_ORA8I, OTL_ORA9I, OTL_ORA10G, OTL_ORA10G_R2, or OTL_ORA11G, or OTL_ORA11G_R2, or OTL_ORA12C is defined
  696. #endif
  697. // --------------------------------------------------------------------
  698. #if defined(OTL_TRACE_LEVEL)
  699. #if !defined(OTL_TRACE_LINE_PREFIX)
  700. #define OTL_TRACE_LINE_PREFIX "OTL TRACE ==> "
  701. #endif
  702. #if defined(OTL_UNICODE_CHAR_TYPE) && !defined(OTL_UNICODE)
  703. #error OTL_UNICODE needs to be defined if OTL_UNICODE_CHAR_TYPE is defined
  704. #endif
  705. #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE_CHAR_TYPE)
  706. #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_STRING_TYPE is defined
  707. #endif
  708. #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE_CHAR_TYPE)
  709. #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_STRING_TYPE is defined
  710. #endif
  711. #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE)
  712. #error OTL_UNICODE needs to be defined if OTL_UNICODE_STRING_TYPE is defined
  713. #endif
  714. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) && !defined(OTL_UNICODE_CHAR_TYPE)
  715. #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_EXCEPTION_AND_RLOGON is defined
  716. #endif
  717. #if !defined(OTL_TRACE_LINE_SUFFIX)
  718. #if defined(OTL_UNICODE)
  719. #define OTL_TRACE_LINE_SUFFIX L"\n"
  720. #else
  721. #define OTL_TRACE_LINE_SUFFIX "\n"
  722. #endif
  723. #endif
  724. #if !defined(OTL_TRACE_STREAM_OPEN)
  725. #define OTL_TRACE_STREAM_OPEN \
  726. if (OTL_TRACE_LEVEL & 0x4) { \
  727. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  728. OTL_TRACE_STREAM << "otl_stream(this="; \
  729. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  730. OTL_TRACE_STREAM << ")::open(buffer_size="; \
  731. OTL_TRACE_STREAM << arr_size; \
  732. OTL_TRACE_STREAM << ", sqlstm="; \
  733. OTL_TRACE_STREAM << sqlstm; \
  734. OTL_TRACE_STREAM << ", connect="; \
  735. OTL_TRACE_STREAM << OTL_RCAST(void *, &db); \
  736. OTL_TRACE_STREAM << ", implicit_select="; \
  737. OTL_TRACE_STREAM << implicit_select; \
  738. if (sqlstm_label) { \
  739. OTL_TRACE_STREAM << ", label="; \
  740. OTL_TRACE_STREAM << sqlstm_label; \
  741. } \
  742. OTL_TRACE_STREAM << ");"; \
  743. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  744. }
  745. #endif
  746. #if !defined(OTL_TRACE_STREAM_OPEN2)
  747. #define OTL_TRACE_STREAM_OPEN2 \
  748. if (OTL_TRACE_LEVEL & 0x4) { \
  749. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  750. OTL_TRACE_STREAM << "otl_stream(this="; \
  751. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  752. OTL_TRACE_STREAM << ")::open(buffer_size="; \
  753. OTL_TRACE_STREAM << arr_size; \
  754. OTL_TRACE_STREAM << ", sqlstm="; \
  755. OTL_TRACE_STREAM << sqlstm; \
  756. OTL_TRACE_STREAM << ", connect="; \
  757. OTL_TRACE_STREAM << OTL_RCAST(void *, &db); \
  758. if (ref_cur_placeholder) { \
  759. OTL_TRACE_STREAM << ", ref_cur_placeholder="; \
  760. OTL_TRACE_STREAM << ref_cur_placeholder; \
  761. } \
  762. if (sqlstm_label) { \
  763. OTL_TRACE_STREAM << ", label="; \
  764. OTL_TRACE_STREAM << sqlstm_label; \
  765. } \
  766. OTL_TRACE_STREAM << ");"; \
  767. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  768. }
  769. #endif
  770. #if !defined(OTL_TRACE_DIRECT_EXEC)
  771. #define OTL_TRACE_DIRECT_EXEC \
  772. if (OTL_TRACE_LEVEL & 0x2) { \
  773. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  774. OTL_TRACE_STREAM << "otl_cursor::direct_exec(connect="; \
  775. OTL_TRACE_STREAM << OTL_RCAST(void *, &connect); \
  776. OTL_TRACE_STREAM << ",sqlstm=\""; \
  777. OTL_TRACE_STREAM << sqlstm; \
  778. OTL_TRACE_STREAM << "\",exception_enabled="; \
  779. OTL_TRACE_STREAM << exception_enabled; \
  780. OTL_TRACE_STREAM << ");"; \
  781. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  782. }
  783. #endif
  784. #if !defined(OTL_TRACE_SYNTAX_CHECK)
  785. #define OTL_TRACE_SYNTAX_CHECK \
  786. if (OTL_TRACE_LEVEL & 0x2) { \
  787. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  788. OTL_TRACE_STREAM << "otl_cursor::syntax_check(connect="; \
  789. OTL_TRACE_STREAM << OTL_RCAST(void *, &connect); \
  790. OTL_TRACE_STREAM << ",sqlstm=\""; \
  791. OTL_TRACE_STREAM << sqlstm; \
  792. OTL_TRACE_STREAM << "\""; \
  793. OTL_TRACE_STREAM << ");"; \
  794. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  795. }
  796. #endif
  797. #if !defined(OTL_TRACE_FUNC)
  798. #define OTL_TRACE_FUNC(level, class_name, func_name, args) \
  799. if (OTL_TRACE_LEVEL & level) { \
  800. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  801. OTL_TRACE_STREAM << class_name; \
  802. OTL_TRACE_STREAM << "(this="; \
  803. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  804. OTL_TRACE_STREAM << ")::" func_name "("; \
  805. OTL_TRACE_STREAM << args; \
  806. OTL_TRACE_STREAM << ");"; \
  807. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  808. }
  809. #endif
  810. #if !defined(OTL_TRACE_EXCEPTION)
  811. #define OTL_TRACE_EXCEPTION(code, msg, stm_text, var_info) \
  812. if (OTL_TRACE_LEVEL & 0x20) { \
  813. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  814. OTL_TRACE_STREAM << "otl_exception, code="; \
  815. OTL_TRACE_STREAM << code; \
  816. OTL_TRACE_STREAM << ", msg="; \
  817. char *c = OTL_RCAST(char *, msg); \
  818. while (*c && *c != '\n') { \
  819. OTL_TRACE_STREAM << *c; \
  820. ++c; \
  821. } \
  822. OTL_TRACE_STREAM << ", stm_text="; \
  823. OTL_TRACE_STREAM << stm_text; \
  824. OTL_TRACE_STREAM << ", var_info="; \
  825. OTL_TRACE_STREAM << var_info; \
  826. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  827. }
  828. #endif
  829. #if !defined(OTL_TRACE_EXCEPTION2)
  830. #define OTL_TRACE_EXCEPTION2(code, msg, stm_text, var_info, input_str, \
  831. input_str_size) \
  832. if (OTL_TRACE_LEVEL & 0x20) { \
  833. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  834. OTL_TRACE_STREAM << "otl_exception, code="; \
  835. OTL_TRACE_STREAM << code; \
  836. OTL_TRACE_STREAM << ", msg="; \
  837. char *c = OTL_RCAST(char *, msg); \
  838. while (*c && *c != '\n') { \
  839. OTL_TRACE_STREAM << *c; \
  840. ++c; \
  841. } \
  842. OTL_TRACE_STREAM << ", stm_text="; \
  843. OTL_TRACE_STREAM << stm_text; \
  844. OTL_TRACE_STREAM << ", var_info="; \
  845. OTL_TRACE_STREAM << var_info; \
  846. OTL_TRACE_STREAM << ", input string=\""; \
  847. const char *str = OTL_RCAST(const char *, input_str); \
  848. int i = 0; \
  849. while (i < input_str_size) \
  850. OTL_TRACE_STREAM << str[i++]; \
  851. OTL_TRACE_STREAM << "\"" << OTL_TRACE_LINE_SUFFIX; \
  852. }
  853. #endif
  854. #if !defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ORA8) && defined(OTL_ORA8)
  855. #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \
  856. passwd, auto_commit) \
  857. if (OTL_TRACE_LEVEL & level) { \
  858. char temp_connect_str[2048]; \
  859. OTL_STRCPY_S(temp_connect_str, sizeof(temp_connect_str), userid); \
  860. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "/"); \
  861. size_t sz = strlen(passwd); \
  862. for (size_t i = 0; i < sz; ++i) \
  863. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "*"); \
  864. size_t tns_sz = strlen(tnsname); \
  865. if (tns_sz > 0) { \
  866. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "@"); \
  867. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), tnsname); \
  868. } \
  869. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  870. OTL_TRACE_STREAM << class_name << "(this="; \
  871. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  872. OTL_TRACE_STREAM << ")::" func_name "("; \
  873. OTL_TRACE_STREAM << "connect_str=\""; \
  874. OTL_TRACE_STREAM << temp_connect_str; \
  875. OTL_TRACE_STREAM << "\", auto_commit="; \
  876. OTL_TRACE_STREAM << auto_commit << ");"; \
  877. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  878. }
  879. #elif defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ORA8) && defined(OTL_ORA8)
  880. #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \
  881. passwd, auto_commit) \
  882. { \
  883. char temp_connect_str[2048]; \
  884. OTL_STRCPY_S(temp_connect_str, sizeof(temp_connect_str), userid); \
  885. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "/"); \
  886. size_t sz = strlen(passwd); \
  887. for (size_t i = 0; i < sz; ++i) \
  888. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "*"); \
  889. size_t tns_sz = strlen(tnsname); \
  890. if (tns_sz > 0) { \
  891. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), "@"); \
  892. OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str), tnsname); \
  893. } \
  894. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  895. OTL_TRACE_STREAM << class_name << "(this="; \
  896. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  897. OTL_TRACE_STREAM << ")::" func_name "("; \
  898. OTL_TRACE_STREAM << "connect_str=\""; \
  899. OTL_TRACE_STREAM << temp_connect_str; \
  900. OTL_TRACE_STREAM << "\", auto_commit="; \
  901. OTL_TRACE_STREAM << auto_commit << ");"; \
  902. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  903. }
  904. #endif
  905. #if !defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ODBC) \
  906. && (defined(OTL_ODBC) || defined(OTL_DB2_CLI))
  907. #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \
  908. passwd, auto_commit) \
  909. if (OTL_TRACE_LEVEL & level) { \
  910. char temp_connect_str2[2048]; \
  911. OTL_STRCPY_S(temp_connect_str2, sizeof(temp_connect_str2), userid); \
  912. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "/"); \
  913. size_t sz = strlen(passwd); \
  914. for (size_t i = 0; i < sz; ++i) \
  915. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "*"); \
  916. size_t tns_sz = strlen(tnsname); \
  917. if (tns_sz > 0) { \
  918. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "@"); \
  919. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), tnsname); \
  920. } \
  921. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  922. OTL_TRACE_STREAM << class_name; \
  923. OTL_TRACE_STREAM << "(this="; \
  924. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  925. OTL_TRACE_STREAM << ")::" func_name "("; \
  926. OTL_TRACE_STREAM << "connect_str=\""; \
  927. OTL_TRACE_STREAM << temp_connect_str2; \
  928. OTL_TRACE_STREAM << "\", auto_commit="; \
  929. OTL_TRACE_STREAM << auto_commit; \
  930. OTL_TRACE_STREAM << ");"; \
  931. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  932. }
  933. #elif defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ODBC) \
  934. && (defined(OTL_ODBC) || defined(OTL_DB2_CLI))
  935. #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \
  936. passwd, auto_commit) \
  937. { \
  938. char temp_connect_str2[2048]; \
  939. OTL_STRCPY_S(temp_connect_str2, sizeof(temp_connect_str2), userid); \
  940. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "/"); \
  941. size_t sz = strlen(passwd); \
  942. for (size_t i = 0; i < sz; ++i) \
  943. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "*"); \
  944. size_t tns_sz = strlen(tnsname); \
  945. if (tns_sz > 0) { \
  946. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), "@"); \
  947. OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2), tnsname); \
  948. } \
  949. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  950. OTL_TRACE_STREAM << class_name; \
  951. OTL_TRACE_STREAM << "(this="; \
  952. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  953. OTL_TRACE_STREAM << ")::" func_name "("; \
  954. OTL_TRACE_STREAM << "connect_str=\""; \
  955. OTL_TRACE_STREAM << temp_connect_str2; \
  956. OTL_TRACE_STREAM << "\", auto_commit="; \
  957. OTL_TRACE_STREAM << auto_commit; \
  958. OTL_TRACE_STREAM << ");"; \
  959. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  960. }
  961. #endif
  962. #if !defined(OTL_TRACE_RLOGON_ODBC_W) && \
  963. (defined(OTL_ODBC) || defined(OTL_DB2_CLI))
  964. #define OTL_TRACE_RLOGON_ODBC_W(level, class_name, func_name, tnsname, userid, \
  965. passwd, auto_commit) \
  966. if (OTL_TRACE_LEVEL & level) { \
  967. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  968. OTL_TRACE_STREAM << class_name; \
  969. OTL_TRACE_STREAM << L"(this="; \
  970. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  971. OTL_TRACE_STREAM << L")::" func_name L"("; \
  972. OTL_TRACE_STREAM << L"connect_str=\""; \
  973. OTL_TRACE_STREAM << userid << L"/***@" << tnsname; \
  974. OTL_TRACE_STREAM << L"\", auto_commit="; \
  975. OTL_TRACE_STREAM << auto_commit; \
  976. OTL_TRACE_STREAM << L");"; \
  977. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  978. }
  979. #endif
  980. #if !defined(OTL_TRACE_FIRST_FETCH)
  981. #if defined(OTL_TRACE_ENABLE_STREAM_LABELS)
  982. #define OTL_TRACE_FIRST_FETCH \
  983. if (OTL_TRACE_LEVEL & 0x8) { \
  984. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  985. OTL_TRACE_STREAM << "otl_stream(this="; \
  986. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  987. OTL_TRACE_STREAM << "), "; \
  988. OTL_TRACE_STREAM << "fetched the first batch of rows, SQL Stm="; \
  989. if (this->stm_label) \
  990. OTL_TRACE_STREAM << this->stm_label; \
  991. else \
  992. OTL_TRACE_STREAM << this->stm_text; \
  993. OTL_TRACE_STREAM << ", RPC="; \
  994. OTL_TRACE_STREAM << row_count; \
  995. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  996. }
  997. #else
  998. #define OTL_TRACE_FIRST_FETCH \
  999. if (OTL_TRACE_LEVEL & 0x8) { \
  1000. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1001. OTL_TRACE_STREAM << "otl_stream(this="; \
  1002. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1003. OTL_TRACE_STREAM << "), "; \
  1004. OTL_TRACE_STREAM << "fetched the first batch of rows, SQL Stm="; \
  1005. OTL_TRACE_STREAM << this->stm_text; \
  1006. OTL_TRACE_STREAM << ", RPC="; \
  1007. OTL_TRACE_STREAM << row_count; \
  1008. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1009. }
  1010. #endif
  1011. #endif
  1012. #if !defined(OTL_TRACE_NEXT_FETCH)
  1013. #if defined(OTL_TRACE_ENABLE_STREAM_LABELS)
  1014. #define OTL_TRACE_NEXT_FETCH \
  1015. if (OTL_TRACE_LEVEL & 0x8 && cur_row == 0) { \
  1016. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1017. OTL_TRACE_STREAM << "otl_stream(this="; \
  1018. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1019. OTL_TRACE_STREAM << "), "; \
  1020. OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \
  1021. if (this->stm_label) \
  1022. OTL_TRACE_STREAM << this->stm_label; \
  1023. else \
  1024. OTL_TRACE_STREAM << this->stm_text; \
  1025. OTL_TRACE_STREAM << ", RPC="; \
  1026. OTL_TRACE_STREAM << row_count; \
  1027. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1028. }
  1029. #define OTL_TRACE_NEXT_FETCH2 \
  1030. if (OTL_TRACE_LEVEL & 0x8 && cur_row == 1) { \
  1031. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1032. OTL_TRACE_STREAM << "otl_stream(this="; \
  1033. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1034. OTL_TRACE_STREAM << "), "; \
  1035. OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \
  1036. if (this->stm_label) \
  1037. OTL_TRACE_STREAM << this->stm_label; \
  1038. else \
  1039. OTL_TRACE_STREAM << this->stm_text; \
  1040. OTL_TRACE_STREAM << ", RPC="; \
  1041. OTL_TRACE_STREAM << row_count; \
  1042. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1043. }
  1044. #else
  1045. #define OTL_TRACE_NEXT_FETCH \
  1046. if (OTL_TRACE_LEVEL & 0x8 && cur_row == 0) { \
  1047. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1048. OTL_TRACE_STREAM << "otl_stream(this="; \
  1049. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1050. OTL_TRACE_STREAM << "), "; \
  1051. OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \
  1052. OTL_TRACE_STREAM << this->stm_text; \
  1053. OTL_TRACE_STREAM << ", RPC="; \
  1054. OTL_TRACE_STREAM << row_count; \
  1055. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1056. }
  1057. #define OTL_TRACE_NEXT_FETCH2 \
  1058. if (OTL_TRACE_LEVEL & 0x8 && cur_row == 1) { \
  1059. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1060. OTL_TRACE_STREAM << "otl_stream(this="; \
  1061. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1062. OTL_TRACE_STREAM << "), "; \
  1063. OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \
  1064. OTL_TRACE_STREAM << this->stm_text; \
  1065. OTL_TRACE_STREAM << ", RPC="; \
  1066. OTL_TRACE_STREAM << row_count; \
  1067. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1068. }
  1069. #endif
  1070. #endif
  1071. #if !defined(OTL_TRACE_STREAM_EXECUTION)
  1072. #if defined(OTL_TRACE_ENABLE_STREAM_LABELS)
  1073. #define OTL_TRACE_STREAM_EXECUTION \
  1074. if (OTL_TRACE_LEVEL & 0x8) { \
  1075. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1076. OTL_TRACE_STREAM << "otl_stream(this="; \
  1077. OTL_TRACE_STREAM << override_->get_master_stream_ptr(); \
  1078. OTL_TRACE_STREAM << "), executing SQL Stm="; \
  1079. if (this->stm_label) \
  1080. OTL_TRACE_STREAM << this->stm_label; \
  1081. else \
  1082. OTL_TRACE_STREAM << this->stm_text; \
  1083. OTL_TRACE_STREAM << ", buffer size="; \
  1084. OTL_TRACE_STREAM << this->array_size; \
  1085. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1086. }
  1087. #else
  1088. #define OTL_TRACE_STREAM_EXECUTION \
  1089. if (OTL_TRACE_LEVEL & 0x8) { \
  1090. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1091. OTL_TRACE_STREAM << "otl_stream(this="; \
  1092. OTL_TRACE_STREAM << override_->get_master_stream_ptr(); \
  1093. OTL_TRACE_STREAM << "), executing SQL Stm="; \
  1094. OTL_TRACE_STREAM << this->stm_text; \
  1095. OTL_TRACE_STREAM << ", buffer size="; \
  1096. OTL_TRACE_STREAM << this->array_size; \
  1097. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1098. }
  1099. #endif
  1100. #endif
  1101. #if !defined(OTL_TRACE_STREAM_EXECUTION2)
  1102. #if defined(OTL_TRACE_ENABLE_STREAM_LABELS)
  1103. #define OTL_TRACE_STREAM_EXECUTION2 \
  1104. if (OTL_TRACE_LEVEL & 0x8) { \
  1105. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1106. OTL_TRACE_STREAM << "otl_stream(this="; \
  1107. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1108. OTL_TRACE_STREAM << "), executing SQL Stm="; \
  1109. if (this->stm_label) \
  1110. OTL_TRACE_STREAM << this->stm_label; \
  1111. else \
  1112. OTL_TRACE_STREAM << this->stm_text; \
  1113. OTL_TRACE_STREAM << ", current batch size="; \
  1114. OTL_TRACE_STREAM << (cur_y + 1); \
  1115. OTL_TRACE_STREAM << ", row offset="; \
  1116. OTL_TRACE_STREAM << rowoff; \
  1117. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1118. }
  1119. #else
  1120. #define OTL_TRACE_STREAM_EXECUTION2 \
  1121. if (OTL_TRACE_LEVEL & 0x8) { \
  1122. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1123. OTL_TRACE_STREAM << "otl_stream(this="; \
  1124. OTL_TRACE_STREAM << this->master_stream_ptr_; \
  1125. OTL_TRACE_STREAM << "), executing SQL Stm="; \
  1126. OTL_TRACE_STREAM << this->stm_text; \
  1127. OTL_TRACE_STREAM << ", current batch size="; \
  1128. OTL_TRACE_STREAM << (cur_y + 1); \
  1129. OTL_TRACE_STREAM << ", row offset="; \
  1130. OTL_TRACE_STREAM << rowoff; \
  1131. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1132. }
  1133. #endif
  1134. #endif
  1135. #if !defined(OTL_TRACE_READ)
  1136. #define OTL_TRACE_READ(val, function, type) \
  1137. if (OTL_TRACE_LEVEL & 0x10) { \
  1138. otl_var_desc *temp_vdesc = describe_next_in_var(); \
  1139. if (temp_vdesc) { \
  1140. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1141. OTL_TRACE_STREAM << "otl_stream(this="; \
  1142. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  1143. OTL_TRACE_STREAM << ")::" function "(" type ": "; \
  1144. OTL_TRACE_STREAM << "ftype="; \
  1145. OTL_TRACE_STREAM << temp_vdesc->ftype; \
  1146. OTL_TRACE_STREAM << ", placeholder="; \
  1147. OTL_TRACE_STREAM << temp_vdesc->name; \
  1148. OTL_TRACE_STREAM << ", value="; \
  1149. OTL_TRACE_STREAM << val; \
  1150. OTL_TRACE_STREAM << ");"; \
  1151. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1152. } else { \
  1153. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1154. OTL_TRACE_STREAM << "loading superfluous input variable"; \
  1155. OTL_TRACE_STREAM << "::" function "(" type ": "; \
  1156. OTL_TRACE_STREAM << ", value="; \
  1157. OTL_TRACE_STREAM << val; \
  1158. OTL_TRACE_STREAM << ");"; \
  1159. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1160. } \
  1161. }
  1162. #endif
  1163. #if !defined(OTL_TRACE_WRITE)
  1164. #define OTL_TRACE_WRITE(val, function, type) \
  1165. if (OTL_TRACE_LEVEL & 0x10) { \
  1166. otl_var_desc *temp_vdesc = describe_next_out_var(); \
  1167. if (temp_vdesc) { \
  1168. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1169. OTL_TRACE_STREAM << "otl_stream(this="; \
  1170. OTL_TRACE_STREAM << OTL_RCAST(void *, this); \
  1171. OTL_TRACE_STREAM << ")::" function "(" type " : "; \
  1172. OTL_TRACE_STREAM << "ftype="; \
  1173. OTL_TRACE_STREAM << temp_vdesc->ftype; \
  1174. OTL_TRACE_STREAM << ", placeholder="; \
  1175. OTL_TRACE_STREAM << temp_vdesc->name; \
  1176. OTL_TRACE_STREAM << ", value="; \
  1177. if (this->is_null()) \
  1178. OTL_TRACE_STREAM << "NULL"; \
  1179. else \
  1180. OTL_TRACE_STREAM << val; \
  1181. OTL_TRACE_STREAM << ");"; \
  1182. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1183. } else { \
  1184. OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \
  1185. OTL_TRACE_STREAM << "writing superfluous output variable"; \
  1186. OTL_TRACE_STREAM << "::" function "(" type " : "; \
  1187. OTL_TRACE_STREAM << ", value="; \
  1188. if (this->is_null()) \
  1189. OTL_TRACE_STREAM << "NULL"; \
  1190. else \
  1191. OTL_TRACE_STREAM << val; \
  1192. OTL_TRACE_STREAM << ");"; \
  1193. OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \
  1194. } \
  1195. }
  1196. #endif
  1197. #else
  1198. #define OTL_TRACE_LINE_PREFIX
  1199. #define OTL_TRACE_LINE_SUFFIX
  1200. #define OTL_TRACE_DIRECT_EXEC
  1201. #define OTL_TRACE_SYNTAX_CHECK
  1202. #define OTL_TRACE_FUNC(level, class_name, func_name, args)
  1203. #define OTL_TRACE_EXCEPTION(code, msg, stm_text, var_info)
  1204. #define OTL_TRACE_EXCEPTION2(code, msg, stm_text, var_info, input_str, \
  1205. inputs_str_size)
  1206. #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \
  1207. passwd, auto_commit)
  1208. #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \
  1209. passwd, auto_commit)
  1210. #define OTL_TRACE_STREAM_OPEN
  1211. #define OTL_TRACE_STREAM_OPEN2
  1212. #define OTL_TRACE_FIRST_FETCH
  1213. #define OTL_TRACE_NEXT_FETCH
  1214. #define OTL_TRACE_NEXT_FETCH2
  1215. #define OTL_TRACE_STREAM_EXECUTION
  1216. #define OTL_TRACE_STREAM_EXECUTION2
  1217. #define OTL_TRACE_WRITE(val, function, type)
  1218. #define OTL_TRACE_READ(val, function, type)
  1219. #define OTL_TRACE_RLOGON_ODBC_W(level, class_name, func_name, tnsname, userid, \
  1220. passwd, auto_commit)
  1221. #endif
  1222. #if defined(OTL_DB2_CLI)
  1223. #define OTL_ODBC
  1224. #endif
  1225. #if defined(OTL_UNICODE)
  1226. #if !defined(OTL_UNICODE_CHAR_TYPE)
  1227. #define OTL_UNICODE_CHAR_TYPE wchar_t
  1228. #endif
  1229. #if !defined(OTL_UNICODE_CHAR_TYPE_TRACE_NAME)
  1230. #define OTL_UNICODE_CHAR_TYPE_TRACE_NAME "wchar_t"
  1231. #endif
  1232. #endif
  1233. #if defined(OTL_UNICODE) && (defined(OTL_ORA8I) || defined(OTL_ORA9I) || \
  1234. defined(OTL_ORA10G) || defined(OTL_ORA10G_R2))
  1235. #define OTL_ORA_UNICODE
  1236. #endif
  1237. #if defined(OTL_UNICODE)
  1238. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \
  1239. defined(OTL_ORA10G_R2)) && \
  1240. defined(OTL_ODBC)
  1241. #error OTL_UNICODE is not supported when both OTL_ORAxx and OTL_ODBC/OTL_DB2_CLI are defined
  1242. #endif
  1243. #if defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \
  1244. defined(OTL_ORA10G_R2)
  1245. #define OTL_CHAR unsigned short
  1246. #define OTL_UNICODE_CHAR OTL_CHAR
  1247. #define OTL_WCHAR unsigned long
  1248. #if defined(OTL_ORA8I) && !defined(OTL_ORA9I) && !defined(OTL_ORA10G) && \
  1249. !defined(OTL_ORA10G_R2) && !defined(OTL_ORA11G) && \
  1250. !defined(OTL_ORA11G_R2) && !defined(OTL_ORA12C)
  1251. #define OTL_UNICODE_ID OCI_UCS2ID
  1252. #endif
  1253. #if defined(OTL_ORA9I)
  1254. #define OTL_UNICODE_ID OCI_UTF16ID
  1255. #endif
  1256. #elif defined(OTL_ODBC)
  1257. #define OTL_CHAR unsigned short
  1258. #define OTL_UNICODE_CHAR OTL_CHAR
  1259. #define OTL_WCHAR OTL_CHAR
  1260. #endif
  1261. #else
  1262. #define OTL_CHAR unsigned char
  1263. #endif
  1264. #if defined(OTL_ORA8)
  1265. #define OTL_PL_TAB
  1266. #endif
  1267. const int otl_short_int_max = 32760;
  1268. #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  1269. #define OTL_ADAPTER_ENUM otl_adapter_enum::
  1270. enum class otl_adapter_enum : unsigned char {
  1271. otl_odbc_adapter = 1,
  1272. otl_ora8_adapter = 2
  1273. };
  1274. #else
  1275. #define OTL_ADAPTER_ENUM
  1276. typedef unsigned char otl_adapter_enum;
  1277. const otl_adapter_enum otl_odbc_adapter = 1;
  1278. const otl_adapter_enum otl_ora8_adapter = 2;
  1279. #endif
  1280. #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  1281. #define OTL_BINDING_ENUM otl_binding_enum::
  1282. enum class otl_binding_enum : unsigned char {
  1283. otl_inout_binding = 1,
  1284. otl_select_binding = 2
  1285. };
  1286. #else
  1287. #define OTL_BINDING_ENUM
  1288. typedef unsigned char otl_binding_enum;
  1289. const otl_binding_enum otl_inout_binding = 1;
  1290. const otl_binding_enum otl_select_binding = 2;
  1291. #endif
  1292. const int otl_unsupported_type = -10000;
  1293. #if defined(OTL_ANSI_CPP)
  1294. #define OTL_SCAST(_t, _e) static_cast<_t>(_e)
  1295. #define OTL_RCAST(_t, _e) reinterpret_cast<_t>(_e)
  1296. #define OTL_DCAST(_t, _e) dynamic_cast<_t>(_e)
  1297. #define OTL_CCAST(_t, _e) const_cast<_t>(_e)
  1298. #define OTL_CONST_EXCEPTION const
  1299. #if defined(OTL_FUNC_THROW_SPEC_ON)
  1300. #define OTL_THROWS_OTL_EXCEPTION throw(otl_exception)
  1301. #define OTL_THROWS_OTL_EXCEPTION2
  1302. #define OTL_THROWS_OTL_EXCEPTION3 throw(OTL_TMPL_EXCEPTION)
  1303. #define OTL_THROWS_OTL_EXCEPTION4
  1304. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  1305. #define OTL_NO_THROW OTL_ANSI_CPP_11_NOEXCEPT
  1306. #else
  1307. #define OTL_NO_THROW throw()
  1308. #endif
  1309. #else
  1310. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_FALSE) && !defined(OTL_THROWS_OTL_EXCEPTION)
  1311. #define OTL_THROWS_OTL_EXCEPTION OTL_ANSI_CPP_11_NOEXCEPT_FALSE
  1312. #define OTL_THROWS_OTL_EXCEPTION2 OTL_ANSI_CPP_11_NOEXCEPT_FALSE
  1313. #define OTL_THROWS_OTL_EXCEPTION3 OTL_ANSI_CPP_11_NOEXCEPT_FALSE
  1314. #define OTL_THROWS_OTL_EXCEPTION4 OTL_ANSI_CPP_11_NOEXCEPT_FALSE
  1315. #else
  1316. #if !defined(OTL_THROWS_OTL_EXCEPTION)
  1317. #define OTL_THROWS_OTL_EXCEPTION
  1318. #define OTL_THROWS_OTL_EXCEPTION2
  1319. #define OTL_THROWS_OTL_EXCEPTION3
  1320. #define OTL_THROWS_OTL_EXCEPTION4
  1321. #endif
  1322. #endif
  1323. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) && !defined(OTL_NO_THROW)
  1324. #define OTL_NO_THROW OTL_ANSI_CPP_11_NOEXCEPT
  1325. #else
  1326. #if defined(OTL_NO_THROW_IS_EMPTY_THROW)
  1327. #define OTL_NO_THROW throw()
  1328. #else
  1329. #if !defined(OTL_NO_THROW)
  1330. #define OTL_NO_THROW
  1331. #endif
  1332. #endif
  1333. #endif
  1334. #endif
  1335. #define OTL_TYPE_NAME typename
  1336. #include <new>
  1337. #else
  1338. #define OTL_SCAST(_t, _e) ((_t)(_e))
  1339. #define OTL_RCAST(_t, _e) ((_t)(_e))
  1340. #define OTL_DCAST(_t, _e) ((_t)(_e))
  1341. #define OTL_CCAST(_t, _e) ((_t)(_e))
  1342. #define OTL_CONST_EXCEPTION
  1343. #define OTL_THROWS_OTL_EXCEPTION
  1344. #define OTL_THROWS_OTL_EXCEPTION2
  1345. #define OTL_THROWS_OTL_EXCEPTION3
  1346. #if defined(OTL_NO_THROW_IS_EMPTY_THROW)
  1347. #define OTL_NO_THROW throw()
  1348. #else
  1349. #define OTL_NO_THROW
  1350. #endif
  1351. #define OTL_TYPE_NAME class
  1352. #endif
  1353. #define OTL_PCONV(_to, _from, _val) \
  1354. OTL_SCAST(_to, *OTL_RCAST(_from *, OTL_CCAST(void *, _val)))
  1355. #if defined(OTL_ACE)
  1356. #include <ace/SString.h>
  1357. #include <ace/Containers_T.h>
  1358. #include <ace/Null_Mutex.h>
  1359. #include <ace/Functor.h>
  1360. #include <ace/RB_Tree.h>
  1361. #define OTL_USER_DEFINED_STRING_CLASS_ON
  1362. #define USER_DEFINED_STRING_CLASS ACE_TString
  1363. #define OTL_VALUE_TEMPLATE_ON
  1364. const int otl_tmpl_vector_default_size = 16;
  1365. template <OTL_TYPE_NAME T> class otl_tmpl_vector : public ACE_Array<T> {
  1366. public:
  1367. otl_tmpl_vector(const int init_size = otl_tmpl_vector_default_size)
  1368. : ACE_Array<T>(init_size == 0 ? otl_tmpl_vector_default_size
  1369. : init_size) {
  1370. length_ = 0;
  1371. }
  1372. ~otl_tmpl_vector() {}
  1373. OTL_NODISCARD int capacity(void) const { return this->max_size(); }
  1374. OTL_NODISCARD int size(void) const { return length_; }
  1375. void clear(void) { length_ = 0; }
  1376. void resize(const int new_size, const T &t = T()) {
  1377. ACE_Array<T>::size(new_size);
  1378. if (new_size > length_) {
  1379. for (int i = length_; i < new_size; ++i)
  1380. (*this)[i] = t;
  1381. }
  1382. length_ = new_size;
  1383. }
  1384. void push_back(const T &elem) {
  1385. int curr_max_size = OTL_SCAST(int, this->max_size());
  1386. if (length_ == curr_max_size)
  1387. ACE_Array<T>::size(curr_max_size * 2);
  1388. ++length_;
  1389. (*this)[length_ - 1] = elem;
  1390. }
  1391. void pop_back(void) {
  1392. if (length_ > 0)
  1393. --length_;
  1394. }
  1395. private:
  1396. int length_;
  1397. };
  1398. #endif
  1399. #if defined(OTL_STLPORT)
  1400. #if defined(__STLPORT_STD)
  1401. #define OTL_STLPORT_NAMESPACE __STLPORT_STD
  1402. #else
  1403. #if defined(_STLP_USE_OWN_NAMESPACE)
  1404. #define OTL_STLPORT_NAMESPACE _STL
  1405. #else
  1406. #define OTL_STLPORT_NAMESPACE std
  1407. #endif
  1408. #endif
  1409. #define OTL_STL
  1410. #endif
  1411. #if defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  1412. #include <exception>
  1413. #if !defined(OTL_STLPORT)
  1414. #if defined(OTL_CPP_17_ON)
  1415. // C++17 and higher deprecated bool std::uncaught_exception()
  1416. OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exceptions() > 0; }
  1417. #else
  1418. OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exception(); }
  1419. #endif
  1420. #else
  1421. OTL_NODISCARD inline bool otl_uncaught_exception() {
  1422. #if defined(OTL_STLPORT_USES_STD_ALIAS_NAMESPACE)
  1423. return __std_alias::uncaught_exception();
  1424. #else
  1425. return OTL_STLPORT_NAMESPACE::uncaught_exception();
  1426. #endif
  1427. }
  1428. #endif
  1429. #else
  1430. OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exception(); }
  1431. #endif
  1432. #define OTL_UNCAUGHT_EXCEPTION_NORETURN if(otl_uncaught_exception()) return;
  1433. #define OTL_UNCAUGHT_EXCEPTION_RETURN(x) if(otl_uncaught_exception()) return x;
  1434. #if defined(OTL_VALUE_TEMPLATE_ON) && !defined(OTL_STL) && !defined(OTL_ACE)
  1435. #define STD_NAMESPACE_PREFIX
  1436. #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(OTL_ANSI_CPP)
  1437. #include <iostream>
  1438. #include <iomanip>
  1439. #else
  1440. #include <iostream.h>
  1441. #include <iomanip.h>
  1442. #endif
  1443. #endif
  1444. #if defined(OTL_USER_DEFINED_STRING_CLASS_ON)
  1445. #if defined(OTL_STL)
  1446. #error OTL_STL cannot be used in combination with OTL_USER_DEFINED_STRING_CLASS_ON
  1447. #endif
  1448. #if defined(USER_DEFINED_STRING_CLASS)
  1449. #define OTL_STRING_CONTAINER USER_DEFINED_STRING_CLASS
  1450. #define STD_NAMESPACE_PREFIX
  1451. #else
  1452. #error USER_DEFINED_STRING_CLASS macro needs to be defined before including otlv4.h
  1453. #endif
  1454. #endif
  1455. #if defined(OTL_STL)
  1456. #if defined(_MSC_VER)
  1457. #if (_MSC_VER >= 1200)
  1458. #pragma warning(disable : 4786)
  1459. #pragma warning(disable : 4290)
  1460. #pragma warning(disable : 4996)
  1461. #endif
  1462. #endif
  1463. #if defined(OTL_STL_NOSTD_NAMESPACE)
  1464. #ifndef OTL_STRING_CONTAINER
  1465. #define OTL_STRING_CONTAINER string
  1466. #endif
  1467. #define STD_NAMESPACE_PREFIX
  1468. #else
  1469. #ifndef OTL_STRING_CONTAINER
  1470. #if defined(OTL_STLPORT)
  1471. #define OTL_STRING_CONTAINER OTL_STLPORT_NAMESPACE::string
  1472. #else
  1473. #define OTL_STRING_CONTAINER std::string
  1474. #endif
  1475. #endif
  1476. #if defined(OTL_STLPORT)
  1477. #define STD_NAMESPACE_PREFIX OTL_STLPORT_NAMESPACE::
  1478. #else
  1479. #define STD_NAMESPACE_PREFIX std::
  1480. #endif
  1481. #endif
  1482. #include <string>
  1483. #include <iterator>
  1484. #include <vector>
  1485. #ifndef OTL_STL_NOSTD_NAMESPACE
  1486. #include <iostream>
  1487. #include <iomanip>
  1488. #else
  1489. #if defined(_MSC_VER) && (_MSC_VER >= 1300)
  1490. #include <iostream>
  1491. #include <iomanip>
  1492. #else
  1493. #include <iostream.h>
  1494. #include <iomanip.h>
  1495. #endif
  1496. #endif
  1497. #endif
  1498. //======================= END OF CONFIGURATION ==============================
  1499. // ====== COMMON NON-TEMPLATE OBJECTS: CONSTANTS, CLASSES, ETC. ===========
  1500. #if defined(OTL_INITIAL_VAR_LIST_SIZE)
  1501. const int otl_var_list_size = OTL_INITIAL_VAR_LIST_SIZE;
  1502. #else
  1503. #if defined(OTL_ORA8)
  1504. const int otl_var_list_size = 1024;
  1505. #else
  1506. const int otl_var_list_size = 512;
  1507. #endif
  1508. #endif
  1509. const int otl_error_code_0 = 32000;
  1510. #define otl_error_msg_0 "Incompatible data types in stream operation"
  1511. const int otl_error_code_1 = 32004;
  1512. #define otl_error_msg_1 "No input variables have been defined in SQL statement"
  1513. const int otl_error_code_2 = 32003;
  1514. #define otl_error_msg_2 "Not all input variables have been initialized"
  1515. const int otl_error_code_3 = 32001;
  1516. #define otl_error_msg_3 "Row must be full for flushing output stream"
  1517. const int otl_error_code_4 = 32005;
  1518. #define otl_error_msg_4 "Input string value is too large to fit into the buffer"
  1519. const int otl_error_code_5 = 32006;
  1520. #define otl_error_msg_5 \
  1521. "Input otl_long_string is too large to fit into the buffer"
  1522. const int otl_error_code_6 = 32007;
  1523. #define otl_error_msg_6 "PL/SQL table size is too large (>32767)"
  1524. const int otl_error_code_7 = 32008;
  1525. #define otl_error_msg_7 \
  1526. "Writing CLOB/BLOB in stream mode: actual size is greater than specified"
  1527. const int otl_error_code_8 = 32009;
  1528. #define otl_error_msg_8 \
  1529. "Closing CLOB/BLOB in stream mode: actual size is not equal to specified " \
  1530. "size"
  1531. const int otl_error_code_9 = 32010;
  1532. #define otl_error_msg_9 "CLOB/BLOB stream is not open for writing"
  1533. const int otl_error_code_10 = 32011;
  1534. #define otl_error_msg_10 "CLOB/BLOB stream is not open for reading"
  1535. const int otl_error_code_11 = 32012;
  1536. #define otl_error_msg_11 "First session must be started with session_begin()"
  1537. const int otl_error_code_12 = 32013;
  1538. #define otl_error_msg_12 "Invalid bind variable declaration"
  1539. const int otl_error_code_13 = 32014;
  1540. #define otl_error_msg_13 "No stored procedure was found"
  1541. const int otl_error_code_14 = 32015;
  1542. #define otl_error_msg_14 "Unsupported data type: "
  1543. const int otl_error_code_15 = 32016;
  1544. #define otl_error_msg_15 "Unsupported procedure type"
  1545. const int otl_error_code_16 = 32017;
  1546. #define otl_error_msg_16 "Stream buffer size can't be > 1 in this case"
  1547. const int otl_error_code_17 = 32018;
  1548. #define otl_error_msg_17 \
  1549. "ODBC / DB2 CLI function name is not recognized. " \
  1550. "It should be one of the following: SQLTables, SQLColumns, " \
  1551. "SQLProcedures, SQLColumnPrivileges, SQLTablePrivileges, " \
  1552. "SQLPrimaryKeys, SQLProcedureColumns, SQLForeignKeys, SQLStatistics"
  1553. const int otl_error_code_18 = 32019;
  1554. #define otl_error_msg_18 \
  1555. "otl_stream::operator>>() should have been called " \
  1556. "before otl_stream::operator int()"
  1557. const int otl_error_code_19 = 32020;
  1558. #define otl_error_msg_19 "otl_stream_read_iterator: otl_stream is not open"
  1559. const int otl_error_code_20 = 32021;
  1560. #define otl_error_msg_20 \
  1561. "otl_stream_read_iterator: PL/SQL table and 'refcur' " \
  1562. "parameters are not supported"
  1563. const int otl_error_code_21 = 32022;
  1564. #define otl_error_msg_21 \
  1565. "otl_stream_read_iterator: otl_stream cannot be described"
  1566. const int otl_error_code_22 = 32023;
  1567. #define otl_error_msg_22 "otl_stream_read_iterator: position is out of range"
  1568. const int otl_error_code_23 = 32024;
  1569. #define otl_error_msg_23 "otl_stream_read_iterator: incompatible types in get()"
  1570. const int otl_error_code_24 = 32025;
  1571. #define otl_error_msg_24 \
  1572. "otl_stream::operator int() is not supported in the LOB stream mode"
  1573. const int otl_error_code_25 = 32026;
  1574. #define otl_error_msg_25 \
  1575. "otl_stream_read_iterator: get(otl_lob_stream*&) function " \
  1576. "can only be used if otl_stream::set_lob_stream_mode(true) had been called " \
  1577. "before the iterator was attached to the stream"
  1578. const int otl_error_code_26 = 32027;
  1579. #define otl_error_msg_26 \
  1580. "otl_stream_read_iterator: variable name is not recognized "
  1581. const int otl_error_code_27 = 32028;
  1582. #define otl_error_msg_27 "Unsupported column data type"
  1583. const int otl_error_code_28 = 32029;
  1584. #define otl_error_msg_28 \
  1585. "RAW value cannot be read with otl_lob_stream, use otl_long_string instead"
  1586. const int otl_error_code_29 = 32030;
  1587. #define otl_error_msg_29 "otl_stream is already open"
  1588. const int otl_error_code_30 = 32031;
  1589. #define otl_error_msg_30 "otl_connect is already connected"
  1590. const int otl_error_code_31 = 32032;
  1591. #define otl_error_msg_31 \
  1592. "SELECT otl_stream buffer size for TimesTen should be in [0..128] range"
  1593. const int otl_error_code_32 = 32033;
  1594. #define otl_error_msg_32 \
  1595. "otl_connect object needs to be connected to DB before using otl_subscriber"
  1596. const int otl_error_code_33 = 32034;
  1597. #define otl_error_msg_33 \
  1598. "otl_stream buffer size should be 1 when refcur or plsql table is used"
  1599. const int otl_error_code_34 = 32035;
  1600. #define otl_error_msg_34 "END-OF-ROW check failed"
  1601. const int otl_error_code_35 = 32036;
  1602. #define otl_error_msg_35 "otl_connect is not connected to the database"
  1603. const int otl_error_code_36 = 32037;
  1604. #define otl_error_msg_36 \
  1605. "SQL Statement has a white space in bind variable declaration"
  1606. const int otl_error_code_37 = 32038;
  1607. #define otl_error_msg_37 \
  1608. "otl_long_unicode_string should be used with strings when OTL_UNICODE is " \
  1609. "enabled, " \
  1610. " and otl_long_string should be use with strings when OTL_UNICODE is not " \
  1611. "enabled"
  1612. const int otl_error_code_38 = 32039;
  1613. #define otl_error_msg_38 \
  1614. "otl_long_string should be used with nonstrings when OTL_UNICODE is enabled"
  1615. const int otl_error_code_39 = 32040;
  1616. #define otl_error_msg_39 "This type of otl_stream can only have input variables"
  1617. const int otl_error_code_40 = 32041;
  1618. #define otl_error_msg_40 "Invalid stream buffer size (<=0)"
  1619. const int otl_error_code_41 = 32042;
  1620. #define otl_error_msg_41 \
  1621. "otl_lob_stream can't be used as an input parameter " \
  1622. "with a SELECT statement or a stored procedure that returns an implicit " \
  1623. "result set"
  1624. const int otl_error_code_42 = 32043;
  1625. #define otl_error_msg_42 \
  1626. "otl_stream::operator>>(%s) has been called when EOF was already reached"
  1627. const int otl_error_code_43 = 32044;
  1628. #define otl_error_msg_43 \
  1629. "Bind variable declaration is missing a terminator: > or */"
  1630. const int otl_error_code_44 = 32045;
  1631. #define otl_error_msg_44 "Empty TNS name in connect string"
  1632. const int otl_error_code_45 = 32046;
  1633. #define otl_error_msg_45 "target std::array<char,...> container is too small"
  1634. const int otl_error_code_46 = 32047;
  1635. #define otl_error_msg_46 "target std::array<char16_t,...> container is too small"
  1636. const int otl_error_code_47 = 32048;
  1637. #define otl_error_msg_47 "rewind() cannot be called when implicit_select == otl_direct_exec_select"
  1638. const int otl_oracle_date_size = 7;
  1639. const int otl_explicit_select = 0;
  1640. const int otl_implicit_select = 1;
  1641. const int otl_direct_exec_select = 2;
  1642. const int otl_input_param = 0;
  1643. const int otl_output_param = 1;
  1644. const int otl_inout_param = 2;
  1645. const unsigned int otl_all_num2str = 1;
  1646. const unsigned int otl_all_date2str = 2;
  1647. const int otl_num_str_size = 60;
  1648. const int otl_date_str_size = 60;
  1649. template <OTL_TYPE_NAME T> class otl_auto_array_ptr {
  1650. public:
  1651. otl_auto_array_ptr() : ptr(0), arr_size_(0) {}
  1652. otl_auto_array_ptr(const int arr_size)
  1653. : ptr(new T[OTL_SCAST(size_t,arr_size)]), arr_size_(arr_size) {}
  1654. void double_size(void) {
  1655. int old_arr_size = arr_size_;
  1656. arr_size_ *= 2;
  1657. T *temp_ptr = new T[OTL_SCAST(size_t,arr_size_)];
  1658. for (int i = 0; i < old_arr_size; ++i)
  1659. temp_ptr[i] = ptr[i];
  1660. delete[] ptr;
  1661. ptr = temp_ptr;
  1662. }
  1663. virtual ~otl_auto_array_ptr() { delete[] ptr; }
  1664. OTL_NODISCARD T *get_ptr() { return ptr; }
  1665. OTL_NODISCARD int get_arr_size() const { return arr_size_; }
  1666. private:
  1667. T *ptr;
  1668. int arr_size_;
  1669. otl_auto_array_ptr(const otl_auto_array_ptr<T> &)
  1670. : ptr(nullptr), arr_size_(0) {}
  1671. otl_auto_array_ptr<T> &operator=(const otl_auto_array_ptr<T> &) {
  1672. return *this;
  1673. }
  1674. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  1675. otl_auto_array_ptr(otl_auto_array_ptr<T> &&) : ptr(nullptr), arr_size_(0) {}
  1676. otl_auto_array_ptr<T> &operator=(otl_auto_array_ptr<T> &&) { return *this; }
  1677. #endif
  1678. };
  1679. template <OTL_TYPE_NAME T> class otl_ptr {
  1680. public:
  1681. otl_ptr() : ptr(nullptr), arr_flag(0) {}
  1682. void assign(T **var) {
  1683. ptr = var;
  1684. arr_flag = 0;
  1685. }
  1686. void assign_array(T **var) {
  1687. ptr = var;
  1688. arr_flag = 1;
  1689. }
  1690. void disconnect(void) {
  1691. if (ptr != nullptr)
  1692. *ptr = nullptr;
  1693. ptr = nullptr;
  1694. }
  1695. void destroy(void) {
  1696. if (ptr == nullptr)
  1697. return;
  1698. if (*ptr != nullptr) {
  1699. if (arr_flag)
  1700. delete[] * ptr;
  1701. else
  1702. delete *ptr;
  1703. *ptr = nullptr;
  1704. }
  1705. }
  1706. ~otl_ptr() { destroy(); }
  1707. protected:
  1708. T **ptr;
  1709. int arr_flag;
  1710. private:
  1711. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  1712. public:
  1713. otl_ptr(const otl_ptr &) = delete;
  1714. otl_ptr &operator=(const otl_ptr &) = delete;
  1715. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  1716. otl_ptr(otl_ptr &&) = delete;
  1717. otl_ptr &operator=(otl_ptr &&) = delete;
  1718. #endif
  1719. private:
  1720. #else
  1721. otl_ptr(const otl_ptr &) : ptr(nullptr), arr_flag(0) {}
  1722. otl_ptr &operator=(const otl_ptr &) { return *this; }
  1723. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  1724. otl_ptr(otl_ptr &&) : ptr(nullptr), arr_flag(0) {}
  1725. otl_ptr &operator=(otl_ptr &&) { return *this; }
  1726. #endif
  1727. #endif
  1728. };
  1729. template <OTL_TYPE_NAME T> class otl_Tptr {
  1730. public:
  1731. otl_Tptr() : ptr(nullptr), do_not_destroy(false) {}
  1732. void assign(T *var) { ptr = var; }
  1733. void disconnect(void) { ptr = nullptr; }
  1734. void destroy(void) {
  1735. if (do_not_destroy)
  1736. return;
  1737. delete ptr;
  1738. ptr = nullptr;
  1739. }
  1740. ~otl_Tptr() { destroy(); }
  1741. otl_Tptr &operator=(const otl_Tptr &src) {
  1742. ptr = src.ptr;
  1743. do_not_destroy = src.do_not_destroy;
  1744. return *this;
  1745. }
  1746. void set_do_not_destroy(const bool ado_not_destroy) {
  1747. do_not_destroy = ado_not_destroy;
  1748. }
  1749. T *get_ptr() { return ptr; }
  1750. protected:
  1751. T *ptr;
  1752. bool do_not_destroy;
  1753. private:
  1754. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  1755. public:
  1756. otl_Tptr(const otl_Tptr &) = delete;
  1757. otl_Tptr(otl_Tptr &&) = delete;
  1758. private:
  1759. #else
  1760. otl_Tptr(const otl_Tptr &) : ptr(nullptr), do_not_destroy(false) {}
  1761. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  1762. otl_Tptr(otl_Tptr &&) : ptr(nullptr), do_not_destroy(false) {}
  1763. #endif
  1764. #endif
  1765. };
  1766. class otl_select_struct_override {
  1767. public:
  1768. otl_select_struct_override()
  1769. : col_ndx(new short int[otl_var_list_size]),
  1770. col_type(new short int[otl_var_list_size]),
  1771. col_size(new int[otl_var_list_size]), len(0), all_mask(0),
  1772. lob_stream_mode(false), container_size_(otl_var_list_size),
  1773. master_stream_ptr_(nullptr) {}
  1774. ~otl_select_struct_override() {
  1775. delete[] col_ndx;
  1776. delete[] col_type;
  1777. delete[] col_size;
  1778. }
  1779. void set_master_stream_ptr(void *stream_ptr) {
  1780. master_stream_ptr_ = stream_ptr;
  1781. }
  1782. OTL_NODISCARD void *get_master_stream_ptr() { return master_stream_ptr_; }
  1783. void reset(void) {
  1784. len = 0;
  1785. all_mask = 0;
  1786. lob_stream_mode = false;
  1787. }
  1788. void add_override(const int andx, const int atype, const int asize = 0) {
  1789. if (len == container_size_) {
  1790. unsigned int temp_container_size =
  1791. OTL_SCAST(unsigned int, container_size_);
  1792. container_size_ *= 2;
  1793. short int *temp_col_ndx = nullptr;
  1794. short int *temp_col_type = nullptr;
  1795. int *temp_col_size = nullptr;
  1796. try {
  1797. temp_col_ndx = new short int[OTL_SCAST(size_t,container_size_)];
  1798. temp_col_type = new short int[OTL_SCAST(size_t,container_size_)];
  1799. temp_col_size = new int[OTL_SCAST(size_t,container_size_)];
  1800. }
  1801. catch (const std::bad_alloc &) {
  1802. delete[] temp_col_ndx;
  1803. delete[] temp_col_type;
  1804. delete[] temp_col_size;
  1805. throw;
  1806. }
  1807. memcpy(temp_col_ndx, col_ndx, sizeof(short int) * temp_container_size);
  1808. memcpy(temp_col_type, col_type, sizeof(short int) * temp_container_size);
  1809. memcpy(temp_col_size, col_size, sizeof(int) * temp_container_size);
  1810. delete[] col_ndx;
  1811. delete[] col_type;
  1812. delete[] col_size;
  1813. col_ndx = temp_col_ndx;
  1814. col_type = temp_col_type;
  1815. col_size = temp_col_size;
  1816. }
  1817. ++len;
  1818. col_ndx[len - 1] = OTL_SCAST(short, andx);
  1819. col_type[len - 1] = OTL_SCAST(short, atype);
  1820. col_size[len - 1] = asize;
  1821. }
  1822. OTL_NODISCARD int find(const int ndx) const {
  1823. int i;
  1824. for (i = 0; i < len; ++i)
  1825. if (ndx == col_ndx[i])
  1826. return i;
  1827. return -1;
  1828. }
  1829. void set_all_column_types(const unsigned int amask = 0) { all_mask = amask; }
  1830. OTL_NODISCARD int getLen(void) const { return len; }
  1831. OTL_NODISCARD unsigned int get_all_mask() const { return all_mask; }
  1832. OTL_NODISCARD short int get_col_type(int ndx) const { return col_type[ndx]; }
  1833. OTL_NODISCARD int get_col_size(int ndx) const { return col_size[ndx]; }
  1834. void setLen(const int alen) { len = alen; }
  1835. OTL_NODISCARD bool get_lob_stream_mode() const { return lob_stream_mode; }
  1836. void set_lob_stream_mode(const bool alobs_tream_mode) {
  1837. lob_stream_mode = alobs_tream_mode;
  1838. }
  1839. private:
  1840. short int *col_ndx;
  1841. short int *col_type;
  1842. int *col_size;
  1843. int len;
  1844. unsigned int all_mask;
  1845. bool lob_stream_mode;
  1846. int container_size_;
  1847. void *master_stream_ptr_;
  1848. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  1849. public:
  1850. otl_select_struct_override(const otl_select_struct_override &) = delete;
  1851. otl_select_struct_override &operator=(const otl_select_struct_override &) =
  1852. delete;
  1853. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  1854. otl_select_struct_override(otl_select_struct_override &&) = delete;
  1855. otl_select_struct_override &operator=(otl_select_struct_override &&) = delete;
  1856. #endif
  1857. private:
  1858. #else
  1859. otl_select_struct_override(const otl_select_struct_override &)
  1860. : col_ndx(nullptr), col_type(nullptr), col_size(nullptr), len(0),
  1861. all_mask(0), lob_stream_mode(false), container_size_(0),
  1862. master_stream_ptr_(nullptr) {}
  1863. otl_select_struct_override &operator=(const otl_select_struct_override &) {
  1864. return *this;
  1865. }
  1866. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  1867. otl_select_struct_override(otl_select_struct_override &&)
  1868. : col_ndx(nullptr), col_type(nullptr), col_size(nullptr), len(0),
  1869. all_mask(0), lob_stream_mode(false), container_size_(0),
  1870. master_stream_ptr_(nullptr) {}
  1871. otl_select_struct_override &operator=(otl_select_struct_override &&) {
  1872. return *this;
  1873. }
  1874. #endif
  1875. #endif
  1876. };
  1877. OTL_NODISCARD inline int otl_decimal_degree(unsigned int num) {
  1878. int n = 0;
  1879. while (num != 0) {
  1880. ++n;
  1881. num /= 10;
  1882. }
  1883. return n;
  1884. }
  1885. OTL_NODISCARD inline bool otl_isspace(char c) {
  1886. return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
  1887. c == '\v';
  1888. }
  1889. OTL_NODISCARD inline char otl_to_upper(char c) { return OTL_SCAST(char, toupper(c)); }
  1890. OTL_NODISCARD inline bool otl_str_case_insensitive_equal(const char *s1, const char *s2) {
  1891. while (*s1 && *s2) {
  1892. if (otl_to_upper(*s1) != otl_to_upper(*s2))
  1893. return false;
  1894. ++s1;
  1895. ++s2;
  1896. }
  1897. if (*s1 == 0 && *s2 == 0)
  1898. return true;
  1899. else
  1900. return false;
  1901. }
  1902. OTL_NODISCARD inline unsigned int otl_to_fraction(unsigned int fraction, int frac_prec) {
  1903. if (fraction == 0 || frac_prec == 0)
  1904. return fraction;
  1905. int fraction_degree = otl_decimal_degree(fraction);
  1906. if (fraction_degree > frac_prec) {
  1907. // in case if the actual fraction value is beyond the "fraction
  1908. // precision" range, truncate the value
  1909. int excess_decimal_digits = fraction_degree - frac_prec;
  1910. for (int iter = 1; iter <= excess_decimal_digits; ++iter)
  1911. fraction /= 10;
  1912. }
  1913. int degree_diff = 9 - frac_prec;
  1914. for (int i = 0; i < degree_diff; ++i)
  1915. fraction *= 10;
  1916. return fraction;
  1917. }
  1918. OTL_NODISCARD inline unsigned int otl_from_fraction(unsigned int fraction, int frac_prec) {
  1919. if (fraction == 0 || frac_prec == 0)
  1920. return fraction;
  1921. int degree_diff = 9 - frac_prec;
  1922. for (int i = 0; i < degree_diff; ++i)
  1923. fraction /= 10;
  1924. return fraction;
  1925. }
  1926. #define OTL_NO_STM_TEXT "#No Stm Text available#"
  1927. #if (defined(OTL_ODBC) || defined(OTL_DB2_CLI)) && defined(OTL_ORA_UTF8)
  1928. #if !defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1929. #define OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS
  1930. #endif
  1931. #endif
  1932. class otl_datetime {
  1933. public:
  1934. int year;
  1935. int month;
  1936. int day;
  1937. int hour;
  1938. int minute;
  1939. int second;
  1940. unsigned long fraction;
  1941. int frac_precision;
  1942. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  1943. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1944. short int tz_hour;
  1945. short int tz_minute;
  1946. #endif
  1947. otl_datetime()
  1948. : year(1900), month(1), day(1), hour(0), minute(0), second(0),
  1949. fraction(0), frac_precision(0)
  1950. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  1951. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1952. ,
  1953. tz_hour(0), tz_minute(0)
  1954. #endif
  1955. {
  1956. }
  1957. otl_datetime(const int ayear, const int amonth, const int aday,
  1958. const int ahour, const int aminute, const int asecond,
  1959. const unsigned long afraction = 0, const int afrac_precision = 0
  1960. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  1961. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1962. ,
  1963. const short int atz_hour = 0, const short int atz_minute = 0
  1964. #endif
  1965. )
  1966. : year(ayear), month(amonth), day(aday), hour(ahour), minute(aminute),
  1967. second(asecond), fraction(afraction), frac_precision(afrac_precision)
  1968. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  1969. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1970. ,
  1971. tz_hour(atz_hour), tz_minute(atz_minute)
  1972. #endif
  1973. {
  1974. }
  1975. otl_datetime(const otl_datetime &dt)
  1976. : year(dt.year), month(dt.month), day(dt.day), hour(dt.hour),
  1977. minute(dt.minute), second(dt.second), fraction(dt.fraction),
  1978. frac_precision(dt.frac_precision)
  1979. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  1980. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  1981. ,
  1982. tz_hour(dt.tz_hour), tz_minute(dt.tz_minute)
  1983. #endif
  1984. {
  1985. }
  1986. ~otl_datetime() {}
  1987. otl_datetime &operator=(const otl_datetime &dt) {
  1988. copy(dt);
  1989. return *this;
  1990. }
  1991. private:
  1992. void copy(const otl_datetime &dt) {
  1993. year = dt.year;
  1994. month = dt.month;
  1995. day = dt.day;
  1996. hour = dt.hour;
  1997. minute = dt.minute;
  1998. second = dt.second;
  1999. fraction = dt.fraction;
  2000. frac_precision = dt.frac_precision;
  2001. #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \
  2002. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2003. tz_hour = dt.tz_hour;
  2004. tz_minute = dt.tz_minute;
  2005. #endif
  2006. }
  2007. };
  2008. struct otl_oracle_date {
  2009. unsigned char century;
  2010. unsigned char year;
  2011. unsigned char month;
  2012. unsigned char day;
  2013. unsigned char hour;
  2014. unsigned char minute;
  2015. unsigned char second;
  2016. otl_oracle_date()
  2017. : century(0), year(0), month(0), day(0), hour(0), minute(0), second(0) {}
  2018. otl_oracle_date& operator=(const otl_oracle_date& that){
  2019. century=that.century;
  2020. year=that.year;
  2021. month=that.month;
  2022. day=that.day;
  2023. hour=that.hour;
  2024. minute=that.minute;
  2025. second=that.second;
  2026. return *this;
  2027. }
  2028. ~otl_oracle_date() {}
  2029. };
  2030. inline void convert_date(otl_datetime &t, const otl_oracle_date &s) {
  2031. t.year =
  2032. (OTL_SCAST(int, s.century - 100) * 100 + (OTL_SCAST(int, s.year - 100)));
  2033. t.month = s.month;
  2034. t.day = s.day;
  2035. t.hour = s.hour - 1;
  2036. t.minute = s.minute - 1;
  2037. t.second = s.second - 1;
  2038. }
  2039. inline void convert_date(otl_oracle_date &t, const otl_datetime &s) {
  2040. t.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100));
  2041. t.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100));
  2042. t.month = OTL_SCAST(unsigned char, s.month);
  2043. t.day = OTL_SCAST(unsigned char, s.day);
  2044. t.hour = OTL_SCAST(unsigned char, (s.hour + 1));
  2045. t.minute = OTL_SCAST(unsigned char, (s.minute + 1));
  2046. t.second = OTL_SCAST(unsigned char, (s.second + 1));
  2047. }
  2048. class otl_null {
  2049. public:
  2050. otl_null() {}
  2051. ~otl_null() {}
  2052. otl_null(const otl_null&){}
  2053. };
  2054. #if defined(OTL_ORA_SDO_GEOMETRY)
  2055. struct OCIType;
  2056. #endif
  2057. class otl_column_desc {
  2058. public:
  2059. char *name;
  2060. int dbtype;
  2061. int otl_var_dbtype;
  2062. #if defined(_WIN64)
  2063. __int64 dbsize;
  2064. #else
  2065. int dbsize;
  2066. #endif
  2067. int scale;
  2068. #if defined(_WIN64)
  2069. __int64 prec;
  2070. #else
  2071. int prec;
  2072. #endif
  2073. int nullok;
  2074. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2075. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2076. int charset_form;
  2077. int char_size;
  2078. #endif
  2079. #if defined(OTL_ORA_SDO_GEOMETRY)
  2080. char *name_type;
  2081. OCIType *colOCIType;
  2082. #endif
  2083. private:
  2084. #if defined(OTL_ORA_SDO_GEOMETRY)
  2085. int name_type_len_;
  2086. #endif
  2087. int name_len_;
  2088. public:
  2089. otl_column_desc()
  2090. : name(nullptr), dbtype(0), otl_var_dbtype(0), dbsize(0), scale(0),
  2091. prec(0), nullok(0),
  2092. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2093. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2094. charset_form(0), char_size(0),
  2095. #endif
  2096. #if defined(OTL_ORA_SDO_GEOMETRY)
  2097. name_type(nullptr), colOCIType(nullptr), name_type_len_(0),
  2098. #endif
  2099. name_len_(0)
  2100. {
  2101. }
  2102. ~otl_column_desc() {
  2103. if(name)delete[] name;
  2104. #if defined(OTL_ORA_SDO_GEOMETRY)
  2105. if(name_type)delete[] name_type;
  2106. #endif
  2107. }
  2108. #if defined(_MSC_VER) && (_MSC_VER>=1900)
  2109. #pragma warning(push)
  2110. #pragma warning(disable : 6387)
  2111. #endif
  2112. otl_column_desc &operator=(const otl_column_desc &desc) {
  2113. if (name_len_ >= desc.name_len_)
  2114. OTL_STRCPY_S(name, name_len_, desc.name);
  2115. else if (name == nullptr && desc.name != nullptr) {
  2116. name = new char[OTL_SCAST(size_t,desc.name_len_)];
  2117. name_len_ = desc.name_len_;
  2118. OTL_STRCPY_S(name, name_len_, desc.name);
  2119. } else if (name_len_ < desc.name_len_ && desc.name != nullptr) {
  2120. delete[] name;
  2121. name = new char[OTL_SCAST(size_t,desc.name_len_)];
  2122. name_len_ = desc.name_len_;
  2123. OTL_STRCPY_S(name, name_len_, desc.name);
  2124. }
  2125. dbtype = desc.dbtype;
  2126. otl_var_dbtype = desc.otl_var_dbtype;
  2127. dbsize = desc.dbsize;
  2128. scale = desc.scale;
  2129. prec = desc.prec;
  2130. nullok = desc.nullok;
  2131. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2132. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2133. charset_form = desc.charset_form;
  2134. char_size = desc.char_size;
  2135. #endif
  2136. #if defined(OTL_ORA_SDO_GEOMETRY)
  2137. if(name_type_len_ >= desc.name_type_len_ && name_type)
  2138. OTL_STRCPY_S(name_type, name_type_len_, desc.name);
  2139. else if(name_type == nullptr && desc.name_type != nullptr){
  2140. name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)];
  2141. name_type_len_ = desc.name_type_len_;
  2142. OTL_STRCPY_S(name_type, name_type_len_, desc.name_type);
  2143. }else if(name_type_len_ < desc.name_type_len_ && desc.name_type != nullptr){
  2144. delete[] name_type;
  2145. name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)];
  2146. name_type_len_ = desc.name_type_len_;
  2147. OTL_STRCPY_S(name_type, name_type_len_, desc.name_type);
  2148. }
  2149. colOCIType = desc.colOCIType;
  2150. #endif
  2151. return *this;
  2152. }
  2153. #if defined(_MSC_VER) && (_MSC_VER>=1900)
  2154. #pragma warning(pop)
  2155. #endif
  2156. otl_column_desc(const otl_column_desc &desc)
  2157. : name(nullptr), dbtype(desc.dbtype), otl_var_dbtype(0),
  2158. dbsize(desc.dbsize), scale(desc.scale), prec(desc.prec),
  2159. nullok(desc.nullok),
  2160. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2161. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2162. charset_form(desc.charset_form), char_size(desc.char_size),
  2163. #endif
  2164. #if defined(OTL_ORA_SDO_GEOMETRY)
  2165. colOCIType(desc.colOCIType),
  2166. name_type_len_(desc.name_type_len_),
  2167. #endif
  2168. name_len_(desc.name_len_)
  2169. {
  2170. if (desc.name != nullptr) {
  2171. name = new char[OTL_SCAST(size_t,desc.name_len_)];
  2172. OTL_STRCPY_S(name, name_len_, desc.name);
  2173. }
  2174. #if defined(OTL_ORA_SDO_GEOMETRY)
  2175. if(desc.name_type != nullptr){
  2176. name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)];
  2177. OTL_STRCPY_S(name_type, name_type_len_, desc.name_type);
  2178. }
  2179. #endif
  2180. }
  2181. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  2182. otl_column_desc &operator=(otl_column_desc &&desc) OTL_ANSI_CPP_11_NOEXCEPT {
  2183. if (name != nullptr)
  2184. delete[] name;
  2185. name = desc.name;
  2186. name_len_ = desc.name_len_;
  2187. desc.name = nullptr;
  2188. desc.name_len_ = 0;
  2189. dbtype = desc.dbtype;
  2190. otl_var_dbtype = desc.otl_var_dbtype;
  2191. dbsize = desc.dbsize;
  2192. scale = desc.scale;
  2193. prec = desc.prec;
  2194. nullok = desc.nullok;
  2195. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2196. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2197. charset_form = desc.charset_form;
  2198. char_size = desc.char_size;
  2199. #endif
  2200. #if defined(OTL_ORA_SDO_GEOMETRY)
  2201. name_type = desc.name_type;
  2202. name_type_len_ = desc.name_type_len_;
  2203. desc.name_type = nullptr;
  2204. desc.name_type_len_ = 0;
  2205. colOCIType = desc.colOCIType;
  2206. #endif
  2207. return *this;
  2208. }
  2209. otl_column_desc(otl_column_desc &&desc) OTL_ANSI_CPP_11_NOEXCEPT
  2210. : name(desc.name),
  2211. dbtype(desc.dbtype),
  2212. otl_var_dbtype(0),
  2213. dbsize(desc.dbsize),
  2214. scale(desc.scale),
  2215. prec(desc.prec),
  2216. nullok(desc.nullok),
  2217. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \
  2218. defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  2219. charset_form(desc.charset_form),
  2220. char_size(desc.char_size),
  2221. #endif
  2222. #if defined(OTL_ORA_SDO_GEOMETRY)
  2223. name_type(desc.name_type),
  2224. colOCIType(desc.colOCIType),
  2225. name_type_len_(desc.name_type_len_),
  2226. #endif
  2227. name_len_(desc.name_len_)
  2228. {
  2229. desc.name = nullptr;
  2230. desc.name_len_ = 0;
  2231. #if defined(OTL_ORA_SDO_GEOMETRY)
  2232. desc.name_type = nullptr;
  2233. desc.name_type_len_ = 0;
  2234. #endif
  2235. }
  2236. #endif
  2237. void set_name(const char *aname, const int aname_len = 0) {
  2238. int len;
  2239. if (aname_len == 0)
  2240. len = OTL_SCAST(int, strlen(aname)) + 1;
  2241. else
  2242. len = aname_len + 1;
  2243. if (name_len_ < len) {
  2244. if (name)
  2245. delete[] name;
  2246. name = new char[OTL_SCAST(size_t,len)];
  2247. name_len_ = len;
  2248. for (int i = 0; i < len - 1; ++i)
  2249. name[i] = aname[i];
  2250. name[len - 1] = 0;
  2251. }
  2252. }
  2253. #if defined(OTL_ORA_SDO_GEOMETRY)
  2254. void set_name_type(const char *aname, const int aname_len = 0){
  2255. int len;
  2256. if(aname_len == 0)
  2257. len = OTL_SCAST(int, strlen(aname)) + 1;
  2258. else
  2259. len = aname_len + 1;
  2260. if(name_type_len_ < len){
  2261. if(name_type)delete[] name_type;
  2262. name_type = new char[OTL_SCAST(size_t, len)];
  2263. name_type_len_ = len;
  2264. for(int i = 0; i < len - 1; ++i)
  2265. name_type[i] = aname[i];
  2266. name_type[len - 1] = 0;
  2267. }
  2268. }
  2269. #endif
  2270. };
  2271. class otl_var_desc {
  2272. public:
  2273. int param_type;
  2274. int ftype;
  2275. int elem_size;
  2276. int array_size;
  2277. int pos;
  2278. int name_pos;
  2279. char name[128];
  2280. int pl_tab_flag;
  2281. otl_var_desc()
  2282. : param_type(0), ftype(0), elem_size(0), array_size(0), pos(0),
  2283. name_pos(0), name(), pl_tab_flag(0) {
  2284. name[0] = 0;
  2285. }
  2286. ~otl_var_desc() {}
  2287. void copy_name(const char *nm) {
  2288. if (!nm)
  2289. name[0] = 0;
  2290. else {
  2291. #if defined(_MSC_VER)
  2292. #if (_MSC_VER >= 1400)
  2293. OTL_STRNCPY_S(name, sizeof(name), nm, sizeof(name) - 1);
  2294. name[sizeof(name) - 1] = 0;
  2295. #else
  2296. strncpy(name, nm, sizeof(name));
  2297. name[sizeof(name) - 1] = 0;
  2298. #endif
  2299. #else
  2300. strncpy(name, nm, sizeof(name));
  2301. name[sizeof(name) - 1] = 0;
  2302. #endif
  2303. }
  2304. }
  2305. void set_param_type(const int aparam_type){ this->param_type=aparam_type; }
  2306. };
  2307. #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  2308. enum otl_var_enum : unsigned char {
  2309. otl_var_none = 0,
  2310. otl_var_char = 1,
  2311. otl_var_double = 2,
  2312. otl_var_float = 3,
  2313. otl_var_int = 4,
  2314. otl_var_unsigned_int = 5,
  2315. otl_var_short = 6,
  2316. otl_var_long_int = 7,
  2317. otl_var_timestamp = 8,
  2318. otl_var_varchar_long = 9,
  2319. otl_var_raw_long = 10,
  2320. otl_var_clob = 11,
  2321. otl_var_blob = 12,
  2322. otl_var_refcur = 13,
  2323. otl_var_long_string = 15,
  2324. otl_var_db2time = 16,
  2325. otl_var_db2date = 17,
  2326. otl_var_tz_timestamp = 18,
  2327. otl_var_ltz_timestamp = 19,
  2328. otl_var_bigint = 20,
  2329. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  2330. otl_var_nchar = 21,
  2331. otl_var_nclob = 22,
  2332. #else
  2333. #endif
  2334. otl_var_raw = 23,
  2335. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  2336. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  2337. otl_var_numeric_type_1 = 24,
  2338. #endif
  2339. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  2340. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  2341. otl_var_numeric_type_2 = 25,
  2342. #endif
  2343. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  2344. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  2345. otl_var_numeric_type_3 = 26,
  2346. #endif
  2347. otl_var_ubigint = 27,
  2348. otl_var_bfloat = 28,
  2349. otl_var_bdouble = 29,
  2350. otl_var_lob_stream = 100
  2351. #if defined(OTL_ORA_SDO_GEOMETRY)
  2352. ,otl_var_sdo_geometry = 101
  2353. #endif
  2354. };
  2355. #else
  2356. typedef unsigned char otl_var_enum;
  2357. const otl_var_enum otl_var_none = 0;
  2358. const otl_var_enum otl_var_char = 1;
  2359. const otl_var_enum otl_var_double = 2;
  2360. const otl_var_enum otl_var_float = 3;
  2361. const otl_var_enum otl_var_int = 4;
  2362. const otl_var_enum otl_var_unsigned_int = 5;
  2363. const otl_var_enum otl_var_short = 6;
  2364. const otl_var_enum otl_var_long_int = 7;
  2365. const otl_var_enum otl_var_timestamp = 8;
  2366. const otl_var_enum otl_var_varchar_long = 9;
  2367. const otl_var_enum otl_var_raw_long = 10;
  2368. const otl_var_enum otl_var_clob = 11;
  2369. const otl_var_enum otl_var_blob = 12;
  2370. const otl_var_enum otl_var_refcur = 13;
  2371. const otl_var_enum otl_var_long_string = 15;
  2372. const otl_var_enum otl_var_db2time = 16;
  2373. const otl_var_enum otl_var_db2date = 17;
  2374. const otl_var_enum otl_var_tz_timestamp = 18;
  2375. const otl_var_enum otl_var_ltz_timestamp = 19;
  2376. const otl_var_enum otl_var_bigint = 20;
  2377. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  2378. const otl_var_enum otl_var_nchar = 21;
  2379. const otl_var_enum otl_var_nclob = 22;
  2380. #else
  2381. #endif
  2382. const otl_var_enum otl_var_raw = 23;
  2383. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  2384. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  2385. const otl_var_enum otl_var_numeric_type_1 = 24;
  2386. #endif
  2387. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  2388. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  2389. const otl_var_enum otl_var_numeric_type_2 = 25;
  2390. #endif
  2391. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  2392. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  2393. const otl_var_enum otl_var_numeric_type_3 = 26;
  2394. #endif
  2395. const otl_var_enum otl_var_ubigint = 27;
  2396. const otl_var_enum otl_var_bfloat = 28;
  2397. const otl_var_enum otl_var_bdouble = 29;
  2398. const otl_var_enum otl_var_lob_stream = 100;
  2399. #if defined(OTL_ORA_SDO_GEOMETRY)
  2400. const otl_var_enum otl_var_sdo_geometry = 101;
  2401. #endif
  2402. #endif
  2403. const int otl_bigint_str_size = 40;
  2404. const int otl_ubigint_str_size = 40;
  2405. #if defined(OTL_NUMERIC_TYPE_1_STR_SIZE)
  2406. const int otl_numeric_type_1_str_size = OTL_NUMERIC_TYPE_1_STR_SIZE;
  2407. #else
  2408. const int otl_numeric_type_1_str_size = 60;
  2409. #endif
  2410. #if defined(OTL_NUMERIC_TYPE_2_STR_SIZE)
  2411. const int otl_numeric_type_2_str_size = OTL_NUMERIC_TYPE_2_STR_SIZE;
  2412. #else
  2413. const int otl_numeric_type_2_str_size = 60;
  2414. #endif
  2415. #if defined(OTL_NUMERIC_TYPE_3_STR_SIZE)
  2416. const int otl_numeric_type_3_str_size = OTL_NUMERIC_TYPE_3_STR_SIZE;
  2417. #else
  2418. const int otl_numeric_type_3_str_size = 60;
  2419. #endif
  2420. typedef unsigned char otl_sql_exec_from_enum;
  2421. const otl_sql_exec_from_enum otl_sql_exec_from_cursor_class = 0;
  2422. const otl_sql_exec_from_enum otl_sql_exec_from_select_cursor_class = 1;
  2423. #if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON)
  2424. #include <type_traits>
  2425. #include <variant>
  2426. template<const size_t I, typename Variant>
  2427. struct otl_convert_type_to_code_helper{
  2428. static int convert(){
  2429. using currType=typename std::variant_alternative<I,Variant>::type;
  2430. if constexpr(std::is_same_v<int,currType>)
  2431. return otl_var_int;
  2432. if constexpr(std::is_same_v<double,currType>)
  2433. return otl_var_double;
  2434. if constexpr(std::is_same_v<float,currType>)
  2435. return otl_var_float;
  2436. if constexpr(std::is_same_v<unsigned int,currType>)
  2437. return otl_var_unsigned_int;
  2438. if constexpr(std::is_same_v<short int,currType>)
  2439. return otl_var_short;
  2440. if constexpr(std::is_same_v<long int,currType>)
  2441. return otl_var_long_int;
  2442. if constexpr(std::is_same_v<otl_datetime,currType>)
  2443. return otl_var_timestamp;
  2444. #if defined(OTL_BIGINT)
  2445. if constexpr(std::is_same_v<OTL_BIGINT,currType>)
  2446. return otl_var_bigint;
  2447. #endif
  2448. #if defined(OTL_UBIGINT)
  2449. if constexpr(std::is_same_v<OTL_UBIGINT,currType>)
  2450. return otl_var_ubigint;
  2451. #endif
  2452. }
  2453. };
  2454. template<typename streamType, const size_t N, typename Variant>
  2455. struct otl_variant_helper{
  2456. static void write(streamType& s, const Variant& v, bool& value_written){
  2457. otl_variant_helper<streamType,N-1,Variant>::write(s,v,value_written);
  2458. if(value_written)return;
  2459. otl_var_desc* vd=s.describe_next_in_var();
  2460. if(vd &&
  2461. vd->ftype==otl_convert_type_to_code_helper<N-1,Variant>::convert() &&
  2462. v.index()==N-1){
  2463. // write the value only when the bind variable is of the same
  2464. // type and when the variant's currently held alternative's index
  2465. // is N-1
  2466. s<<std::get<N-1>(v);
  2467. value_written=true;
  2468. }
  2469. }
  2470. static void read(streamType& s, Variant& v, bool& value_read){
  2471. otl_variant_helper<streamType,N-1,Variant>::read(s,v,value_read);
  2472. if(value_read)return;
  2473. otl_var_desc* vd=s.describe_next_out_var();
  2474. if(vd && vd->ftype==otl_convert_type_to_code_helper<N-1,Variant>::convert()){
  2475. using currType=typename std::variant_alternative<N-1,Variant>::type;
  2476. currType val;
  2477. s>>val;
  2478. v=val;
  2479. value_read=true;
  2480. }
  2481. }
  2482. };
  2483. template<typename streamType, typename Variant>
  2484. struct otl_variant_helper<streamType,1,Variant>{
  2485. static void write(streamType& s, const Variant& v, bool& value_written) {
  2486. value_written=false;
  2487. otl_var_desc* vd=s.describe_next_in_var();
  2488. if(vd &&
  2489. vd->ftype==otl_convert_type_to_code_helper<0,Variant>::convert() &&
  2490. v.index()==0){
  2491. // write the value only when the bind variable is of the same
  2492. // type and when the variant's currently held alternative's
  2493. // index is 0
  2494. s<<std::get<0>(v);
  2495. value_written=true;
  2496. }
  2497. }
  2498. static void read(streamType& s, Variant& v, bool& value_read) {
  2499. value_read=false;
  2500. otl_var_desc* vd=s.describe_next_out_var();
  2501. if(vd && vd->ftype==otl_convert_type_to_code_helper<0,Variant>::convert()){
  2502. using currType=typename std::variant_alternative<0,Variant>::type;
  2503. currType val;
  2504. s>>val;
  2505. v=val;
  2506. value_read=true;
  2507. }
  2508. }
  2509. };
  2510. #endif
  2511. class otl_long_string {
  2512. public:
  2513. unsigned char *v;
  2514. otl_long_string(const int buffer_size = otl_short_int_max,
  2515. const int input_length = 0)
  2516. : v(nullptr), length(0), extern_buffer_flag(0), buf_size(0),
  2517. this_is_last_piece_(false), unicode_flag_(false) {
  2518. this_is_last_piece_ = false;
  2519. if (buffer_size == 0) {
  2520. v = nullptr;
  2521. length = 0;
  2522. extern_buffer_flag = 0;
  2523. } else {
  2524. extern_buffer_flag = 0;
  2525. length = input_length;
  2526. buf_size = buffer_size;
  2527. v = new unsigned char[OTL_SCAST(size_t,buffer_size + 1)];
  2528. memset(v, 0, OTL_SCAST(unsigned int, buffer_size+1));
  2529. }
  2530. }
  2531. otl_long_string(const void *external_buffer, const int buffer_size,
  2532. const int input_length = 0)
  2533. : v(OTL_RCAST(unsigned char *, OTL_CCAST(void *, external_buffer))),
  2534. length(input_length), extern_buffer_flag(1), buf_size(buffer_size),
  2535. this_is_last_piece_(false), unicode_flag_(false) {}
  2536. otl_long_string &operator=(const otl_long_string &s) {
  2537. this_is_last_piece_ = s.this_is_last_piece_;
  2538. if (s.extern_buffer_flag) {
  2539. if (!extern_buffer_flag)
  2540. delete[] v;
  2541. v = s.v;
  2542. length = s.length;
  2543. extern_buffer_flag = s.extern_buffer_flag;
  2544. buf_size = s.buf_size;
  2545. } else {
  2546. if (extern_buffer_flag) {
  2547. v = new unsigned char[OTL_SCAST(size_t,s.buf_size + 1)];
  2548. buf_size = s.buf_size;
  2549. } else if (buf_size < s.buf_size) {
  2550. delete[] v;
  2551. v = new unsigned char[OTL_SCAST(size_t,s.buf_size + 1)];
  2552. buf_size = s.buf_size;
  2553. }
  2554. length = s.length;
  2555. extern_buffer_flag = s.extern_buffer_flag;
  2556. memcpy(v, s.v, OTL_SCAST(unsigned int, length));
  2557. if (length < buf_size && s.v[length] == 0)
  2558. v[length] = 0;
  2559. }
  2560. return *this;
  2561. }
  2562. otl_long_string(const otl_long_string &s)
  2563. : v(nullptr), length(s.length), extern_buffer_flag(s.extern_buffer_flag),
  2564. buf_size(s.buf_size), this_is_last_piece_(s.this_is_last_piece_),
  2565. unicode_flag_(false) {
  2566. if (s.extern_buffer_flag)
  2567. v = s.v;
  2568. else {
  2569. v = new unsigned char[OTL_SCAST(size_t,buf_size + 1)];
  2570. memcpy(v, s.v, OTL_SCAST(unsigned int, length));
  2571. if (length < buf_size && s.v[length] == 0)
  2572. v[length] = 0;
  2573. }
  2574. }
  2575. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  2576. otl_long_string &operator=(otl_long_string &&s) OTL_ANSI_CPP_11_NOEXCEPT {
  2577. if (!extern_buffer_flag)
  2578. delete[] v;
  2579. this_is_last_piece_ = s.this_is_last_piece_;
  2580. length = s.length;
  2581. extern_buffer_flag = s.extern_buffer_flag;
  2582. v = s.v;
  2583. s.v = nullptr;
  2584. s.length = 0;
  2585. s.buf_size = 0;
  2586. return *this;
  2587. }
  2588. otl_long_string(otl_long_string &&s) OTL_ANSI_CPP_11_NOEXCEPT
  2589. : v(s.v),
  2590. length(s.length),
  2591. extern_buffer_flag(s.extern_buffer_flag),
  2592. buf_size(s.buf_size),
  2593. this_is_last_piece_(s.this_is_last_piece_),
  2594. unicode_flag_(false) {
  2595. s.v = nullptr;
  2596. s.length = 0;
  2597. s.buf_size = 0;
  2598. }
  2599. #endif
  2600. virtual ~otl_long_string() {
  2601. if (!extern_buffer_flag)
  2602. delete[] v;
  2603. }
  2604. void set_len(const int alen = 0) { length = alen; }
  2605. int len(void) const { return length; }
  2606. void set_last_piece(const bool this_is_last_piece = false) {
  2607. this_is_last_piece_ = this_is_last_piece;
  2608. }
  2609. bool is_last_piece() const { return this_is_last_piece_; }
  2610. unsigned char &operator[](int ndx) { return v[ndx]; }
  2611. const unsigned char &operator[](int ndx) const { return v[ndx]; }
  2612. virtual void null_terminate_string(const int alen) { (*this)[alen] = 0; }
  2613. int get_buf_size() const { return buf_size; }
  2614. int get_extern_buffer_flag() const { return extern_buffer_flag; }
  2615. bool get_unicode_flag() const { return unicode_flag_; }
  2616. protected:
  2617. int length;
  2618. int extern_buffer_flag;
  2619. int buf_size;
  2620. bool this_is_last_piece_;
  2621. bool unicode_flag_;
  2622. };
  2623. #if defined(OTL_UNICODE)
  2624. class otl_long_unicode_string : public otl_long_string {
  2625. public:
  2626. otl_long_unicode_string(const int buffer_size = otl_short_int_max,
  2627. const int input_length = 0)
  2628. : otl_long_string(0, 0) {
  2629. unicode_flag_ = true;
  2630. extern_buffer_flag = 0;
  2631. length = input_length;
  2632. buf_size = buffer_size;
  2633. v = new unsigned char
  2634. [OTL_SCAST(size_t, buffer_size + 1) * sizeof(OTL_WCHAR)];
  2635. memset(v, 0, OTL_SCAST(size_t, buffer_size) * sizeof(OTL_WCHAR));
  2636. }
  2637. otl_long_unicode_string(const void *external_buffer, const int buffer_size,
  2638. const int input_length = 0)
  2639. : otl_long_string(external_buffer, buffer_size, input_length) {
  2640. unicode_flag_ = true;
  2641. extern_buffer_flag = 1;
  2642. length = input_length;
  2643. buf_size = buffer_size;
  2644. v = OTL_RCAST(unsigned char *, OTL_CCAST(void *, external_buffer));
  2645. }
  2646. otl_long_unicode_string(const otl_long_unicode_string &s)
  2647. : otl_long_string(0, 0) {
  2648. this->unicode_flag_ = true;
  2649. this->buf_size = s.buf_size;
  2650. this->this_is_last_piece_ = s.this_is_last_piece_;
  2651. this->extern_buffer_flag = s.extern_buffer_flag;
  2652. this->v = nullptr;
  2653. this->length = s.length;
  2654. if (s.extern_buffer_flag)
  2655. v = s.v;
  2656. else {
  2657. v = new unsigned char
  2658. [OTL_SCAST(size_t, buf_size + 1) * sizeof(OTL_WCHAR)];
  2659. memcpy(v, s.v, OTL_SCAST(size_t, length) * sizeof(OTL_WCHAR));
  2660. if (length < buf_size && s.v[length] == 0)
  2661. (*this)[length] = 0;
  2662. }
  2663. }
  2664. otl_long_unicode_string &operator=(const otl_long_unicode_string &s) {
  2665. this_is_last_piece_ = s.this_is_last_piece_;
  2666. if (s.extern_buffer_flag) {
  2667. if (!extern_buffer_flag)
  2668. delete[] v;
  2669. v = s.v;
  2670. length = s.length;
  2671. extern_buffer_flag = s.extern_buffer_flag;
  2672. buf_size = s.buf_size;
  2673. } else {
  2674. if (extern_buffer_flag) {
  2675. v = new unsigned char
  2676. [OTL_SCAST(size_t, s.buf_size + 1) * sizeof(OTL_WCHAR)];
  2677. buf_size = s.buf_size;
  2678. } else if (buf_size < s.buf_size) {
  2679. delete[] v;
  2680. v = new unsigned char
  2681. [OTL_SCAST(size_t, s.buf_size + 1) * sizeof(OTL_WCHAR)];
  2682. buf_size = s.buf_size;
  2683. }
  2684. length = s.length;
  2685. extern_buffer_flag = s.extern_buffer_flag;
  2686. memcpy(v, s.v, OTL_SCAST(size_t, length) * sizeof(OTL_WCHAR));
  2687. if (length < buf_size && s.v[length] == 0)
  2688. (*this)[length] = 0;
  2689. }
  2690. return *this;
  2691. }
  2692. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  2693. otl_long_unicode_string(otl_long_unicode_string &&s) OTL_ANSI_CPP_11_NOEXCEPT
  2694. : otl_long_string(0, 0) {
  2695. unicode_flag_ = true;
  2696. buf_size = s.buf_size;
  2697. this_is_last_piece_ = s.this_is_last_piece_;
  2698. extern_buffer_flag = s.extern_buffer_flag;
  2699. length = s.length;
  2700. v = s.v;
  2701. s.v = nullptr;
  2702. s.buf_size = 0;
  2703. s.length = 0;
  2704. }
  2705. otl_long_unicode_string &
  2706. operator=(otl_long_unicode_string &&s) OTL_ANSI_CPP_11_NOEXCEPT {
  2707. this_is_last_piece_ = s.this_is_last_piece_;
  2708. if (!extern_buffer_flag)
  2709. delete[] v;
  2710. v = s.v;
  2711. length = s.length;
  2712. extern_buffer_flag = s.extern_buffer_flag;
  2713. buf_size = s.buf_size;
  2714. s.v = nullptr;
  2715. s.buf_size = 0;
  2716. s.length = 0;
  2717. return *this;
  2718. }
  2719. #endif
  2720. virtual ~otl_long_unicode_string() {}
  2721. OTL_CHAR &operator[](int ndx) { return OTL_RCAST(OTL_CHAR *, v)[ndx]; }
  2722. const OTL_CHAR &operator[](int ndx) const { return OTL_RCAST(OTL_CHAR *, v)[ndx]; }
  2723. virtual void null_terminate_string(const int alen) { (*this)[alen] = 0; }
  2724. };
  2725. #endif
  2726. const int const_STD_CHAR_ARRAY_code=200;
  2727. const int const_STD_UNICODE_CHAR_ARRAY_code=201;
  2728. inline const char *otl_var_type_name(const int ftype) {
  2729. const char *const_STD_CHAR_ARRAY = "std::array<char,...>";
  2730. const char *const_STD_UNICODE_CHAR_ARRAY = "std::array<char16_t,...>";
  2731. const char *const_CHAR = "CHAR";
  2732. const char *const_DOUBLE = "DOUBLE";
  2733. const char *const_FLOAT = "FLOAT";
  2734. const char *const_BDOUBLE = "BINARY_DOUBLE";
  2735. const char *const_BFLOAT = "BINARY_FLOAT";
  2736. const char *const_INT = "INT";
  2737. const char *const_UNSIGNED_INT = "UNSIGNED INT";
  2738. const char *const_SHORT_INT = "SHORT INT";
  2739. const char *const_LONG_INT = "LONG INT";
  2740. const char *const_TIMESTAMP = "TIMESTAMP";
  2741. const char *const_DB2DATE = "DB2DATE";
  2742. const char *const_DB2TIME = "DB2TIME";
  2743. const char *const_TZ_TIMESTAMP = "TIMESTAMP WITH TIME ZONE";
  2744. const char *const_LTZ_TIMESTAMP = "TIMESTAMP WITH LOCAL TIME ZONE";
  2745. const char *const_BIGINT = "BIGINT";
  2746. const char *const_UBIGINT = "UBIGINT";
  2747. const char *const_VARCHAR_LONG = "VARCHAR LONG";
  2748. const char *const_RAW_LONG = "RAW LONG";
  2749. const char *const_CLOB = "CLOB";
  2750. const char *const_BLOB = "BLOB";
  2751. const char *const_RAW = "RAW";
  2752. const char *const_UNKNOWN = "UNKNOWN";
  2753. const char *const_LONG_STRING = "otl_long_string()";
  2754. const char *const_LOB_STREAM = "otl_lob_stream*&";
  2755. const char *const_USER_DEFINED =
  2756. "User-defined type (object type, VARRAY, Nested Table)";
  2757. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  2758. const char *const_NCHAR = "NCHAR";
  2759. const char *const_NCLOB = "NCLOB";
  2760. #endif
  2761. switch (ftype) {
  2762. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  2763. case otl_var_nchar:
  2764. return const_NCHAR;
  2765. case otl_var_nclob:
  2766. return const_NCLOB;
  2767. #endif
  2768. case otl_var_char:
  2769. return const_CHAR;
  2770. case otl_var_double:
  2771. return const_DOUBLE;
  2772. case otl_var_float:
  2773. return const_FLOAT;
  2774. case otl_var_bfloat:
  2775. return const_BFLOAT;
  2776. case otl_var_bdouble:
  2777. return const_BDOUBLE;
  2778. case otl_var_int:
  2779. return const_INT;
  2780. case otl_var_unsigned_int:
  2781. return const_UNSIGNED_INT;
  2782. case otl_var_short:
  2783. return const_SHORT_INT;
  2784. case otl_var_long_int:
  2785. return const_LONG_INT;
  2786. case otl_var_timestamp:
  2787. return const_TIMESTAMP;
  2788. case otl_var_db2date:
  2789. return const_DB2DATE;
  2790. case otl_var_db2time:
  2791. return const_DB2TIME;
  2792. case otl_var_tz_timestamp:
  2793. return const_TZ_TIMESTAMP;
  2794. case otl_var_ltz_timestamp:
  2795. return const_LTZ_TIMESTAMP;
  2796. case otl_var_bigint:
  2797. return const_BIGINT;
  2798. case otl_var_ubigint:
  2799. return const_UBIGINT;
  2800. case otl_var_varchar_long:
  2801. return const_VARCHAR_LONG;
  2802. case otl_var_raw_long:
  2803. return const_RAW_LONG;
  2804. case otl_var_clob:
  2805. return const_CLOB;
  2806. case otl_var_blob:
  2807. return const_BLOB;
  2808. case otl_var_raw:
  2809. return const_RAW;
  2810. case otl_var_long_string:
  2811. return const_LONG_STRING;
  2812. case otl_var_lob_stream:
  2813. return const_LOB_STREAM;
  2814. case 108:
  2815. return const_USER_DEFINED;
  2816. case const_STD_CHAR_ARRAY_code:
  2817. return const_STD_CHAR_ARRAY;
  2818. case const_STD_UNICODE_CHAR_ARRAY_code:
  2819. return const_STD_UNICODE_CHAR_ARRAY;
  2820. default:
  2821. return const_UNKNOWN;
  2822. }
  2823. }
  2824. inline void otl_var_info_var(const char *name, const int ftype,
  2825. const int type_code, char *var_info,
  2826. const size_t var_info_sz) {
  2827. char buf1[128];
  2828. char buf2[128];
  2829. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  2830. OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code));
  2831. OTL_STRCPY_S(var_info, var_info_sz, "Variable: ");
  2832. OTL_STRCAT_S(var_info, var_info_sz, name);
  2833. OTL_STRCAT_S(var_info, var_info_sz, "<");
  2834. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  2835. OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in operator <</>>: ");
  2836. OTL_STRCAT_S(var_info, var_info_sz, buf2);
  2837. }
  2838. inline void otl_var_info_var2(const char *name, const int ftype, char *var_info,
  2839. const size_t var_info_sz) {
  2840. char buf1[128];
  2841. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  2842. OTL_STRCPY_S(var_info, var_info_sz, "Variable: ");
  2843. OTL_STRCPY_S(var_info, var_info_sz, name);
  2844. OTL_STRCAT_S(var_info, var_info_sz, "<");
  2845. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  2846. OTL_STRCAT_S(var_info, var_info_sz, ">");
  2847. }
  2848. inline void otl_var_info_var3(const char *name, const int ftype,
  2849. const int type_code, char *var_info,
  2850. const size_t var_info_sz) {
  2851. char buf1[128];
  2852. char buf2[128];
  2853. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  2854. OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code));
  2855. OTL_STRCPY_S(var_info, var_info_sz, "Variable: ");
  2856. OTL_STRCAT_S(var_info, var_info_sz, name);
  2857. OTL_STRCAT_S(var_info, var_info_sz, "<");
  2858. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  2859. OTL_STRCAT_S(var_info, var_info_sz,
  2860. ">, datatype in otl_stream_read_iterator::get(): ");
  2861. OTL_STRCAT_S(var_info, var_info_sz, buf2);
  2862. }
  2863. inline void otl_var_info_var4(const char *name, const int ftype,
  2864. const int type_code, char *var_info,
  2865. const size_t var_info_sz) {
  2866. char buf1[128];
  2867. char buf2[128];
  2868. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  2869. OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code));
  2870. OTL_STRCPY_S(var_info, var_info_sz, "Variable: ");
  2871. OTL_STRCAT_S(var_info, var_info_sz, name);
  2872. OTL_STRCAT_S(var_info, var_info_sz, "<");
  2873. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  2874. OTL_STRCAT_S(var_info, var_info_sz,
  2875. ">, datatype in otl_stream_read_iterator::get(): ");
  2876. OTL_STRCAT_S(var_info, var_info_sz, buf2);
  2877. }
  2878. inline void otl_strcpy(unsigned char *trg, unsigned char *src, int &overflow,
  2879. const int inp_size = 0, const int actual_inp_size = -1) {
  2880. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2881. const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src);
  2882. int out_size = 0;
  2883. overflow = 0;
  2884. if (actual_inp_size != -1) {
  2885. while (out_size < inp_size - 1 && out_size < actual_inp_size) {
  2886. *c1++ = *c2++;
  2887. ++out_size;
  2888. }
  2889. *c1 = 0;
  2890. if (out_size == inp_size - 1 && out_size < actual_inp_size)
  2891. overflow = 1;
  2892. } else {
  2893. while (*c2 && out_size < inp_size - 1) {
  2894. *c1++ = *c2++;
  2895. ++out_size;
  2896. }
  2897. *c1 = 0;
  2898. if (*c2 && out_size == inp_size - 1)
  2899. overflow = 1;
  2900. }
  2901. }
  2902. #if defined(OTL_UNICODE) || (defined(_MSC_VER) && (_MSC_VER >= 1400))
  2903. inline void otl_strcpy(unsigned char *trg, const unsigned char *src) {
  2904. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2905. const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src);
  2906. while (*c2) {
  2907. *c1++ = *c2++;
  2908. }
  2909. *c1 = 0;
  2910. }
  2911. #else
  2912. inline void otl_strcpy(unsigned char *trg, const unsigned char *src) {
  2913. strcpy(OTL_RCAST(char *, trg), OTL_RCAST(const char *, src));
  2914. }
  2915. #endif
  2916. inline void otl_strcat(char *trg, const char *src) {
  2917. while (*trg)
  2918. ++trg;
  2919. while (*src) {
  2920. *trg = *src;
  2921. ++trg;
  2922. ++src;
  2923. }
  2924. *trg = 0;
  2925. }
  2926. #if defined(OTL_UNICODE) && !defined(OTL_ODBC)
  2927. inline void otl_strcpy2(unsigned char *trg, const unsigned char *src,
  2928. const int max_src_len) {
  2929. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2930. const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src);
  2931. int src_len = OTL_SCAST(int, *OTL_SCAST(const unsigned short *, c2));
  2932. int len = 0;
  2933. ++c2;
  2934. while (*c2 && len < max_src_len && len < src_len) {
  2935. *c1++ = *c2++;
  2936. ++len;
  2937. }
  2938. *c1 = 0;
  2939. #else
  2940. inline void otl_strcpy2(unsigned char *trg, const unsigned char *src,
  2941. const int /* max_src_len */
  2942. ) {
  2943. otl_strcpy(trg, src);
  2944. #endif
  2945. }
  2946. #if defined(OTL_UNICODE)
  2947. inline void otl_memcpy(unsigned char *trg, unsigned char *src,
  2948. const int src_len, const int ftype) {
  2949. if (ftype == otl_var_raw_long || ftype == otl_var_raw) {
  2950. memcpy(trg, src, OTL_SCAST(size_t, src_len));
  2951. return;
  2952. }
  2953. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2954. OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src);
  2955. int len = 0;
  2956. while (len < src_len) {
  2957. *c1++ = *c2++;
  2958. ++len;
  2959. }
  2960. #else
  2961. inline void otl_memcpy(unsigned char *trg, unsigned char *src,
  2962. const int src_len, const int /* ftype */
  2963. ) {
  2964. memcpy(trg, src, OTL_SCAST(unsigned int, src_len));
  2965. #endif
  2966. }
  2967. #if defined(OTL_UNICODE) && !defined(OTL_ODBC)
  2968. inline void otl_strcpy3(unsigned char *trg, unsigned char *src,
  2969. const int max_src_len, int &overflow,
  2970. const int inp_size = 0) {
  2971. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2972. OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src);
  2973. int len = 0;
  2974. int src_len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c2));
  2975. ++c2;
  2976. int out_size = 0;
  2977. overflow = 0;
  2978. while (len < src_len && len < max_src_len && out_size < inp_size - 1) {
  2979. *c1++ = *c2++;
  2980. ++out_size;
  2981. ++len;
  2982. }
  2983. *c1 = 0;
  2984. if (len < src_len && out_size == inp_size - 1)
  2985. overflow = 1;
  2986. #else
  2987. inline void otl_strcpy3(unsigned char *trg, unsigned char *src,
  2988. const int /* max_src_len */, int &overflow,
  2989. const int inp_size = 0) {
  2990. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  2991. OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src);
  2992. int out_size = 0;
  2993. overflow = 0;
  2994. while (*c2 && out_size < inp_size - 1) {
  2995. *c1++ = *c2++;
  2996. ++out_size;
  2997. }
  2998. *c1 = 0;
  2999. if (*c2 && out_size == inp_size - 1)
  3000. overflow = 1;
  3001. #endif
  3002. }
  3003. inline void otl_strcpy4(unsigned char *trg, unsigned char *src, int &overflow,
  3004. const int inp_size = 0,
  3005. const int actual_inp_size = -1) {
  3006. #if defined(OTL_UNICODE) && !defined(OTL_ODBC)
  3007. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  3008. OTL_CHAR *bc1 = c1;
  3009. ++c1;
  3010. OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src);
  3011. int out_size = 0;
  3012. overflow = 0;
  3013. if (actual_inp_size != -1) {
  3014. while (out_size < inp_size - 1 && out_size < actual_inp_size) {
  3015. *c1++ = *c2++;
  3016. ++out_size;
  3017. }
  3018. *OTL_RCAST(unsigned short *, bc1) = OTL_SCAST(unsigned short, out_size);
  3019. if (out_size == inp_size - 1 && out_size < actual_inp_size)
  3020. overflow = 1;
  3021. } else {
  3022. while (*c2 && out_size < inp_size - 1) {
  3023. *c1++ = *c2++;
  3024. ++out_size;
  3025. }
  3026. *OTL_RCAST(unsigned short *, bc1) = OTL_SCAST(unsigned short, out_size);
  3027. if (*c2 && out_size == inp_size - 1)
  3028. overflow = 1;
  3029. }
  3030. #else
  3031. OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg);
  3032. OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src);
  3033. int out_size = 0;
  3034. overflow = 0;
  3035. if (actual_inp_size != -1) {
  3036. while (out_size < inp_size - 1 && out_size < actual_inp_size) {
  3037. *c1++ = *c2++;
  3038. ++out_size;
  3039. }
  3040. *c1 = 0;
  3041. if (out_size == inp_size - 1 && out_size < actual_inp_size)
  3042. overflow = 1;
  3043. } else {
  3044. while (*c2 && out_size < inp_size - 1) {
  3045. *c1++ = *c2++;
  3046. ++out_size;
  3047. }
  3048. *c1 = 0;
  3049. if (*c2 && out_size == inp_size - 1)
  3050. overflow = 1;
  3051. }
  3052. #endif
  3053. }
  3054. inline char *otl_itoa(int i, char *a) {
  3055. const char *digits = "0123456789";
  3056. int n = i;
  3057. int k;
  3058. char buf[64];
  3059. char *c = buf;
  3060. char *c1 = a;
  3061. int klen = 0;
  3062. char digit = ' ';
  3063. bool negative = false;
  3064. if (n < 0) {
  3065. n = -n;
  3066. negative = true;
  3067. }
  3068. do {
  3069. if (n >= 10)
  3070. k = n % 10;
  3071. else
  3072. k = n;
  3073. digit = digits[k];
  3074. *c = digit;
  3075. ++c;
  3076. ++klen;
  3077. n = n / 10;
  3078. } while (n != 0);
  3079. *c = 0;
  3080. if (negative) {
  3081. *c1 = '-';
  3082. ++c1;
  3083. }
  3084. for (int j = klen - 1; j >= 0; --j) {
  3085. *c1 = buf[j];
  3086. ++c1;
  3087. }
  3088. *c1 = 0;
  3089. return c1;
  3090. }
  3091. inline void otl_var_info_col(const int pos, const int ftype,
  3092. const int type_code, char *var_info,
  3093. const size_t var_info_sz) {
  3094. char buf1[128];
  3095. char buf2[128];
  3096. char name[128];
  3097. otl_itoa(pos, name);
  3098. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  3099. OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code));
  3100. OTL_STRCPY_S(var_info, var_info_sz, "Column: ");
  3101. OTL_STRCAT_S(var_info, var_info_sz, name);
  3102. OTL_STRCAT_S(var_info, var_info_sz, "<");
  3103. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  3104. OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in operator <</>>: ");
  3105. OTL_STRCAT_S(var_info, var_info_sz, buf2);
  3106. }
  3107. inline void otl_var_info_col2(const int pos, const int ftype, char *var_info,
  3108. const size_t var_info_sz) {
  3109. char buf1[128];
  3110. char name[128];
  3111. otl_itoa(pos, name);
  3112. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  3113. OTL_STRCPY_S(var_info, var_info_sz, "Column: ");
  3114. OTL_STRCAT_S(var_info, var_info_sz, name);
  3115. OTL_STRCAT_S(var_info, var_info_sz, "<");
  3116. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  3117. OTL_STRCAT_S(var_info, var_info_sz, ">");
  3118. }
  3119. inline void otl_var_info_col3(const int pos, const int ftype,
  3120. const char *col_name, char *var_info,
  3121. const size_t var_info_sz) {
  3122. char buf1[128];
  3123. char name[128];
  3124. otl_itoa(pos, name);
  3125. OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype));
  3126. OTL_STRCPY_S(var_info, var_info_sz, "Column: ");
  3127. OTL_STRCAT_S(var_info, var_info_sz, name);
  3128. OTL_STRCAT_S(var_info, var_info_sz, " / ");
  3129. OTL_STRCAT_S(var_info, var_info_sz, col_name);
  3130. OTL_STRCAT_S(var_info, var_info_sz, " <");
  3131. OTL_STRCAT_S(var_info, var_info_sz, buf1);
  3132. OTL_STRCAT_S(var_info, var_info_sz, ">");
  3133. }
  3134. class otl_pl_tab_generic {
  3135. public:
  3136. otl_pl_tab_generic()
  3137. : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0),
  3138. vtype(0) {}
  3139. virtual ~otl_pl_tab_generic() {}
  3140. unsigned char *val(int ndx = 0) { return p_v + (ndx * elem_size); }
  3141. int is_null(int ndx = 0) { return p_null[ndx] != 0; }
  3142. void set_null(int ndx = 0) { p_null[ndx] = 1; }
  3143. void set_non_null(int ndx = 0) { p_null[ndx] = 0; }
  3144. void init_generic(void) {
  3145. int i;
  3146. memset(p_v, 0, OTL_SCAST(size_t, elem_size * tab_len));
  3147. for (i = 0; i < tab_len; ++i)
  3148. p_null[i] = 0;
  3149. }
  3150. int len() { return tab_len; }
  3151. void set_len(int new_len = 0) { tab_len = new_len; }
  3152. int get_vtype() const { return vtype; }
  3153. int get_elem_size() const { return elem_size; }
  3154. int get_tab_size() const { return tab_size; }
  3155. unsigned char *get_p_v() { return p_v; }
  3156. protected:
  3157. unsigned char *p_v;
  3158. short *p_null;
  3159. int elem_size;
  3160. int tab_size;
  3161. int tab_len;
  3162. int vtype;
  3163. private:
  3164. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3165. public:
  3166. otl_pl_tab_generic(const otl_pl_tab_generic &) = delete;
  3167. otl_pl_tab_generic &operator=(const otl_pl_tab_generic &) = delete;
  3168. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3169. otl_pl_tab_generic(otl_pl_tab_generic &&) = delete;
  3170. otl_pl_tab_generic &operator=(otl_pl_tab_generic &&) = delete;
  3171. #endif
  3172. private:
  3173. #else
  3174. otl_pl_tab_generic(const otl_pl_tab_generic &)
  3175. : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0),
  3176. vtype(0) {}
  3177. otl_pl_tab_generic &operator=(const otl_pl_tab_generic &) { return *this; }
  3178. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3179. otl_pl_tab_generic(otl_pl_tab_generic &&)
  3180. : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0),
  3181. vtype(0) {}
  3182. otl_pl_tab_generic &operator=(otl_pl_tab_generic &&) { return *this; }
  3183. #endif
  3184. #endif
  3185. };
  3186. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  3187. template <OTL_TYPE_NAME T, const int T_type>
  3188. inline int otl_numeric_convert_T(const int ftype, const void *val, T &n) {
  3189. if (ftype == T_type) {
  3190. n = *OTL_RCAST(T *, OTL_CCAST(void *, val));
  3191. return 1;
  3192. } else
  3193. return 0;
  3194. }
  3195. template <OTL_TYPE_NAME T>
  3196. inline int otl_numeric_convert_T2(const int ftype, const void *val, T &n) {
  3197. int rc = 1;
  3198. switch (ftype) {
  3199. case otl_var_double:
  3200. n = OTL_PCONV(T, double, val);
  3201. break;
  3202. case otl_var_short:
  3203. n = OTL_PCONV(T, short, val);
  3204. break;
  3205. case otl_var_int:
  3206. n = OTL_PCONV(T, int, val);
  3207. break;
  3208. case otl_var_unsigned_int:
  3209. n = OTL_PCONV(T, unsigned int, val);
  3210. break;
  3211. case otl_var_long_int:
  3212. n = OTL_PCONV(T, long int, val);
  3213. break;
  3214. case otl_var_float:
  3215. n = OTL_PCONV(T, float, val);
  3216. break;
  3217. case otl_var_bfloat:
  3218. n = OTL_PCONV(T, float, val);
  3219. break;
  3220. case otl_var_bdouble:
  3221. n = OTL_PCONV(T, double, val);
  3222. break;
  3223. #if defined(OTL_BIGINT)
  3224. case otl_var_bigint:
  3225. n = OTL_PCONV(T, OTL_BIGINT, val);
  3226. break;
  3227. #endif
  3228. #if defined(OTL_UBIGINT)
  3229. case otl_var_ubigint:
  3230. n = OTL_PCONV(T, OTL_UBIGINT, val);
  3231. break;
  3232. #endif
  3233. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  3234. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \
  3235. !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  3236. case otl_var_numeric_type_1:
  3237. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_1, val);
  3238. break;
  3239. #endif
  3240. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  3241. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \
  3242. !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS)
  3243. case otl_var_numeric_type_2:
  3244. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_2, val);
  3245. break;
  3246. #endif
  3247. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  3248. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \
  3249. !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  3250. case otl_var_numeric_type_3:
  3251. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_3, val);
  3252. break;
  3253. #endif
  3254. default:
  3255. rc = 0;
  3256. break;
  3257. }
  3258. return rc;
  3259. }
  3260. #else
  3261. template <OTL_TYPE_NAME T>
  3262. inline int otl_numeric_convert_T(const int ftype, const void *val, T &n) {
  3263. int rc = 1;
  3264. switch (ftype) {
  3265. case otl_var_double:
  3266. n = OTL_PCONV(T, double, val);
  3267. break;
  3268. case otl_var_short:
  3269. n = OTL_PCONV(T, short, val);
  3270. break;
  3271. case otl_var_int:
  3272. n = OTL_PCONV(T, int, val);
  3273. break;
  3274. case otl_var_unsigned_int:
  3275. n = OTL_PCONV(T, unsigned int, val);
  3276. break;
  3277. case otl_var_long_int:
  3278. n = OTL_PCONV(T, long int, val);
  3279. break;
  3280. case otl_var_float:
  3281. n = OTL_PCONV(T, float, val);
  3282. break;
  3283. case otl_var_bfloat:
  3284. n = OTL_PCONV(T, float, val);
  3285. break;
  3286. case otl_var_bdouble:
  3287. n = OTL_PCONV(T, double, val);
  3288. break;
  3289. #if defined(OTL_BIGINT)
  3290. case otl_var_bigint:
  3291. n = OTL_PCONV(T, OTL_BIGINT, val);
  3292. break;
  3293. #endif
  3294. #if defined(OTL_UBIGINT)
  3295. case otl_var_ubigint:
  3296. n = OTL_PCONV(T, OTL_UBIGINT, val);
  3297. break;
  3298. #endif
  3299. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  3300. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \
  3301. !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  3302. case otl_var_numeric_type_1:
  3303. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_1, val);
  3304. break;
  3305. #endif
  3306. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  3307. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \
  3308. !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS)
  3309. case otl_var_numeric_type_2:
  3310. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_2, val);
  3311. break;
  3312. #endif
  3313. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  3314. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \
  3315. !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  3316. case otl_var_numeric_type_3:
  3317. n = OTL_PCONV(T, OTL_NUMERIC_TYPE_3, val);
  3318. break;
  3319. #endif
  3320. default:
  3321. rc = 0;
  3322. break;
  3323. }
  3324. return rc;
  3325. }
  3326. #endif
  3327. #if defined(OTL_STL) && defined(OTL_STREAM_POOLING_ON)
  3328. class otl_ltstr {
  3329. public:
  3330. bool operator()(const OTL_STRING_CONTAINER &s1,
  3331. const OTL_STRING_CONTAINER &s2) const {
  3332. return strcmp(s1.c_str(), s2.c_str()) < 0;
  3333. }
  3334. };
  3335. const int otl_max_default_pool_size = 32;
  3336. #endif
  3337. #if defined(OTL_UNICODE_STRING_TYPE) && defined(OTL_STREAM_POOLING_ON)
  3338. #include <string>
  3339. class otl_ltstr {
  3340. public:
  3341. bool operator()(const std::string &s1, const std::string &s2) const {
  3342. return strcmp(s1.c_str(), s2.c_str()) < 0;
  3343. }
  3344. };
  3345. const int otl_max_default_pool_size = 32;
  3346. #endif
  3347. #if defined(OTL_ACE)
  3348. const int otl_max_default_pool_size = 32;
  3349. #endif
  3350. class otl_stream_shell_generic {
  3351. public:
  3352. otl_stream_shell_generic() : should_delete(0) {}
  3353. virtual ~otl_stream_shell_generic() OTL_THROWS_OTL_EXCEPTION2 {}
  3354. int get_should_delete() const { return should_delete; }
  3355. void set_should_delete(const int ashould_delete) {
  3356. should_delete = ashould_delete;
  3357. }
  3358. protected:
  3359. int should_delete;
  3360. };
  3361. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  3362. defined(OTL_UNICODE_STRING_TYPE)) && \
  3363. defined(OTL_STREAM_POOLING_ON)
  3364. #if defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)
  3365. #include <map>
  3366. #include <vector>
  3367. #endif
  3368. class otl_stream_pool;
  3369. class otl_stream_pool_entry {
  3370. public:
  3371. friend class otl_stream_pool;
  3372. #if defined(OTL_ACE)
  3373. otl_tmpl_vector<otl_stream_shell_generic *> s;
  3374. #elif defined(OTL_UNICODE_STRING_TYPE)
  3375. std::vector<otl_stream_shell_generic *> s;
  3376. #else
  3377. STD_NAMESPACE_PREFIX vector<otl_stream_shell_generic *> s;
  3378. #endif
  3379. otl_stream_pool_entry() : s(), cnt(0) {}
  3380. otl_stream_pool_entry(const otl_stream_pool_entry &sc) : s(), cnt(0) {
  3381. copy(sc);
  3382. }
  3383. otl_stream_pool_entry &operator=(const otl_stream_pool_entry &sc) {
  3384. copy(sc);
  3385. return *this;
  3386. }
  3387. virtual ~otl_stream_pool_entry() {}
  3388. int get_cnt() const { return cnt; }
  3389. void set_cnt(const int acnt) { cnt = acnt; }
  3390. private:
  3391. int cnt;
  3392. void copy(const otl_stream_pool_entry &sc) {
  3393. s.clear();
  3394. #if defined(OTL_ACE)
  3395. for (int i = 0; i < sc.s.size(); ++i)
  3396. #else
  3397. for (size_t i = 0; i < sc.s.size(); ++i)
  3398. #endif
  3399. s.push_back(sc.s[i]);
  3400. cnt = sc.cnt;
  3401. }
  3402. };
  3403. class otl_stream_pool {
  3404. public:
  3405. typedef otl_stream_pool_entry cache_entry_type;
  3406. #if defined(OTL_ACE)
  3407. typedef ACE_RB_Tree<OTL_STRING_CONTAINER, cache_entry_type,
  3408. ACE_Less_Than<OTL_STRING_CONTAINER>,
  3409. ACE_Null_Mutex> sc_type;
  3410. typedef otl_tmpl_vector<otl_stream_shell_generic *> vec_type;
  3411. typedef ACE_RB_Tree_Node<OTL_STRING_CONTAINER, cache_entry_type>
  3412. ace_map_entry;
  3413. #elif defined(OTL_UNICODE_STRING_TYPE)
  3414. typedef std::map<std::string, cache_entry_type, otl_ltstr> sc_type;
  3415. typedef std::vector<otl_stream_shell_generic *> vec_type;
  3416. #else
  3417. typedef STD_NAMESPACE_PREFIX
  3418. map<OTL_STRING_CONTAINER, cache_entry_type, otl_ltstr> sc_type;
  3419. typedef STD_NAMESPACE_PREFIX vector<otl_stream_shell_generic *> vec_type;
  3420. #endif
  3421. protected:
  3422. sc_type sc;
  3423. bool pool_enabled_;
  3424. int max_size;
  3425. int size;
  3426. public:
  3427. otl_stream_pool()
  3428. : sc(), pool_enabled_(true), max_size(otl_max_default_pool_size),
  3429. size(0) {}
  3430. void init(int amax_size = otl_max_default_pool_size) {
  3431. if (size == 0 && max_size == 0)
  3432. return;
  3433. if (amax_size < 2)
  3434. amax_size = 2;
  3435. #if defined(OTL_ACE)
  3436. sc_type::iterator elem0 = sc.begin();
  3437. sc_type::iterator elemN = sc.end();
  3438. for (sc_type::iterator i = elem0; i != elemN; ++i) {
  3439. cache_entry_type &ce = (*i).item();
  3440. int sz = ce.s.size();
  3441. for (int j = 0; j < sz; ++j) {
  3442. ce.s[j]->set_should_delete(1);
  3443. delete ce.s[j];
  3444. ce.s[j] = nullptr;
  3445. }
  3446. ce.s.clear();
  3447. ce.cnt = 0;
  3448. }
  3449. sc.clear();
  3450. #else
  3451. sc_type::iterator elem0 = sc.begin();
  3452. sc_type::iterator elemN = sc.end();
  3453. for (sc_type::iterator i = elem0; i != elemN; ++i) {
  3454. cache_entry_type &ce = (*i).second;
  3455. size_t sz = ce.s.size();
  3456. for (size_t j = 0; j < sz; ++j) {
  3457. ce.s[j]->set_should_delete(1);
  3458. delete ce.s[j];
  3459. ce.s[j] = nullptr;
  3460. }
  3461. ce.s.clear();
  3462. ce.set_cnt(0);
  3463. }
  3464. sc.clear();
  3465. #endif
  3466. size = 0;
  3467. max_size = amax_size;
  3468. }
  3469. #if defined(OTL_UNICODE_STRING_TYPE)
  3470. otl_stream_shell_generic *find(const std::string &stmtxt)
  3471. #else
  3472. otl_stream_shell_generic *find(const OTL_STRING_CONTAINER &stmtxt)
  3473. #endif
  3474. {
  3475. otl_stream_shell_generic *s;
  3476. #if defined(OTL_ACE)
  3477. ace_map_entry *ce = 0;
  3478. int found = sc.find(stmtxt, ce);
  3479. if (found == -1)
  3480. return 0; // entry not found
  3481. s = ce->item().s[ce->item().s.size() - 1];
  3482. ce->item().s.pop_back();
  3483. if (ce->item().s.size() == 0) {
  3484. sc.unbind(ce);
  3485. --size;
  3486. }
  3487. #else
  3488. sc_type::iterator cur = sc.find(stmtxt);
  3489. if (cur == sc.end())
  3490. return nullptr; // entry not found
  3491. cache_entry_type &ce = (*cur).second;
  3492. s = ce.s[ce.s.size() - 1];
  3493. ce.s.pop_back();
  3494. if (ce.s.size() == 0) {
  3495. sc.erase(cur);
  3496. --size;
  3497. }
  3498. #endif
  3499. return s;
  3500. }
  3501. #if defined(OTL_UNICODE_STRING_TYPE)
  3502. void remove(const otl_stream_shell_generic *s, const std::string &stmtxt)
  3503. #else
  3504. void remove(const otl_stream_shell_generic *s,
  3505. const OTL_STRING_CONTAINER &stmtxt)
  3506. #endif
  3507. {
  3508. #if defined(OTL_ACE)
  3509. ace_map_entry *cur = 0;
  3510. int found = sc.find(stmtxt, cur);
  3511. if (found == -1)
  3512. return;
  3513. cache_entry_type &ce = (*cur).item();
  3514. for (int i = 0; i < ce.s.size(); ++i)
  3515. if (ce.s[i] == s) {
  3516. if (ce.s.size() > 1 && i != ce.s.size() - 1) {
  3517. otl_stream_shell_generic *temp_s = ce.s[i];
  3518. ce.s[i] = ce.s[ce.s.size() - 1];
  3519. ce.s[ce.s.size() - 1] = temp_s;
  3520. }
  3521. ce.s.pop_back();
  3522. --size;
  3523. return;
  3524. }
  3525. #else
  3526. sc_type::iterator cur = sc.find(stmtxt);
  3527. if (cur == sc.end())
  3528. return;
  3529. cache_entry_type &ce = (*cur).second;
  3530. vec_type::iterator bgn = ce.s.begin();
  3531. vec_type::iterator end = ce.s.end();
  3532. for (vec_type::iterator i = bgn; i != end; ++i)
  3533. if ((*i) == s) {
  3534. ce.s.erase(i);
  3535. --size;
  3536. return;
  3537. }
  3538. #endif
  3539. }
  3540. int get_max_size() const { return max_size; }
  3541. void add(otl_stream_shell_generic *s, const char *stm_text) {
  3542. #if defined(OTL_UNICODE_STRING_TYPE)
  3543. std::string stmtxt(stm_text);
  3544. #else
  3545. OTL_STRING_CONTAINER stmtxt(stm_text);
  3546. #endif
  3547. #if defined(OTL_ACE)
  3548. ace_map_entry *cur = 0;
  3549. int found_in_map = sc.find(stmtxt, cur);
  3550. if (found_in_map == 0) { // entry found
  3551. bool found = false;
  3552. cache_entry_type &ce = (*cur).item();
  3553. int sz = ce.s.size();
  3554. for (int i = 0; i < sz; ++i) {
  3555. if (s == ce.s[i]) {
  3556. found = true;
  3557. break;
  3558. }
  3559. }
  3560. if (!found)
  3561. ce.s.push_back(s);
  3562. ++ce.cnt;
  3563. } else { // entry not found
  3564. if (size < max_size - 1) { // add new entry
  3565. cache_entry_type ce;
  3566. ce.s.push_back(s);
  3567. ce.cnt = 1;
  3568. sc.bind(stmtxt, ce);
  3569. ++size;
  3570. } else { // erase the least used entry and add new one
  3571. sc_type::iterator elem0 = sc.begin();
  3572. sc_type::iterator elemN = sc.end();
  3573. int min_cnt = 0;
  3574. ace_map_entry *min_entry = 0;
  3575. for (sc_type::iterator i = elem0; i != elemN; ++i) {
  3576. if (i == elem0) { // first element
  3577. min_entry = &(*i);
  3578. min_cnt = (*i).item().cnt;
  3579. }
  3580. if (min_cnt > (*i).item().cnt) { // found less used entry
  3581. min_entry = &(*i);
  3582. min_cnt = (*i).item().cnt;
  3583. }
  3584. }
  3585. cache_entry_type &me = (*min_entry).item();
  3586. int sz = me.s.size();
  3587. for (int n = 0; n < sz; ++n) {
  3588. me.s[n]->set_should_delete(1);
  3589. otl_stream_shell_generic *tmp = me.s[n];
  3590. delete tmp;
  3591. }
  3592. me.s.clear();
  3593. sc.unbind(min_entry);
  3594. cache_entry_type ce;
  3595. ce.cnt = 1;
  3596. ce.s.push_back(s);
  3597. sc.bind(stmtxt, ce);
  3598. }
  3599. }
  3600. #else
  3601. sc_type::iterator cur = sc.find(stmtxt);
  3602. if (cur != sc.end()) { // entry found
  3603. bool found = false;
  3604. cache_entry_type &ce = (*cur).second;
  3605. size_t sz = ce.s.size();
  3606. for (size_t i = 0; i < sz; ++i) {
  3607. if (s == ce.s[i]) {
  3608. found = true;
  3609. break;
  3610. }
  3611. }
  3612. if (!found)
  3613. ce.s.push_back(s);
  3614. ce.set_cnt(ce.get_cnt() + 1);
  3615. } else { // entry not found
  3616. if (size < max_size - 1) { // add new entry
  3617. cache_entry_type ce;
  3618. ce.s.push_back(s);
  3619. ce.set_cnt(1);
  3620. sc[stmtxt] = ce;
  3621. ++size;
  3622. } else { // erase the least used entry and add new one
  3623. sc_type::iterator elem0 = sc.begin();
  3624. sc_type::iterator elemN = sc.end();
  3625. int min_cnt = 0;
  3626. sc_type::iterator min_entry;
  3627. for (sc_type::iterator i = elem0; i != elemN; ++i) {
  3628. if (i == elem0) { // first element
  3629. min_entry = i;
  3630. min_cnt = (*i).second.get_cnt();
  3631. }
  3632. if (min_cnt > (*i).second.get_cnt()) { // found less used entry
  3633. min_entry = i;
  3634. min_cnt = (*i).second.get_cnt();
  3635. }
  3636. }
  3637. cache_entry_type &me = (*min_entry).second;
  3638. size_t sz = me.s.size();
  3639. for (size_t n = 0; n < sz; ++n) {
  3640. me.s[n]->set_should_delete(1);
  3641. otl_stream_shell_generic *tmp = me.s[n];
  3642. delete tmp;
  3643. }
  3644. me.s.clear();
  3645. sc.erase(min_entry);
  3646. cache_entry_type ce;
  3647. ce.set_cnt(1);
  3648. ce.s.push_back(s);
  3649. sc[stmtxt] = ce;
  3650. }
  3651. }
  3652. #endif
  3653. }
  3654. virtual ~otl_stream_pool() OTL_THROWS_OTL_EXCEPTION4 { init(); }
  3655. private:
  3656. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3657. public:
  3658. otl_stream_pool(const otl_stream_pool &) = delete;
  3659. otl_stream_pool &operator=(const otl_stream_pool &) = delete;
  3660. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  3661. otl_stream_pool(otl_stream_pool &&) = delete;
  3662. otl_stream_pool &operator=(otl_stream_pool &&) = delete;
  3663. #endif
  3664. private:
  3665. #else
  3666. otl_stream_pool(const otl_stream_pool &)
  3667. : sc(), pool_enabled_(true), max_size(0), size(0) {}
  3668. otl_stream_pool &operator=(const otl_stream_pool &) { return *this; }
  3669. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3670. otl_stream_pool(otl_stream_pool &&)
  3671. : sc(), pool_enabled_(true), max_size(0), size(0) {}
  3672. otl_stream_pool &operator=(otl_stream_pool &&) { return *this; }
  3673. #endif
  3674. #endif
  3675. };
  3676. #endif
  3677. // =========================== COMMON TEMPLATES ============================
  3678. #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \
  3679. defined(OTL_VALUE_TEMPLATE)
  3680. template <OTL_TYPE_NAME TData> class otl_value {
  3681. public:
  3682. TData v;
  3683. bool ind;
  3684. otl_value() : v(), ind(true) {}
  3685. ~otl_value() {}
  3686. otl_value(const otl_value<TData> &var) : v(var.v), ind(var.ind) {}
  3687. otl_value(const TData &var) : v(var), ind(false) {}
  3688. otl_value(const otl_null &) : v(), ind(true) {}
  3689. otl_value<TData> &operator=(const otl_value<TData> &var) {
  3690. v = var.v;
  3691. ind = var.ind;
  3692. return *this;
  3693. }
  3694. otl_value<TData> &operator=(const TData &var) {
  3695. v = var;
  3696. ind = false;
  3697. return *this;
  3698. }
  3699. otl_value<TData> &operator=(const otl_null) {
  3700. ind = true;
  3701. return *this;
  3702. }
  3703. bool is_null(void) const { return ind; }
  3704. void set_null(void) { ind = true; }
  3705. void set_non_null(void) { ind = false; }
  3706. void set_null(const bool null){ind=null;}
  3707. };
  3708. template <OTL_TYPE_NAME TData, const TData null_value> class otl_compact_value {
  3709. public:
  3710. TData v;
  3711. otl_compact_value() : v(null_value) {}
  3712. ~otl_compact_value(){}
  3713. otl_compact_value(const otl_compact_value<TData,null_value> &var) : v(var.v) {}
  3714. otl_compact_value(const TData &var) : v(var) {}
  3715. otl_compact_value(const otl_null) : v(null_value) {}
  3716. otl_compact_value<TData,null_value> &operator=(const otl_compact_value<TData,null_value> &var) {
  3717. v = var.v;
  3718. return *this;
  3719. }
  3720. otl_compact_value<TData,null_value> &operator=(const TData &var) {
  3721. v = var;
  3722. return *this;
  3723. }
  3724. otl_compact_value<TData,null_value> &operator=(const otl_null) {
  3725. v=null_value;
  3726. return *this;
  3727. }
  3728. bool is_null(void) const { return v==null_value; }
  3729. void set_null(const bool null){if(null)v=null_value;}
  3730. };
  3731. template <OTL_TYPE_NAME TData>
  3732. inline STD_NAMESPACE_PREFIX ostream &operator<<(STD_NAMESPACE_PREFIX ostream &s,
  3733. const otl_value<TData> &var) {
  3734. if(var.is_null())
  3735. s<<"NULL";
  3736. else
  3737. s<<var.v;
  3738. return s;
  3739. }
  3740. template <OTL_TYPE_NAME TData, const TData null_value>
  3741. inline STD_NAMESPACE_PREFIX ostream &operator<<
  3742. (STD_NAMESPACE_PREFIX ostream &s,
  3743. const otl_compact_value<TData,null_value> &var) {
  3744. if(var.is_null())
  3745. s<<"NULL";
  3746. else
  3747. s<<var.v;
  3748. return s;
  3749. }
  3750. #if defined(OTL_DISABLE_OPERATOR_GT_GT_FOR_OTL_VALUE_OTL_DATETIME)
  3751. #else
  3752. inline STD_NAMESPACE_PREFIX ostream &operator<<(
  3753. STD_NAMESPACE_PREFIX ostream &s, const otl_value<otl_datetime> &var) {
  3754. if(var.is_null())
  3755. s<<"NULL";
  3756. else{
  3757. #if !defined(OTL_TRACE_LEVEL)
  3758. #if !defined(OTL_LEGACY_TRACE_DATETIME_FORMAT_ON)
  3759. s << var.v.month << "/" << var.v.day << "/" << var.v.year << " "
  3760. << var.v.hour << ":" << var.v.minute << ":" << var.v.second << "."
  3761. << OTL_SETFILL
  3762. << OTL_SETW(var.v)
  3763. << var.v.fraction;
  3764. #else
  3765. s << var.v.month << "/" << var.v.day << "/" << var.v.year << " "
  3766. << var.v.hour << ":" << var.v.minute << ":" << var.v.second << "."
  3767. << var.v.fraction;
  3768. #endif
  3769. #else
  3770. s << OTL_TRACE_FORMAT_DATETIME(var.v);
  3771. #endif
  3772. }
  3773. return s;
  3774. }
  3775. #endif
  3776. #endif
  3777. template <OTL_TYPE_NAME OTLStream, OTL_TYPE_NAME OTLConnect,
  3778. OTL_TYPE_NAME otl_exception>
  3779. class otl_tmpl_nocommit_stream : public OTLStream {
  3780. public:
  3781. otl_tmpl_nocommit_stream() OTL_NO_THROW : OTLStream() {
  3782. OTLStream::set_commit(0);
  3783. }
  3784. otl_tmpl_nocommit_stream(const otl_stream_buffer_size_type arr_size,
  3785. const char *sqlstm, OTLConnect &pdb,
  3786. const char *ref_cur_placeholder = nullptr)
  3787. OTL_THROWS_OTL_EXCEPTION:
  3788. OTLStream(arr_size, sqlstm, pdb, ref_cur_placeholder) {
  3789. OTLStream::set_commit(0);
  3790. }
  3791. void open(otl_stream_buffer_size_type arr_size, const char *sqlstm,
  3792. OTLConnect &db,
  3793. const char *ref_cur_placeholder = nullptr) OTL_THROWS_OTL_EXCEPTION {
  3794. OTLStream::open(arr_size, sqlstm, db, ref_cur_placeholder);
  3795. OTLStream::set_commit(0);
  3796. }
  3797. };
  3798. #if defined(OTL_STL)
  3799. class otl_pl_vec_generic {
  3800. public:
  3801. typedef STD_NAMESPACE_PREFIX vector<bool> null_flag_type;
  3802. otl_pl_vec_generic() : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {}
  3803. virtual int len(void) const { return 0; }
  3804. virtual void set_len(const int /*new_len*/ = 0,
  3805. const bool /*set_all_to_null*/ = true) {}
  3806. bool is_null(const int ndx = 0) const {
  3807. return null_flag[OTL_SCAST(unsigned int, ndx)];
  3808. }
  3809. void set_null(const int ndx = 0) {
  3810. null_flag[OTL_SCAST(unsigned int, ndx)] = true;
  3811. }
  3812. void set_non_null(const int ndx = 0) {
  3813. null_flag[OTL_SCAST(unsigned int, ndx)] = false;
  3814. }
  3815. virtual ~otl_pl_vec_generic() {}
  3816. int get_vtype() const { return vtype; }
  3817. int get_elem_size() const { return elem_size; }
  3818. void *get_p_v() { return p_v; }
  3819. protected:
  3820. void *p_v;
  3821. null_flag_type null_flag;
  3822. int vtype;
  3823. int elem_size;
  3824. private:
  3825. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3826. public:
  3827. otl_pl_vec_generic(const otl_pl_vec_generic &) = delete;
  3828. otl_pl_vec_generic &operator=(const otl_pl_vec_generic &) = delete;
  3829. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3830. otl_pl_vec_generic(otl_pl_vec_generic &&) = delete;
  3831. otl_pl_vec_generic &operator=(otl_pl_vec_generic &&) = delete;
  3832. #endif
  3833. private:
  3834. #else
  3835. otl_pl_vec_generic(const otl_pl_vec_generic &)
  3836. : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {}
  3837. otl_pl_vec_generic &operator=(const otl_pl_vec_generic &) { return *this; }
  3838. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3839. otl_pl_vec_generic(otl_pl_vec_generic &&)
  3840. : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {}
  3841. otl_pl_vec_generic &operator=(otl_pl_vec_generic &&) { return *this; }
  3842. #endif
  3843. #endif
  3844. };
  3845. template <OTL_TYPE_NAME T, const int type_code, const int T_sz>
  3846. class otl_T_vec : public otl_pl_vec_generic {
  3847. public:
  3848. STD_NAMESPACE_PREFIX vector<T> v;
  3849. typedef T value_type;
  3850. otl_T_vec() : v() {
  3851. this->p_v = OTL_RCAST(void *, &v);
  3852. this->vtype = type_code;
  3853. this->elem_size = T_sz;
  3854. }
  3855. virtual ~otl_T_vec() {}
  3856. virtual void set_len(const int new_len = 0,
  3857. const bool set_all_to_null = true) {
  3858. int i, vsize;
  3859. v.resize(OTL_SCAST(size_t, new_len));
  3860. this->null_flag.resize(OTL_SCAST(size_t, new_len));
  3861. vsize = OTL_SCAST(int, v.size());
  3862. if (set_all_to_null)
  3863. for (i = 0; i < vsize; ++i)
  3864. this->null_flag[OTL_SCAST(size_t, i)] = true;
  3865. }
  3866. virtual int len(void) const { return OTL_SCAST(int, v.size()); }
  3867. T &operator[](int ndx) { return v[ndx]; }
  3868. private:
  3869. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3870. public:
  3871. otl_T_vec(const otl_T_vec &) = delete;
  3872. otl_T_vec &operator=(const otl_T_vec &) = delete;
  3873. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3874. otl_T_vec(otl_T_vec &&) = delete;
  3875. otl_T_vec &operator=(otl_T_vec &&) = delete;
  3876. #endif
  3877. private:
  3878. #else
  3879. otl_T_vec(const otl_T_vec &) : v() {}
  3880. otl_T_vec &operator=(const otl_T_vec &) { return *this; }
  3881. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3882. otl_T_vec(otl_T_vec &&) : v() {}
  3883. otl_T_vec &operator=(otl_T_vec &&) { return *this; }
  3884. #endif
  3885. #endif
  3886. };
  3887. typedef otl_T_vec<double, otl_var_double, sizeof(double)> otl_double_vec;
  3888. typedef otl_T_vec<float, otl_var_float, sizeof(float)> otl_float_vec;
  3889. typedef otl_T_vec<int, otl_var_int, sizeof(int)> otl_int_vec;
  3890. typedef otl_T_vec<short, otl_var_short, sizeof(short)> otl_short_vec;
  3891. typedef otl_T_vec<long, otl_var_long_int, sizeof(long)> otl_long_int_vec;
  3892. typedef otl_T_vec<otl_datetime, otl_var_timestamp, sizeof(otl_oracle_date)>
  3893. otl_datetime_vec;
  3894. typedef otl_T_vec<OTL_STRING_CONTAINER, otl_var_char, 1> otl_string_vec;
  3895. #endif
  3896. template <OTL_TYPE_NAME T, const int atab_size, const int avtype>
  3897. class otl_tmpl_pl_tab : public otl_pl_tab_generic {
  3898. public:
  3899. T v[atab_size];
  3900. void init(void) {
  3901. int i;
  3902. tab_len = 0;
  3903. vtype = avtype;
  3904. tab_size = atab_size;
  3905. p_null = null_flag;
  3906. p_v = OTL_RCAST(unsigned char *, v);
  3907. elem_size = sizeof(T);
  3908. for (i = 0; i < atab_size; ++i)
  3909. null_flag[i] = 0;
  3910. memset(v, 0, sizeof(v));
  3911. }
  3912. otl_tmpl_pl_tab() : v(), null_flag() { init(); }
  3913. virtual ~otl_tmpl_pl_tab() {}
  3914. private:
  3915. short null_flag[atab_size];
  3916. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3917. public:
  3918. otl_tmpl_pl_tab &operator=(const otl_tmpl_pl_tab &) = delete;
  3919. otl_tmpl_pl_tab(const otl_tmpl_pl_tab &) = delete;
  3920. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3921. otl_tmpl_pl_tab &operator=(otl_tmpl_pl_tab &&) = delete;
  3922. otl_tmpl_pl_tab(otl_tmpl_pl_tab &&) = delete;
  3923. #endif
  3924. private:
  3925. #else
  3926. otl_tmpl_pl_tab &operator=(const otl_tmpl_pl_tab &) { return *this; }
  3927. otl_tmpl_pl_tab(const otl_tmpl_pl_tab &) : v(), null_flag() {}
  3928. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3929. otl_tmpl_pl_tab &operator=(otl_tmpl_pl_tab &&) { return *this; }
  3930. otl_tmpl_pl_tab(otl_tmpl_pl_tab &&) : v(), null_flag() {}
  3931. #endif
  3932. #endif
  3933. };
  3934. template <const int atab_size>
  3935. class otl_int_tab : public otl_tmpl_pl_tab<int, atab_size, otl_var_int> {
  3936. public:
  3937. otl_int_tab() : otl_tmpl_pl_tab<int, atab_size, otl_var_int>() {}
  3938. };
  3939. template <const int atab_size>
  3940. class otl_double_tab
  3941. : public otl_tmpl_pl_tab<double, atab_size, otl_var_double> {
  3942. public:
  3943. otl_double_tab() : otl_tmpl_pl_tab<double, atab_size, otl_var_double>() {}
  3944. };
  3945. template <const int atab_size>
  3946. class otl_float_tab : public otl_tmpl_pl_tab<float, atab_size, otl_var_float> {
  3947. public:
  3948. otl_float_tab() : otl_tmpl_pl_tab<float, atab_size, otl_var_float>() {}
  3949. };
  3950. template <const int atab_size>
  3951. class otl_unsigned_tab
  3952. : public otl_tmpl_pl_tab<unsigned, atab_size, otl_var_unsigned_int> {
  3953. public:
  3954. otl_unsigned_tab()
  3955. : otl_tmpl_pl_tab<unsigned, atab_size, otl_var_unsigned_int>() {}
  3956. };
  3957. template <const int atab_size>
  3958. class otl_short_tab : public otl_tmpl_pl_tab<short, atab_size, otl_var_short> {
  3959. public:
  3960. otl_short_tab() : otl_tmpl_pl_tab<short, atab_size, otl_var_short>() {}
  3961. };
  3962. template <const int atab_size>
  3963. class otl_long_int_tab
  3964. : public otl_tmpl_pl_tab<long, atab_size, otl_var_long_int> {
  3965. public:
  3966. otl_long_int_tab() : otl_tmpl_pl_tab<long, atab_size, otl_var_long_int>() {}
  3967. };
  3968. template <const int atab_size, const int str_size>
  3969. class otl_cstr_tab : public otl_pl_tab_generic {
  3970. public:
  3971. typedef unsigned char T[str_size];
  3972. T v[atab_size];
  3973. void init(void) {
  3974. int i;
  3975. tab_len = 0;
  3976. vtype = otl_var_char;
  3977. tab_size = atab_size;
  3978. p_null = null_flag;
  3979. p_v = OTL_RCAST(unsigned char *, v);
  3980. elem_size = sizeof(T);
  3981. for (i = 0; i < atab_size; ++i)
  3982. null_flag[i] = 0;
  3983. memset(v, 0, sizeof(v));
  3984. }
  3985. otl_cstr_tab() : v(), null_flag() { init(); }
  3986. virtual ~otl_cstr_tab() {}
  3987. private:
  3988. short null_flag[atab_size];
  3989. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  3990. public:
  3991. otl_cstr_tab(const otl_cstr_tab &) = delete;
  3992. otl_cstr_tab &operator=(const otl_cstr_tab &) = delete;
  3993. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  3994. otl_cstr_tab(otl_cstr_tab &&) = delete;
  3995. otl_cstr_tab &operator=(otl_cstr_tab &&) = delete;
  3996. #endif
  3997. private:
  3998. #else
  3999. otl_cstr_tab(const otl_cstr_tab &) : v(), null_flag() {}
  4000. otl_cstr_tab &operator=(const otl_cstr_tab &) { return *this; }
  4001. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4002. otl_cstr_tab(otl_cstr_tab &&) : v(), null_flag() {}
  4003. otl_cstr_tab &operator=(otl_cstr_tab &&) { return *this; }
  4004. #endif
  4005. #endif
  4006. };
  4007. template <const int atab_size>
  4008. class otl_datetime_tab : public otl_pl_tab_generic {
  4009. public:
  4010. typedef otl_datetime T;
  4011. T v[atab_size];
  4012. void init(void) {
  4013. int i;
  4014. tab_len = 0;
  4015. vtype = otl_var_timestamp;
  4016. tab_size = atab_size;
  4017. p_null = null_flag;
  4018. p_v = OTL_RCAST(unsigned char *, v);
  4019. elem_size = sizeof(otl_oracle_date);
  4020. for (i = 0; i < atab_size; ++i)
  4021. null_flag[i] = 0;
  4022. }
  4023. otl_datetime_tab() : v(), null_flag() { init(); }
  4024. virtual ~otl_datetime_tab() {}
  4025. private:
  4026. short null_flag[atab_size];
  4027. };
  4028. template <OTL_TYPE_NAME T, const int avtype>
  4029. class otl_tmpl_dyn_pl_tab : public otl_pl_tab_generic {
  4030. public:
  4031. T *v;
  4032. void init(const int atab_size = 1) {
  4033. int i;
  4034. tab_len = 0;
  4035. vtype = avtype;
  4036. tab_size = atab_size;
  4037. v = new T[OTL_SCAST(size_t,tab_size)];
  4038. null_flag = new short[OTL_SCAST(size_t,tab_size)];
  4039. p_null = null_flag;
  4040. p_v = OTL_RCAST(unsigned char *, v);
  4041. elem_size = sizeof(T);
  4042. for (i = 0; i < atab_size; ++i)
  4043. null_flag[i] = 0;
  4044. memset(v, 0, OTL_SCAST(size_t, elem_size * tab_size));
  4045. }
  4046. otl_tmpl_dyn_pl_tab(const int atab_size = 1)
  4047. : v(nullptr), null_flag(nullptr) {
  4048. init(atab_size);
  4049. }
  4050. virtual ~otl_tmpl_dyn_pl_tab() {
  4051. delete[] v;
  4052. delete[] null_flag;
  4053. }
  4054. private:
  4055. short *null_flag;
  4056. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4057. public:
  4058. otl_tmpl_dyn_pl_tab(const otl_tmpl_dyn_pl_tab<T, avtype> &) = delete;
  4059. otl_tmpl_dyn_pl_tab<T, avtype> &
  4060. operator=(const otl_tmpl_dyn_pl_tab<T, avtype> &) = delete;
  4061. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4062. otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab<T, avtype> &&) = delete;
  4063. otl_tmpl_dyn_pl_tab<T, avtype> &operator=(otl_tmpl_dyn_pl_tab<T, avtype> &&) =
  4064. delete;
  4065. #endif
  4066. private:
  4067. #else
  4068. otl_tmpl_dyn_pl_tab(const otl_tmpl_dyn_pl_tab<T, avtype> &)
  4069. : v(nullptr), null_flag(nullptr) {}
  4070. otl_tmpl_dyn_pl_tab<T, avtype> &
  4071. operator=(const otl_tmpl_dyn_pl_tab<T, avtype> &) {
  4072. return *this;
  4073. }
  4074. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4075. otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab<T, avtype> &&)
  4076. : v(nullptr), null_flag(nullptr) {}
  4077. otl_tmpl_dyn_pl_tab<T, avtype> &operator=(otl_tmpl_dyn_pl_tab<T, avtype> &&) {
  4078. return *this;
  4079. }
  4080. #endif
  4081. #endif
  4082. };
  4083. class otl_dynamic_int_tab : public otl_tmpl_dyn_pl_tab<int, otl_var_int> {
  4084. public:
  4085. otl_dynamic_int_tab(const int atab_size = 1)
  4086. : otl_tmpl_dyn_pl_tab<int, otl_var_int>(atab_size) {}
  4087. };
  4088. class otl_dynamic_double_tab
  4089. : public otl_tmpl_dyn_pl_tab<double, otl_var_double> {
  4090. public:
  4091. otl_dynamic_double_tab(const int atab_size = 1)
  4092. : otl_tmpl_dyn_pl_tab<double, otl_var_double>(atab_size) {}
  4093. };
  4094. class otl_dynamic_float_tab : public otl_tmpl_dyn_pl_tab<float, otl_var_float> {
  4095. public:
  4096. otl_dynamic_float_tab(const int atab_size = 1)
  4097. : otl_tmpl_dyn_pl_tab<float, otl_var_float>(atab_size) {}
  4098. };
  4099. class otl_dynamic_unsigned_tab
  4100. : public otl_tmpl_dyn_pl_tab<unsigned, otl_var_unsigned_int> {
  4101. public:
  4102. otl_dynamic_unsigned_tab(const int atab_size = 1)
  4103. : otl_tmpl_dyn_pl_tab<unsigned, otl_var_unsigned_int>(atab_size) {}
  4104. };
  4105. class otl_dynamic_short_tab : public otl_tmpl_dyn_pl_tab<short, otl_var_short> {
  4106. public:
  4107. otl_dynamic_short_tab(const int atab_size = 1)
  4108. : otl_tmpl_dyn_pl_tab<short, otl_var_short>(atab_size) {}
  4109. };
  4110. class otl_dynamic_long_int_tab
  4111. : public otl_tmpl_dyn_pl_tab<long, otl_var_long_int> {
  4112. public:
  4113. otl_dynamic_long_int_tab(const int atab_size = 1)
  4114. : otl_tmpl_dyn_pl_tab<long, otl_var_long_int>(atab_size) {}
  4115. };
  4116. template <const int str_size>
  4117. class otl_dynamic_cstr_tab : public otl_pl_tab_generic {
  4118. public:
  4119. typedef unsigned char T[str_size];
  4120. T *v;
  4121. void init(const int atab_size = 1) {
  4122. int i;
  4123. tab_len = 0;
  4124. vtype = otl_var_char;
  4125. tab_size = atab_size;
  4126. v = new T[OTL_SCAST(size_t,tab_size)];
  4127. null_flag = new short[OTL_SCAST(size_t,tab_size)];
  4128. p_null = null_flag;
  4129. p_v = OTL_RCAST(unsigned char *, v);
  4130. elem_size = sizeof(T);
  4131. for (i = 0; i < atab_size; ++i)
  4132. null_flag[i] = 0;
  4133. memset(v, 0, OTL_SCAST(size_t, elem_size) * OTL_SCAST(size_t, tab_size));
  4134. }
  4135. otl_dynamic_cstr_tab(const int atab_size = 1)
  4136. : v(nullptr), null_flag(nullptr) {
  4137. init(atab_size);
  4138. }
  4139. virtual ~otl_dynamic_cstr_tab() {
  4140. delete[] v;
  4141. delete[] null_flag;
  4142. }
  4143. private:
  4144. short *null_flag;
  4145. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4146. public:
  4147. otl_dynamic_cstr_tab(const otl_dynamic_cstr_tab &) = delete;
  4148. otl_dynamic_cstr_tab &operator=(const otl_dynamic_cstr_tab &) = delete;
  4149. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4150. otl_dynamic_cstr_tab(otl_dynamic_cstr_tab &&) = delete;
  4151. otl_dynamic_cstr_tab &operator=(otl_dynamic_cstr_tab &&) = delete;
  4152. #endif
  4153. private:
  4154. #else
  4155. otl_dynamic_cstr_tab(const otl_dynamic_cstr_tab &)
  4156. : v(nullptr), null_flag(nullptr) {}
  4157. otl_dynamic_cstr_tab &operator=(const otl_dynamic_cstr_tab &) {
  4158. return *this;
  4159. }
  4160. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4161. otl_dynamic_cstr_tab(otl_dynamic_cstr_tab &&)
  4162. : v(nullptr), null_flag(nullptr) {}
  4163. otl_dynamic_cstr_tab &operator=(otl_dynamic_cstr_tab &&) { return *this; }
  4164. #endif
  4165. #endif
  4166. };
  4167. class otl_dynamic_datetime_tab : public otl_pl_tab_generic {
  4168. public:
  4169. typedef otl_datetime T;
  4170. T *v;
  4171. void init(const int atab_size = 1) {
  4172. int i;
  4173. tab_len = 0;
  4174. vtype = otl_var_timestamp;
  4175. tab_size = atab_size;
  4176. v = new T[OTL_SCAST(size_t,tab_size)];
  4177. null_flag = new short[OTL_SCAST(size_t,tab_size)];
  4178. p_null = null_flag;
  4179. p_v = OTL_RCAST(unsigned char *, v);
  4180. elem_size = sizeof(otl_oracle_date);
  4181. for (i = 0; i < atab_size; ++i)
  4182. null_flag[i] = 0;
  4183. }
  4184. otl_dynamic_datetime_tab(const int atab_size = 1)
  4185. : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) {
  4186. init(atab_size);
  4187. }
  4188. virtual ~otl_dynamic_datetime_tab() {
  4189. delete[] v;
  4190. delete[] null_flag;
  4191. }
  4192. private:
  4193. short *null_flag;
  4194. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4195. public:
  4196. otl_dynamic_datetime_tab(const otl_dynamic_datetime_tab &) = delete;
  4197. otl_dynamic_datetime_tab &operator=(const otl_dynamic_datetime_tab &) =
  4198. delete;
  4199. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4200. otl_dynamic_datetime_tab(otl_dynamic_datetime_tab &&) = delete;
  4201. otl_dynamic_datetime_tab &operator=(otl_dynamic_datetime_tab &&) = delete;
  4202. #endif
  4203. private:
  4204. #else
  4205. otl_dynamic_datetime_tab(const otl_dynamic_datetime_tab &)
  4206. : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) {}
  4207. otl_dynamic_datetime_tab &operator=(const otl_dynamic_datetime_tab &) {
  4208. return *this;
  4209. }
  4210. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4211. otl_dynamic_datetime_tab(otl_dynamic_datetime_tab &&)
  4212. : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) {}
  4213. otl_dynamic_datetime_tab &operator=(otl_dynamic_datetime_tab &&) {
  4214. return *this;
  4215. }
  4216. #endif
  4217. #endif
  4218. };
  4219. #define OTL_TMPL_EXCEPTION \
  4220. otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
  4221. #define OTL_TMPL_CONNECT \
  4222. otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct>
  4223. #define OTL_TMPL_CURSOR \
  4224. otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct, \
  4225. TVariableStruct>
  4226. #define OTL_TMPL_OUT_STREAM \
  4227. otl_tmpl_out_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
  4228. TVariableStruct, TTimestampStruct>
  4229. #define OTL_TMPL_SELECT_CURSOR \
  4230. otl_tmpl_select_cursor<TExceptionStruct, TConnectStruct, TCursorStruct, \
  4231. TVariableStruct, TSelectCursorStruct>
  4232. #define OTL_TMPL_INOUT_STREAM \
  4233. otl_tmpl_inout_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
  4234. TVariableStruct, TTimestampStruct>
  4235. #define OTL_TMPL_SELECT_STREAM \
  4236. otl_tmpl_select_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
  4237. TVariableStruct, TSelectCursorStruct, \
  4238. TTimestampStruct>
  4239. #if defined(OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION)
  4240. #if defined(OTL_EXCEPTION_DERIVED_FROM)
  4241. #error OTL_EXCEPTION_DERIVED_FROM is already defined. \
  4242. OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION cannot be used
  4243. #endif
  4244. #define OTL_EXCEPTION_DERIVED_FROM std::exception
  4245. #if defined(UNICODE) || defined(_UNICODE)
  4246. #if !defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  4247. #error OTL_UNICODE_EXCEPTION_AND_RLOGON needs to be defined when \
  4248. OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION is used with Unicode
  4249. #endif
  4250. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4251. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4252. #define OTL_EXCEPTION_HAS_MEMBERS \
  4253. virtual const char *what() const noexcept { \
  4254. otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \
  4255. return reinterpret_cast<const char *>(this->char_msg); \
  4256. }
  4257. #else
  4258. #define OTL_EXCEPTION_HAS_MEMBERS \
  4259. virtual const char *what() const throw() { \
  4260. otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \
  4261. return reinterpret_cast<const char *>(this->char_msg); \
  4262. }
  4263. #endif
  4264. #else
  4265. #define OTL_EXCEPTION_HAS_MEMBERS \
  4266. virtual const char *what() const throw() { \
  4267. otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \
  4268. return reinterpret_cast<const char *>(this->char_msg); \
  4269. }
  4270. #endif
  4271. #else
  4272. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4273. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4274. #define OTL_EXCEPTION_HAS_MEMBERS \
  4275. virtual const char *what() const noexcept { \
  4276. return reinterpret_cast<const char *>(this->msg); \
  4277. }
  4278. #else
  4279. #define OTL_EXCEPTION_HAS_MEMBERS \
  4280. virtual const char *what() const throw() { \
  4281. return reinterpret_cast<const char *>(this->msg); \
  4282. }
  4283. #endif
  4284. #else
  4285. #define OTL_EXCEPTION_HAS_MEMBERS \
  4286. virtual const char *what() const throw() { \
  4287. return reinterpret_cast<const char *>(this->msg); \
  4288. }
  4289. #endif
  4290. #endif
  4291. #endif
  4292. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  4293. OTL_TYPE_NAME TCursorStruct>
  4294. #if defined(OTL_EXCEPTION_DERIVED_FROM)
  4295. class otl_tmpl_exception : public OTL_EXCEPTION_DERIVED_FROM,
  4296. public TExceptionStruct {
  4297. #else
  4298. class otl_tmpl_exception : public TExceptionStruct {
  4299. #endif
  4300. public:
  4301. #if defined(OTL_EXCEPTION_HAS_MEMBERS)
  4302. OTL_EXCEPTION_HAS_MEMBERS
  4303. #endif
  4304. #if defined(OTL_EXCEPTION_STM_TEXT_SIZE)
  4305. char stm_text[OTL_EXCEPTION_STM_TEXT_SIZE];
  4306. #else
  4307. char stm_text[2048];
  4308. #endif
  4309. char var_info[256];
  4310. otl_tmpl_exception()
  4311. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4312. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4313. OTL_ANSI_CPP_11_NOEXCEPT
  4314. #else
  4315. throw()
  4316. #endif
  4317. #else
  4318. OTL_NO_THROW
  4319. #endif
  4320. {
  4321. stm_text[0] = 0;
  4322. var_info[0] = 0;
  4323. }
  4324. otl_tmpl_exception(TConnectStruct &conn_struct, const char *sqlstm = nullptr)
  4325. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4326. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4327. OTL_ANSI_CPP_11_NOEXCEPT
  4328. #else
  4329. throw()
  4330. #endif
  4331. #else
  4332. OTL_NO_THROW
  4333. #endif
  4334. {
  4335. stm_text[0] = 0;
  4336. var_info[0] = 0;
  4337. if (sqlstm) {
  4338. OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm,
  4339. sizeof(stm_text) - 1);
  4340. stm_text[sizeof(stm_text) - 1] = 0;
  4341. }
  4342. conn_struct.error(OTL_SCAST(TExceptionStruct &, *this));
  4343. OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info)
  4344. }
  4345. otl_tmpl_exception(TCursorStruct &cursor_struct, const char *sqlstm = nullptr)
  4346. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4347. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4348. OTL_ANSI_CPP_11_NOEXCEPT
  4349. #else
  4350. throw()
  4351. #endif
  4352. #else
  4353. OTL_NO_THROW
  4354. #endif
  4355. {
  4356. stm_text[0] = 0;
  4357. var_info[0] = 0;
  4358. if (sqlstm) {
  4359. OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm,
  4360. sizeof(stm_text) - 1);
  4361. stm_text[sizeof(stm_text) - 1] = 0;
  4362. }
  4363. cursor_struct.error(OTL_SCAST(TExceptionStruct &, *this));
  4364. OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info)
  4365. }
  4366. otl_tmpl_exception(const char *amsg, const int acode,
  4367. const char *sqlstm = nullptr,
  4368. const char *varinfo = nullptr)
  4369. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4370. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4371. OTL_ANSI_CPP_11_NOEXCEPT
  4372. #else
  4373. throw()
  4374. #endif
  4375. #else
  4376. OTL_NO_THROW
  4377. #endif
  4378. #if defined(OTL_EXCEPTION_DERIVED_FROM) && \
  4379. defined(OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL)
  4380. : OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL
  4381. #endif
  4382. {
  4383. stm_text[0] = 0;
  4384. var_info[0] = 0;
  4385. if (sqlstm) {
  4386. #if defined(_MSC_VER)
  4387. #if (_MSC_VER >= 1400)
  4388. OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm,
  4389. sizeof(stm_text) - 1);
  4390. #else
  4391. strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text));
  4392. stm_text[sizeof(stm_text) - 1] = 0;
  4393. #endif
  4394. #else
  4395. strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text));
  4396. stm_text[sizeof(stm_text) - 1] = 0;
  4397. #endif
  4398. }
  4399. if (varinfo)
  4400. OTL_STRCPY_S(OTL_RCAST(char *, var_info), sizeof(var_info), varinfo);
  4401. TExceptionStruct::init(amsg, acode);
  4402. OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info)
  4403. }
  4404. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) && \
  4405. !defined(OTL_EXCEPTION_DERIVED_FROM)
  4406. #error OTL_EXCEPTION_DERIVED_FROM needs to be defined when \
  4407. OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW is defined
  4408. #endif
  4409. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  4410. otl_tmpl_exception(const char *amsg, const int acode, const char *sqlstm,
  4411. const char *varinfo, const void *input_string,
  4412. int input_string_size)
  4413. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4414. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4415. OTL_ANSI_CPP_11_NOEXCEPT
  4416. #else
  4417. throw()
  4418. #endif
  4419. #else
  4420. OTL_NO_THROW
  4421. #endif
  4422. #if defined(OTL_EXCEPTION_DERIVED_FROM) && \
  4423. defined(OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL)
  4424. : OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL
  4425. #endif
  4426. {
  4427. stm_text[0] = 0;
  4428. var_info[0] = 0;
  4429. if (sqlstm) {
  4430. #if defined(_MSC_VER)
  4431. #if (_MSC_VER >= 1400)
  4432. OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm,
  4433. sizeof(stm_text) - 1);
  4434. #else
  4435. strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text));
  4436. stm_text[sizeof(stm_text) - 1] = 0;
  4437. #endif
  4438. #else
  4439. strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text));
  4440. stm_text[sizeof(stm_text) - 1] = 0;
  4441. #endif
  4442. }
  4443. if (varinfo)
  4444. OTL_STRCPY_S(OTL_RCAST(char *, var_info), sizeof(var_info), varinfo);
  4445. TExceptionStruct::init(amsg, acode);
  4446. OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW(input_string,
  4447. input_string_size)
  4448. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  4449. OTL_TRACE_EXCEPTION2(this->code, this->msg, this->stm_text, this->var_info,
  4450. input_string, input_string_size)
  4451. #else
  4452. OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info)
  4453. #endif
  4454. }
  4455. #endif
  4456. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4457. otl_tmpl_exception(const otl_tmpl_exception &) = default;
  4458. #endif
  4459. virtual ~otl_tmpl_exception()
  4460. #if defined(__GNUC__) && (__GNUC__ >= 3)
  4461. #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT)
  4462. OTL_ANSI_CPP_11_NOEXCEPT
  4463. #else
  4464. throw()
  4465. #endif
  4466. #else
  4467. OTL_NO_THROW
  4468. #endif
  4469. {
  4470. }
  4471. };
  4472. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  4473. OTL_TYPE_NAME TCursorStruct>
  4474. class otl_tmpl_connect {
  4475. protected:
  4476. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  4477. bool use_fetch_scroll_;
  4478. #endif
  4479. TConnectStruct connect_struct;
  4480. int long_max_size;
  4481. int retcode;
  4482. public:
  4483. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  4484. void set_fetch_scroll_mode(const bool use_fetch_scroll_mode = true) {
  4485. use_fetch_scroll_ = use_fetch_scroll_mode;
  4486. }
  4487. bool get_fetch_scroll_mode() const { return use_fetch_scroll_; }
  4488. #endif
  4489. void set_retcode(const int aretcode) { retcode = aretcode; }
  4490. int get_retcode() const { return retcode; }
  4491. TConnectStruct &get_connect_struct() { return connect_struct; }
  4492. int connected;
  4493. void set_max_long_size(const int amax_size) {
  4494. #if defined(OTL_UNICODE)
  4495. #if defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \
  4496. defined(OTL_ORA10G_R2)
  4497. long_max_size = amax_size * OTL_SCAST(int, sizeof(OTL_WCHAR));
  4498. #else
  4499. long_max_size = amax_size;
  4500. #endif
  4501. #else
  4502. long_max_size = amax_size;
  4503. #endif
  4504. }
  4505. int get_max_long_size(void) {
  4506. return long_max_size;
  4507. }
  4508. void set_timeout(const int atimeout = 0) {
  4509. connect_struct.set_timeout(atimeout);
  4510. }
  4511. void set_cursor_type(const int acursor_type = 0) {
  4512. connect_struct.set_cursor_type(acursor_type);
  4513. }
  4514. otl_tmpl_connect()
  4515. :
  4516. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  4517. use_fetch_scroll_(false),
  4518. #endif
  4519. connect_struct(), long_max_size(otl_short_int_max), retcode(1),
  4520. connected(0) {
  4521. }
  4522. otl_tmpl_connect(const char *connect_str, const int auto_commit = 0)
  4523. :
  4524. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  4525. use_fetch_scroll_(false),
  4526. #endif
  4527. connect_struct(), long_max_size(otl_short_int_max), retcode(1),
  4528. connected(0) {
  4529. rlogon(connect_str, auto_commit);
  4530. }
  4531. virtual ~otl_tmpl_connect() OTL_THROWS_OTL_EXCEPTION3 { logoff(); }
  4532. static int otl_initialize(const int threaded_mode = 0) {
  4533. return TConnectStruct::initialize(threaded_mode);
  4534. }
  4535. void rlogon(const char *connect_str, const int auto_commit = 0) {
  4536. retcode = connect_struct.rlogon(connect_str, auto_commit);
  4537. if (retcode)
  4538. connected = 1;
  4539. else {
  4540. connected = 0;
  4541. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4542. OTL_TMPL_EXCEPTION ex(connect_struct);
  4543. connect_struct.cleanup();
  4544. OTL_THROW(ex);
  4545. }
  4546. }
  4547. void logoff(void) {
  4548. if (!connected)
  4549. return;
  4550. OTL_TRACE_FUNC(0x1, "otl_connect", "logoff", "")
  4551. retcode = connect_struct.logoff();
  4552. connected = 0;
  4553. if (retcode)
  4554. return;
  4555. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4556. OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct)));
  4557. }
  4558. void commit(void) {
  4559. if (!connected)
  4560. return;
  4561. OTL_TRACE_FUNC(0x1, "otl_connect", "commit", "")
  4562. retcode = connect_struct.commit();
  4563. if (retcode)
  4564. return;
  4565. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4566. OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct)));
  4567. }
  4568. void auto_commit_on(void) {
  4569. if (!connected)
  4570. return;
  4571. OTL_TRACE_FUNC(0x1, "otl_connect", "auto_commit_on", "")
  4572. retcode = connect_struct.auto_commit_on();
  4573. if (retcode)
  4574. return;
  4575. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4576. OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct)));
  4577. }
  4578. void auto_commit_off(void) {
  4579. if (!connected)
  4580. return;
  4581. OTL_TRACE_FUNC(0x1, "otl_connect", "auto_commit_off", "")
  4582. retcode = connect_struct.auto_commit_off();
  4583. if (retcode)
  4584. return;
  4585. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4586. OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct)));
  4587. }
  4588. void rollback(void) {
  4589. if (!connected)
  4590. return;
  4591. OTL_TRACE_FUNC(0x1, "otl_connect", "rollback", "")
  4592. retcode = connect_struct.rollback();
  4593. if (retcode)
  4594. return;
  4595. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4596. OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct)));
  4597. }
  4598. private:
  4599. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4600. public:
  4601. otl_tmpl_connect(const otl_tmpl_connect &) = delete;
  4602. otl_tmpl_connect &operator=(const otl_tmpl_connect &) = delete;
  4603. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4604. otl_tmpl_connect(otl_tmpl_connect &&) = delete;
  4605. otl_tmpl_connect &operator=(otl_tmpl_connect &&) = delete;
  4606. #endif
  4607. private:
  4608. #else
  4609. otl_tmpl_connect(const otl_tmpl_connect &)
  4610. : connected(0),
  4611. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  4612. use_fetch_scroll_(false),
  4613. #endif
  4614. connect_struct(), long_max_size(otl_short_int_max), retcode(1)
  4615. {}
  4616. otl_tmpl_connect &operator=(const otl_tmpl_connect &) { return *this; }
  4617. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4618. otl_tmpl_connect(otl_tmpl_connect &&)
  4619. : connected(0), connect_struct(), long_max_size(otl_short_int_max),
  4620. retcode(1){}
  4621. otl_tmpl_connect &operator=(otl_tmpl_connect &&) { return *this; }
  4622. #endif
  4623. #endif
  4624. };
  4625. template <OTL_TYPE_NAME TVariableStruct> class otl_tmpl_variable {
  4626. protected:
  4627. int param_type;
  4628. int ftype;
  4629. int elem_size;
  4630. int array_size;
  4631. char *name;
  4632. int pos;
  4633. int name_pos;
  4634. int bound;
  4635. int pl_tab_flag;
  4636. TVariableStruct var_struct;
  4637. public:
  4638. TVariableStruct &get_var_struct() { return var_struct; }
  4639. const TVariableStruct &get_const_var_struct() const { return var_struct; }
  4640. int get_bound() const { return bound; }
  4641. int get_param_type() const { return param_type; }
  4642. int get_ftype() const { return ftype; }
  4643. int get_name_pos() const { return name_pos; }
  4644. int get_elem_size() const { return elem_size; }
  4645. int get_pl_tab_flag() const { return pl_tab_flag; }
  4646. int get_pos() const { return pos; }
  4647. int get_array_size() const { return array_size; }
  4648. const char *get_name() const { return name; }
  4649. void set_param_type(const int aparam_type){ this->param_type=aparam_type; }
  4650. void set_pos(const int apos) { this->pos = apos; }
  4651. void set_bound(const int abound) { this->bound = abound; }
  4652. void set_name_pos(const int aname_pos) { this->name_pos = aname_pos; }
  4653. void set_ftype(const int aftype) { this->ftype = aftype; }
  4654. int actual_elem_size(void) { return var_struct.actual_elem_size(); }
  4655. void copy_var_desc(otl_var_desc &v) {
  4656. v.param_type = param_type;
  4657. v.ftype = ftype;
  4658. v.elem_size = elem_size;
  4659. v.array_size = array_size;
  4660. v.pos = pos;
  4661. v.name_pos = name_pos;
  4662. if (name) {
  4663. OTL_STRNCPY_S(v.name, sizeof(v.name), name, sizeof(v.name) - 1);
  4664. v.name[sizeof(v.name) - 1] = 0;
  4665. } else
  4666. v.name[0] = 0;
  4667. v.pl_tab_flag = pl_tab_flag;
  4668. }
  4669. otl_tmpl_variable()
  4670. : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr),
  4671. pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {}
  4672. virtual ~otl_tmpl_variable() { delete[] name; }
  4673. void init(const bool select_stm_flag, const int aftype, const int aelem_size,
  4674. const otl_stream_buffer_size_type aarray_size,
  4675. const void *connect_struct = nullptr, const int apl_tab_flag = 0
  4676. #if defined(OTL_ORA_SDO_GEOMETRY)
  4677. ,OCIType* colOCIType = nullptr
  4678. #endif
  4679. ){
  4680. ftype = aftype;
  4681. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  4682. if (ftype == otl_var_nchar)
  4683. ftype = otl_var_char;
  4684. else if (ftype == otl_var_nclob)
  4685. ftype = otl_var_clob;
  4686. #endif
  4687. elem_size = aelem_size;
  4688. array_size = aarray_size;
  4689. pl_tab_flag = apl_tab_flag;
  4690. bound = 0;
  4691. var_struct.init(select_stm_flag, aftype, elem_size, aarray_size,
  4692. connect_struct, pl_tab_flag
  4693. #if defined(OTL_ORA_SDO_GEOMETRY)
  4694. ,colOCIType
  4695. #endif
  4696. );
  4697. }
  4698. int get_param_type(void) { return param_type; }
  4699. void copy_name(const char *aname) {
  4700. pos = 0;
  4701. if (name == aname)
  4702. return;
  4703. if (name)
  4704. delete[] name;
  4705. size_t len = strlen(aname) + 1;
  4706. name = new char[len];
  4707. OTL_STRCPY_S(name, len, aname);
  4708. }
  4709. void copy_pos(const int apos) {
  4710. if (name) {
  4711. delete[] name;
  4712. name = nullptr;
  4713. name_pos = 0;
  4714. }
  4715. pos = apos;
  4716. }
  4717. void set_null(int ndx) { var_struct.set_null(ndx); }
  4718. void set_not_null(int ndx) { var_struct.set_not_null(ndx, elem_size); }
  4719. void set_len(int len, int ndx = 0) { var_struct.set_len(len, ndx); }
  4720. int get_len(int ndx = 0) { return var_struct.get_len(ndx); }
  4721. int get_pl_tab_len(void) { return this->var_struct.get_pl_tab_len(); }
  4722. int get_max_pl_tab_len(void) { return this->var_struct.get_max_pl_tab_len(); }
  4723. void set_pl_tab_len(const int pl_tab_len) {
  4724. this->var_struct.set_pl_tab_len(pl_tab_len);
  4725. }
  4726. int is_null(int ndx) { return var_struct.is_null(ndx); }
  4727. void *val(int ndx = 0) { return var_struct.val(ndx, elem_size); }
  4728. static void map_ftype(otl_column_desc &desc, const int max_long_size,
  4729. int &aftype, int &aelem_size,
  4730. otl_select_struct_override &a_override,
  4731. const int column_ndx, const int connection_type) {
  4732. TVariableStruct::map_ftype(desc, max_long_size, aftype, aelem_size,
  4733. a_override, column_ndx, connection_type);
  4734. }
  4735. static int int2ext(int int_type) {
  4736. return TVariableStruct::int2ext(int_type);
  4737. }
  4738. private:
  4739. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  4740. public:
  4741. otl_tmpl_variable(const otl_tmpl_variable &) = delete;
  4742. otl_tmpl_variable &operator=(const otl_tmpl_variable &) = delete;
  4743. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4744. otl_tmpl_variable(otl_tmpl_variable &&) = delete;
  4745. otl_tmpl_variable &operator=(otl_tmpl_variable &&) = delete;
  4746. #endif
  4747. private:
  4748. #else
  4749. otl_tmpl_variable(const otl_tmpl_variable &)
  4750. : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr),
  4751. pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {}
  4752. otl_tmpl_variable &operator=(const otl_tmpl_variable &) { return *this; }
  4753. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  4754. otl_tmpl_variable(otl_tmpl_variable &&)
  4755. : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr),
  4756. pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {}
  4757. otl_tmpl_variable &operator=(otl_tmpl_variable &&) { return *this; }
  4758. #endif
  4759. #endif
  4760. };
  4761. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  4762. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
  4763. class otl_tmpl_cursor {
  4764. protected:
  4765. int connected;
  4766. char *stm_text;
  4767. char *stm_label;
  4768. TCursorStruct cursor_struct;
  4769. int vl_len;
  4770. otl_tmpl_variable<TVariableStruct> **vl;
  4771. OTL_TMPL_CONNECT *adb;
  4772. int eof_data;
  4773. int eof_desc;
  4774. int retcode;
  4775. long _rpc;
  4776. int in_destructor;
  4777. public:
  4778. void set_batch_error_mode(const bool batch_error_mode) {
  4779. cursor_struct.set_batch_error_mode(batch_error_mode);
  4780. }
  4781. int get_number_of_errors_in_batch() {
  4782. int rv = cursor_struct.get_number_of_errors_in_batch(retcode);
  4783. if (retcode)
  4784. return rv;
  4785. OTL_UNCAUGHT_EXCEPTION_RETURN(rv);
  4786. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4787. }
  4788. void get_error(const int error_ndx, int &dml_row_offset,
  4789. TExceptionStruct &exception_struct) {
  4790. retcode =
  4791. cursor_struct.get_error(error_ndx, dml_row_offset, exception_struct);
  4792. if (retcode)
  4793. return;
  4794. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4795. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4796. }
  4797. OTL_TMPL_CONNECT *get_adb() { return adb; }
  4798. void set_adb(OTL_TMPL_CONNECT *aadb) { adb = aadb; }
  4799. TCursorStruct &get_cursor_struct_ref() { return cursor_struct; }
  4800. otl_tmpl_variable<TVariableStruct> **get_vl() { return vl; }
  4801. int get_vl_len() const { return vl_len; }
  4802. const char *get_stm_label() const { return stm_label; }
  4803. const char *get_stm_text() const { return stm_text; }
  4804. void set_connected(const int aconnected) { connected = aconnected; }
  4805. int &get_eof_data_ref() { return eof_data; }
  4806. TCursorStruct &get_cursor_struct() { return cursor_struct; }
  4807. int get_connected() const { return connected; }
  4808. otl_tmpl_cursor()
  4809. : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(),
  4810. vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(),
  4811. retcode(1), _rpc(0), in_destructor(0) {}
  4812. otl_tmpl_cursor(OTL_TMPL_CONNECT &connect)
  4813. : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(),
  4814. vl_len(0), vl(nullptr), adb(&connect), eof_data(), eof_desc(),
  4815. retcode(1), _rpc(0), in_destructor(0) {
  4816. open(connect);
  4817. }
  4818. otl_tmpl_cursor(OTL_TMPL_CONNECT &connect, TVariableStruct *var)
  4819. : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(),
  4820. vl_len(0), vl(nullptr), adb(&connect), eof_data(), eof_desc(),
  4821. retcode(1), _rpc(0), in_destructor(0) {
  4822. open(connect, var);
  4823. }
  4824. virtual ~otl_tmpl_cursor() OTL_THROWS_OTL_EXCEPTION2 {
  4825. in_destructor = 1;
  4826. close();
  4827. delete[] stm_label;
  4828. stm_label = nullptr;
  4829. delete[] stm_text;
  4830. stm_text = nullptr;
  4831. }
  4832. void open(OTL_TMPL_CONNECT &connect, TVariableStruct *var = nullptr) {
  4833. in_destructor = 0;
  4834. eof_data = 0;
  4835. eof_desc = 0;
  4836. retcode = 1;
  4837. adb = &connect;
  4838. _rpc = 0;
  4839. if (var == nullptr)
  4840. retcode = cursor_struct.open(connect.get_connect_struct());
  4841. else
  4842. retcode = cursor_struct.open(connect.get_connect_struct(), var);
  4843. if (retcode) {
  4844. connected = 1;
  4845. return;
  4846. }
  4847. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4848. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct)));
  4849. }
  4850. virtual void close(const char force_handle_free = 'N') {
  4851. _rpc = 0;
  4852. if (!connected)
  4853. return;
  4854. if (!this->adb)
  4855. return;
  4856. if (!adb->connected) {
  4857. connected = 0;
  4858. adb = nullptr;
  4859. retcode = 1;
  4860. return;
  4861. }
  4862. connected = 0;
  4863. retcode = cursor_struct.close(force_handle_free);
  4864. if (retcode) {
  4865. adb = nullptr;
  4866. return;
  4867. }
  4868. adb = nullptr;
  4869. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4870. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct)));
  4871. }
  4872. void parse(const int direct_exec_flag=0) {
  4873. _rpc = 0;
  4874. if (!connected)
  4875. return;
  4876. retcode = cursor_struct.parse(stm_text,direct_exec_flag);
  4877. switch (retcode) {
  4878. case 0:
  4879. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4880. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4881. case 2:
  4882. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4883. char var_info[1];
  4884. var_info[0] = 0;
  4885. OTL_THROW((OTL_TMPL_EXCEPTION(
  4886. otl_error_msg_17, otl_error_code_17,
  4887. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  4888. }
  4889. }
  4890. void parse(const char *sqlstm) {
  4891. if (!connected)
  4892. return;
  4893. if (stm_text) {
  4894. delete[] stm_text;
  4895. stm_text = nullptr;
  4896. }
  4897. size_t len = strlen(sqlstm) + 1;
  4898. stm_text = new char[len];
  4899. OTL_STRCPY_S(stm_text, len, sqlstm);
  4900. parse();
  4901. }
  4902. long get_rpc() OTL_NO_THROW { return _rpc; }
  4903. void exec(const int iters /*=1*/, const int rowoff /*=0*/,
  4904. const otl_sql_exec_from_enum
  4905. otl_sql_exec_from_class /*=otl_sql_exec_from_cursor_class*/) {
  4906. if (!connected)
  4907. return;
  4908. retcode = cursor_struct.exec(iters, rowoff, otl_sql_exec_from_class);
  4909. _rpc = cursor_struct.get_rpc();
  4910. if (retcode)
  4911. return;
  4912. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4913. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4914. }
  4915. virtual bool valid_binding(const otl_tmpl_variable<TVariableStruct> &v,
  4916. const otl_binding_enum binding_type) {
  4917. bool rc = true;
  4918. if (((v.get_ftype() == otl_var_varchar_long ||
  4919. v.get_ftype() == otl_var_raw_long) &&
  4920. (v.get_const_var_struct().get_otl_adapter() ==
  4921. OTL_ADAPTER_ENUM otl_ora8_adapter) &&
  4922. v.get_array_size() > 1) ||
  4923. ((v.get_ftype() == otl_var_blob || v.get_ftype() == otl_var_clob) &&
  4924. v.get_const_var_struct().get_otl_adapter() ==
  4925. OTL_ADAPTER_ENUM otl_ora8_adapter &&
  4926. v.get_array_size() > 1 &&
  4927. binding_type == OTL_BINDING_ENUM otl_inout_binding))
  4928. rc = false;
  4929. return rc;
  4930. }
  4931. virtual void bind(const char *name, otl_tmpl_variable<TVariableStruct> &v) {
  4932. if (!connected)
  4933. return;
  4934. if (v.get_bound())
  4935. return;
  4936. v.copy_name(name);
  4937. if (!valid_binding(v, OTL_BINDING_ENUM otl_inout_binding)) {
  4938. char var_info[256];
  4939. otl_var_info_var2(v.get_name(), v.get_ftype(), var_info,
  4940. sizeof(var_info));
  4941. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4942. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_16, otl_error_code_16,
  4943. stm_label ? stm_label : stm_text, var_info)));
  4944. }
  4945. retcode = cursor_struct.bind(
  4946. name, v.get_var_struct(), v.get_elem_size(), v.get_ftype(),
  4947. v.get_param_type(), v.get_name_pos(),
  4948. this->adb->get_connect_struct().get_connection_type(),
  4949. v.get_pl_tab_flag());
  4950. if (retcode) {
  4951. v.set_bound(1);
  4952. return;
  4953. }
  4954. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4955. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4956. }
  4957. virtual void bind(const int column_num,
  4958. otl_tmpl_variable<TVariableStruct> &v) {
  4959. if (!connected)
  4960. return;
  4961. v.copy_pos(column_num);
  4962. if (!valid_binding(v, OTL_BINDING_ENUM otl_select_binding)) {
  4963. char var_info[256];
  4964. otl_var_info_col2(v.get_pos(), v.get_ftype(), var_info, sizeof(var_info));
  4965. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4966. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_16, otl_error_code_16,
  4967. stm_label ? stm_label : stm_text, var_info)));
  4968. }
  4969. retcode =
  4970. cursor_struct.bind(column_num, v.get_var_struct(), v.get_elem_size(),
  4971. v.get_ftype(), v.get_param_type());
  4972. if (retcode)
  4973. return;
  4974. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  4975. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  4976. }
  4977. virtual void bind(otl_tmpl_variable<TVariableStruct> &v) {
  4978. if (!connected)
  4979. return;
  4980. if (v.get_name())
  4981. bind(v.get_name(), v);
  4982. if (v.get_pos())
  4983. bind(v.get_pos(), v);
  4984. }
  4985. static long direct_exec(OTL_TMPL_CONNECT &connect, const char *sqlstm,
  4986. const int exception_enabled = 1)
  4987. #if defined(OTL_ANSI_CPP) && defined(OTL_FUNC_THROW_SPEC_ON)
  4988. throw(OTL_TMPL_EXCEPTION)
  4989. #endif
  4990. {
  4991. OTL_TRACE_DIRECT_EXEC
  4992. try {
  4993. OTL_TMPL_CURSOR cur(connect);
  4994. cur.cursor_struct.set_direct_exec(1);
  4995. cur.parse(sqlstm);
  4996. cur.exec(1, 0, otl_sql_exec_from_cursor_class);
  4997. return cur.cursor_struct.get_rpc();
  4998. }
  4999. catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) {
  5000. if (exception_enabled) {
  5001. throw;
  5002. }
  5003. }
  5004. return -1;
  5005. }
  5006. static void syntax_check(OTL_TMPL_CONNECT &connect, const char *sqlstm)
  5007. #if defined(OTL_ANSI_CPP) && defined(OTL_FUNC_THROW_SPEC_ON)
  5008. throw(OTL_TMPL_EXCEPTION)
  5009. #endif
  5010. {
  5011. OTL_TRACE_SYNTAX_CHECK
  5012. OTL_TMPL_CURSOR cur(connect);
  5013. cur.cursor_struct.set_direct_exec(1);
  5014. cur.cursor_struct.set_parse_only(1);
  5015. cur.parse(sqlstm);
  5016. }
  5017. int eof(void) { return eof_data; }
  5018. int describe_column(otl_column_desc &col, const int column_num) {
  5019. if (!connected)
  5020. return 0;
  5021. retcode = cursor_struct.describe_column(col, column_num, eof_desc);
  5022. if (eof_desc)
  5023. return 0;
  5024. if (retcode)
  5025. return 1;
  5026. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  5027. OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text)));
  5028. }
  5029. private:
  5030. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  5031. public:
  5032. otl_tmpl_cursor(const otl_tmpl_cursor &) = delete;
  5033. otl_tmpl_cursor &operator=(const otl_tmpl_cursor &) = delete;
  5034. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  5035. otl_tmpl_cursor(otl_tmpl_cursor &&) = delete;
  5036. otl_tmpl_cursor &operator=(otl_tmpl_cursor &&) = delete;
  5037. #endif
  5038. private:
  5039. #else
  5040. otl_tmpl_cursor(const otl_tmpl_cursor &)
  5041. : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(),
  5042. vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(),
  5043. retcode(1), _rpc(0), in_destructor(0) {}
  5044. otl_tmpl_cursor &operator=(const otl_tmpl_cursor &) { return *this; }
  5045. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  5046. otl_tmpl_cursor(otl_tmpl_cursor &&)
  5047. : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(),
  5048. vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(),
  5049. retcode(1), _rpc(0), in_destructor(0) {}
  5050. otl_tmpl_cursor &operator=(otl_tmpl_cursor &&) { return *this; }
  5051. #endif
  5052. #endif
  5053. };
  5054. inline int is_num(char c) { return c >= '0' && c <= '9'; }
  5055. template <OTL_TYPE_NAME TVariableStruct, OTL_TYPE_NAME TTimestampStruct,
  5056. OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  5057. OTL_TYPE_NAME TCursorStruct>
  5058. class otl_tmpl_ext_hv_decl {
  5059. private:
  5060. char **hv;
  5061. short int *inout;
  5062. int *pl_tab_size;
  5063. int array_size;
  5064. int prev_array_size;
  5065. short int vst[4];
  5066. int len;
  5067. char *stm_text_;
  5068. char *stm_label_;
  5069. int container_size_;
  5070. bool has_plsql_tabs_or_refcur_;
  5071. bool has_space_in_bind_variable_;
  5072. bool bind_var_terminator_is_missing_;
  5073. public:
  5074. bool has_plsql_tabs_or_refcur() const { return has_plsql_tabs_or_refcur_; }
  5075. bool has_space_in_bind_variable() const {
  5076. return has_space_in_bind_variable_;
  5077. }
  5078. bool bind_var_terminator_is_missing() const {
  5079. return bind_var_terminator_is_missing_;
  5080. }
  5081. short int get_vst(const int ndx) const { return vst[ndx]; }
  5082. int get_len() const { return len; }
  5083. short int get_inout(const int ndx) const { return inout[ndx]; }
  5084. int get_pl_tab_size(const int ndx) const { return pl_tab_size[ndx]; }
  5085. const char *stm_label() const { return stm_label_; }
  5086. const char *stm_text() const { return stm_text_; }
  5087. enum var_status {
  5088. in = 0,
  5089. out = 1,
  5090. io = 2,
  5091. def = 3
  5092. };
  5093. otl_tmpl_ext_hv_decl(char *stm, int arr_size = 1, char *label = nullptr,
  5094. otl_select_struct_override **select_override = nullptr,
  5095. OTL_TMPL_CONNECT *adb = nullptr)
  5096. : hv(nullptr), inout(nullptr), pl_tab_size(nullptr), array_size(0),
  5097. prev_array_size(0), vst(), len(0), stm_text_(nullptr),
  5098. stm_label_(nullptr), container_size_(0),
  5099. has_plsql_tabs_or_refcur_(false), has_space_in_bind_variable_(false),
  5100. bind_var_terminator_is_missing_(false) {
  5101. container_size_ = otl_var_list_size;
  5102. hv = new char *[OTL_SCAST(size_t,container_size_)];
  5103. inout = new short[OTL_SCAST(size_t,container_size_)];
  5104. pl_tab_size = new int[OTL_SCAST(size_t,container_size_)];
  5105. int j;
  5106. array_size = arr_size;
  5107. prev_array_size = arr_size;
  5108. stm_text_ = stm;
  5109. stm_label_ = label;
  5110. int i = 0;
  5111. short in_str = 0;
  5112. bool in_comment = false;
  5113. bool in_one_line_comment = false;
  5114. char *c = stm;
  5115. bool in_comment_column_override = false;
  5116. hv[i] = nullptr;
  5117. while (*c) {
  5118. switch (*c) {
  5119. case '\'':
  5120. if (!in_comment && !in_one_line_comment) {
  5121. if (!in_str)
  5122. in_str = 1;
  5123. else {
  5124. if (c[1] == '\'')
  5125. ++c;
  5126. else
  5127. in_str = 0;
  5128. }
  5129. }
  5130. break;
  5131. case '/':
  5132. if (c[1] == '*' && !in_str && c[2] == ':' && c[3] == '#') {
  5133. in_comment_column_override = true;
  5134. *c = ' ';
  5135. ++c;
  5136. *c = ' ';
  5137. ++c;
  5138. } else if (c[1] == '*' && !in_str) {
  5139. in_comment = true;
  5140. ++c;
  5141. }
  5142. break;
  5143. case '-':
  5144. if (c[1] == '-' && !in_str) {
  5145. in_one_line_comment = true;
  5146. ++c;
  5147. }
  5148. break;
  5149. case '*':
  5150. if (c[1] == '/' && in_comment) {
  5151. in_comment = false;
  5152. ++c;
  5153. } else if (c[1] == '/' && in_comment_column_override) {
  5154. *c = ' ';
  5155. ++c;
  5156. *c = ' ';
  5157. }
  5158. break;
  5159. case '\n':
  5160. if (in_one_line_comment)
  5161. in_one_line_comment = false;
  5162. break;
  5163. }
  5164. if (*c == ':' && !in_str && !in_comment && !in_one_line_comment &&
  5165. ((c > stm && *(c - 1) != '\\') || c == stm)) {
  5166. char *bind_var_ptr = c;
  5167. short in_out = def;
  5168. int apl_tab_size = 0;
  5169. char var[64];
  5170. char *v = var;
  5171. *v++ = *c++;
  5172. while (is_id(*c))
  5173. *v++ = *c++;
  5174. while (otl_isspace(*c) && *c)
  5175. ++c;
  5176. if (*c == '<' || (*c == '/' && c[1] == '*')) {
  5177. if (*c == '<')
  5178. *c = ' ';
  5179. else if (*c == '/' && c[1] == '*') {
  5180. *c = ' ';
  5181. ++c;
  5182. *c = ' ';
  5183. }
  5184. while (*c != '>' && *c != ',' && *c != '*' && *c != '<' &&
  5185. *c != ':' && *c != '/' && *c) {
  5186. *v++ = *c;
  5187. *c++ = ' ';
  5188. }
  5189. if (*c == 0 || *c == ':' || *c == '<' || *c == '/')
  5190. bind_var_terminator_is_missing_ = true;
  5191. if (*c == ',' && otl_isspace(c[1]))
  5192. has_space_in_bind_variable_ = true;
  5193. if (*c == ',') {
  5194. *c++ = ' ';
  5195. if (otl_to_upper(*c) == 'I') {
  5196. if (otl_to_upper(c[2]) == 'O')
  5197. in_out = io;
  5198. else
  5199. in_out = in;
  5200. } else if (otl_to_upper(*c) == 'O')
  5201. in_out = out;
  5202. while (*c != '>' && *c && *c != '*' && (*c != '[' && *c != '('))
  5203. *c++ = ' ';
  5204. if (*c == '*') {
  5205. *c = ' ';
  5206. ++c;
  5207. *c = ' ';
  5208. }
  5209. if (*c == '[' || *c == '(') {
  5210. char tmp[32];
  5211. char *t = tmp;
  5212. *c++ = ' ';
  5213. while ((*c != ']' && *c != ')') && *c != '>' && *c != '*' && *c) {
  5214. *t++ = *c;
  5215. *c++ = ' ';
  5216. }
  5217. if (*c == '*') {
  5218. *c = ' ';
  5219. ++c;
  5220. *c = ' ';
  5221. }
  5222. *t = 0;
  5223. apl_tab_size = atoi(tmp);
  5224. while (*c != '>' && *c != '*' && *c)
  5225. *c++ = ' ';
  5226. if (*c == '*') {
  5227. *c = ' ';
  5228. ++c;
  5229. *c = ' ';
  5230. }
  5231. }
  5232. } else if (*c == '*' && c[1] == '/') {
  5233. *c = ' ';
  5234. ++c;
  5235. *c = ' ';
  5236. }
  5237. if (*c)
  5238. *c = ' ';
  5239. *v = 0;
  5240. if (select_override != nullptr && bind_var_ptr[1] == '#') {
  5241. char *c4 = bind_var_ptr + 2;
  5242. char col_num[64];
  5243. char *col_num_ptr = col_num;
  5244. while (is_num(*c4) && *c4) {
  5245. *col_num_ptr = *c4;
  5246. ++col_num_ptr;
  5247. ++c4;
  5248. }
  5249. *col_num_ptr = 0;
  5250. int col_ndx = atoi(col_num);
  5251. if (col_ndx > 0) {
  5252. if (*select_override == nullptr) {
  5253. *select_override = new otl_select_struct_override();
  5254. }
  5255. int data_type = otl_var_none;
  5256. int data_len = 0;
  5257. char name[128];
  5258. parse_var(adb, var, data_type, data_len, name);
  5259. (*select_override)->add_override(col_ndx, data_type, data_len);
  5260. }
  5261. c4 = bind_var_ptr;
  5262. while (*c4 && *c4 != ' ') {
  5263. *c4 = ' ';
  5264. ++c4;
  5265. }
  5266. } else
  5267. add_var(i, var, in_out, apl_tab_size);
  5268. }
  5269. }
  5270. if (*c)
  5271. ++c;
  5272. }
  5273. for (j = 0; j < 4; ++j)
  5274. vst[j] = 0;
  5275. i = 0;
  5276. while (hv[i]) {
  5277. switch (inout[i]) {
  5278. case in:
  5279. ++vst[0];
  5280. break;
  5281. case out:
  5282. ++vst[1];
  5283. break;
  5284. case io:
  5285. ++vst[2];
  5286. break;
  5287. case def:
  5288. ++vst[3];
  5289. break;
  5290. }
  5291. ++i;
  5292. }
  5293. len = i;
  5294. }
  5295. virtual ~otl_tmpl_ext_hv_decl() {
  5296. int i;
  5297. for (i = 0; hv[i] != nullptr; ++i)
  5298. delete[] hv[i];
  5299. delete[] hv;
  5300. delete[] inout;
  5301. delete[] pl_tab_size;
  5302. }
  5303. char *operator[](int ndx) { return hv[ndx]; }
  5304. short v_status(int ndx) { return inout[ndx]; }
  5305. int is_id(char c) {
  5306. return isalnum(OTL_SCAST(unsigned char, c)) || c == '_' || c == '#';
  5307. }
  5308. int name_comp(char *n1, char *n2) {
  5309. while (*n1 != ' ' && *n1 != 0 && *n2 != ' ' && *n2 != 0) {
  5310. if (otl_to_upper(*n1) != otl_to_upper(*n2))
  5311. return 0;
  5312. ++n1;
  5313. ++n2;
  5314. }
  5315. if ((*n1 == ' ' && *n2 != ' ') || (*n2 == ' ' && *n1 != ' '))
  5316. return 0;
  5317. return 1;
  5318. }
  5319. void add_var(int &n, char *v, short in_out, int apl_tab_size = 0) {
  5320. int i;
  5321. for (i = 0; i < n; ++i)
  5322. if (name_comp(hv[i], v))
  5323. return;
  5324. char *c = v;
  5325. bool is_space = false;
  5326. while (*c) {
  5327. is_space = otl_isspace(*c);
  5328. if (is_space)
  5329. break;
  5330. ++c;
  5331. }
  5332. if (is_space && otl_str_case_insensitive_equal((c + 1), "REFCUR")) {
  5333. has_plsql_tabs_or_refcur_ = true;
  5334. if (apl_tab_size == 0)
  5335. apl_tab_size = 1;
  5336. }
  5337. if (apl_tab_size > 0)
  5338. has_plsql_tabs_or_refcur_ = true;
  5339. size_t v_len = strlen(v) + 1;
  5340. hv[n] = new char[v_len];
  5341. OTL_STRCPY_S(hv[n], v_len, v);
  5342. inout[n] = in_out;
  5343. pl_tab_size[n] = apl_tab_size;
  5344. if (n == container_size_ - 1) {
  5345. int temp_container_size = container_size_;
  5346. container_size_ *= 2;
  5347. char **temp_hv = nullptr;
  5348. short *temp_inout = nullptr;
  5349. int *temp_pl_tab_size = nullptr;
  5350. try {
  5351. temp_hv = new char *[OTL_SCAST(size_t,container_size_)];
  5352. temp_inout = new short[OTL_SCAST(size_t,container_size_)];
  5353. temp_pl_tab_size = new int[OTL_SCAST(size_t,container_size_)];
  5354. }
  5355. catch (const std::bad_alloc &) {
  5356. delete[] temp_hv;
  5357. delete[] temp_inout;
  5358. delete[] temp_pl_tab_size;
  5359. throw;
  5360. }
  5361. size_t temp_container_size_2 = OTL_SCAST(size_t, temp_container_size);
  5362. memcpy(temp_hv, hv, sizeof(char *) * temp_container_size_2);
  5363. memcpy(temp_inout, inout, sizeof(short) * temp_container_size_2);
  5364. memcpy(temp_pl_tab_size, pl_tab_size,
  5365. sizeof(int) * temp_container_size_2);
  5366. delete[] hv;
  5367. delete[] inout;
  5368. delete[] pl_tab_size;
  5369. hv = temp_hv;
  5370. inout = temp_inout;
  5371. pl_tab_size = temp_pl_tab_size;
  5372. }
  5373. hv[++n] = nullptr;
  5374. inout[n] = def;
  5375. pl_tab_size[n] = 0;
  5376. }
  5377. int parse_var(OTL_TMPL_CONNECT *pdb, char *s, int &data_type, int &data_len,
  5378. char *name) {
  5379. data_type = otl_var_none;
  5380. data_len = 0;
  5381. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5382. defined(OTL_NUMERIC_TYPE_1_TO_STR) && \
  5383. defined(OTL_NUMERIC_TYPE_1_ID) || \
  5384. defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON)
  5385. char type_arr[256];
  5386. #endif
  5387. char type = ' ';
  5388. char t2 = ' ';
  5389. char t3 = ' ';
  5390. char t4 = ' ';
  5391. int size = 0;
  5392. char *c = name, *c1 = s;
  5393. while (*c1 != ' ' && *c1)
  5394. *c++ = *c1++;
  5395. *c = 0;
  5396. while (*c1 == ' ' && *c1)
  5397. ++c1;
  5398. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5399. defined(OTL_NUMERIC_TYPE_1_TO_STR) && \
  5400. defined(OTL_NUMERIC_TYPE_1_ID) || \
  5401. defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON)
  5402. char *ct = c1;
  5403. char *tac = type_arr;
  5404. size_t ta_len = 0;
  5405. while (*ct && (*ct != '[' && *ct != '(') && ta_len < sizeof(type_arr)) {
  5406. *tac = otl_to_upper(*ct);
  5407. ++ct;
  5408. ++tac;
  5409. ++ta_len;
  5410. }
  5411. *tac = 0;
  5412. #endif
  5413. size_t clen = strlen(c1);
  5414. if (clen >= 3) {
  5415. type = otl_to_upper(c1[0]);
  5416. t2 = otl_to_upper(c1[1]);
  5417. t3 = otl_to_upper(c1[2]);
  5418. t4 = otl_to_upper(c1[3]);
  5419. }
  5420. if ((type == 'C' && t2 == 'H') ||
  5421. (type == 'R' && t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '('))) {
  5422. char tmp[32];
  5423. char *t = tmp;
  5424. while ((*c1 != '[' && *c1 != '(') && *c1)
  5425. ++c1;
  5426. ++c1;
  5427. while ((*c1 != ']' && *c1 != ')') && *c1)
  5428. *t++ = *c1++;
  5429. *t = 0;
  5430. size = atoi(tmp);
  5431. #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE)
  5432. size += 1;
  5433. #endif
  5434. }
  5435. #if defined(OTL_ORA_UNICODE)
  5436. if (type == 'N' && t2 == 'C' && t3 == 'H') {
  5437. char tmp[32];
  5438. char *t = tmp;
  5439. while ((*c1 != '[' && *c1 != '(') && *c1)
  5440. ++c1;
  5441. ++c1;
  5442. while ((*c1 != ']' && *c1 != ')') && *c1)
  5443. *t++ = *c1++;
  5444. *t = 0;
  5445. size = atoi(tmp);
  5446. #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE)
  5447. size += 1;
  5448. #endif
  5449. }
  5450. #endif
  5451. OTL_CHECK_BIND_VARS
  5452. int rc = 1;
  5453. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5454. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  5455. if (strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) {
  5456. data_type = otl_var_char;
  5457. data_len = otl_numeric_type_1_str_size;
  5458. rc = 0;
  5459. return rc;
  5460. }
  5461. #endif
  5462. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  5463. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  5464. if (strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) {
  5465. data_type = otl_var_char;
  5466. data_len = otl_numeric_type_2_str_size;
  5467. rc = 0;
  5468. return rc;
  5469. }
  5470. #endif
  5471. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  5472. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  5473. if (strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) {
  5474. data_type = otl_var_char;
  5475. data_len = otl_numeric_type_3_str_size;
  5476. rc = 0;
  5477. return rc;
  5478. }
  5479. #endif
  5480. switch (type) {
  5481. case 'B':
  5482. if (t2 == 'L') {
  5483. data_type = otl_var_blob;
  5484. if (pdb)
  5485. data_len = pdb->get_max_long_size();
  5486. else
  5487. data_len = 0;
  5488. } else if (t2 == 'F') {
  5489. data_type = otl_var_bfloat;
  5490. data_len = sizeof(float);
  5491. } else if (t2 == 'D') {
  5492. data_type = otl_var_bdouble;
  5493. data_len = sizeof(double);
  5494. }
  5495. #if defined(OTL_BIGINT)
  5496. else if (t2 == 'I') {
  5497. data_type = TConnectStruct::var_bigint;
  5498. data_len = TConnectStruct::bigint_size;
  5499. }
  5500. #endif
  5501. break;
  5502. case 'C':
  5503. if (t2 == 'H') {
  5504. data_type = otl_var_char;
  5505. data_len = size;
  5506. } else if (t2 == 'L') {
  5507. data_type = otl_var_clob;
  5508. if (pdb)
  5509. data_len = pdb->get_max_long_size();
  5510. else
  5511. data_len = 0;
  5512. } else
  5513. rc = 0;
  5514. break;
  5515. case 'D':
  5516. if (t2 == 'O') {
  5517. data_type = otl_var_double;
  5518. data_len = sizeof(double);
  5519. } else if (t2 == 'B' && t3 == '2') {
  5520. if (t4 == 'T') {
  5521. data_type = otl_var_db2time;
  5522. data_len = sizeof(TTimestampStruct);
  5523. } else if (t4 == 'D') {
  5524. data_type = otl_var_db2date;
  5525. data_len = sizeof(TTimestampStruct);
  5526. } else
  5527. rc = 0;
  5528. } else
  5529. rc = 0;
  5530. break;
  5531. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  5532. case 'N':
  5533. if (t2 == 'C') {
  5534. if (t3 == 'L') {
  5535. data_type = otl_var_nclob;
  5536. if (pdb)
  5537. data_len = pdb->get_max_long_size();
  5538. else
  5539. data_len = 0;
  5540. } else if (t3 == 'H') {
  5541. data_type = otl_var_nchar;
  5542. data_len = size;
  5543. }
  5544. }
  5545. break;
  5546. #endif
  5547. case 'F':
  5548. data_type = otl_var_float;
  5549. data_len = sizeof(float);
  5550. break;
  5551. case 'I':
  5552. data_type = otl_var_int;
  5553. data_len = sizeof(int);
  5554. break;
  5555. case 'U':
  5556. if (t2 == 'N') {
  5557. data_type = otl_var_unsigned_int;
  5558. data_len = sizeof(unsigned);
  5559. }
  5560. #if defined(OTL_UBIGINT)
  5561. else if (t2 == 'B') {
  5562. data_type = TConnectStruct::var_ubigint;
  5563. data_len = TConnectStruct::ubigint_size;
  5564. }
  5565. #endif
  5566. break;
  5567. case 'R':
  5568. if (t2 == 'E' && t3 == 'F') {
  5569. data_type = otl_var_refcur;
  5570. data_len = 1;
  5571. } else if (t2 == 'A' && t3 == 'W' && t4 != '_') {
  5572. data_type = otl_var_raw;
  5573. data_len = size;
  5574. } else if (t2 == 'A' && t3 == 'W' && t4 == '_') {
  5575. data_type = otl_var_raw_long;
  5576. if (pdb)
  5577. data_len = pdb->get_max_long_size();
  5578. else
  5579. data_len = 0;
  5580. }
  5581. break;
  5582. case 'S':
  5583. data_type = otl_var_short;
  5584. data_len = sizeof(short);
  5585. break;
  5586. case 'L':
  5587. if (t2 == 'O' && t3 == 'N') {
  5588. data_type = otl_var_long_int;
  5589. data_len = sizeof(long);
  5590. } else if (t2 == 'T' && t3 == 'Z') {
  5591. data_type = otl_var_ltz_timestamp;
  5592. data_len = sizeof(TTimestampStruct);
  5593. } else
  5594. rc = 0;
  5595. break;
  5596. case 'T':
  5597. if (t2 == 'Z') {
  5598. data_type = otl_var_tz_timestamp;
  5599. data_len = sizeof(TTimestampStruct);
  5600. } else if (t2 == 'I' && t3 == 'M') {
  5601. data_type = otl_var_timestamp;
  5602. data_len = sizeof(TTimestampStruct);
  5603. } else
  5604. rc = 0;
  5605. break;
  5606. case 'V':
  5607. data_type = otl_var_varchar_long;
  5608. if (pdb)
  5609. data_len = pdb->get_max_long_size();
  5610. else
  5611. data_len = 0;
  5612. break;
  5613. default:
  5614. return 0;
  5615. }
  5616. return rc;
  5617. }
  5618. otl_tmpl_variable<TVariableStruct> *alloc_var(char *s, const int vstat,
  5619. const int status,
  5620. OTL_TMPL_CONNECT &adb,
  5621. const int apl_tab_size = 0) {
  5622. char name[128];
  5623. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5624. defined(OTL_NUMERIC_TYPE_1_TO_STR) && \
  5625. defined(OTL_NUMERIC_TYPE_1_ID) || \
  5626. defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON)
  5627. char type_arr[256];
  5628. #endif
  5629. char type = ' ';
  5630. char t2 = ' ';
  5631. char t3 = ' ';
  5632. char t4 = ' ';
  5633. char t5 = ' ';
  5634. int size = 0;
  5635. char *c = name, *c1 = s;
  5636. while (*c1 != ' ' && *c1)
  5637. *c++ = *c1++;
  5638. *c = 0;
  5639. while (*c1 == ' ' && *c1)
  5640. ++c1;
  5641. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5642. defined(OTL_NUMERIC_TYPE_1_TO_STR) && \
  5643. defined(OTL_NUMERIC_TYPE_1_ID) || \
  5644. defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON)
  5645. char *ct = c1;
  5646. char *tac = type_arr;
  5647. size_t ta_len = 0;
  5648. while (*ct && (*ct != '[' && *ct != '(') && ta_len < sizeof(type_arr)) {
  5649. *tac = otl_to_upper(*ct);
  5650. ++ct;
  5651. ++tac;
  5652. ++ta_len;
  5653. }
  5654. *tac = 0;
  5655. #endif
  5656. size_t clen = strlen(c1);
  5657. if (clen >= 3) {
  5658. type = otl_to_upper(c1[0]);
  5659. t2 = otl_to_upper(c1[1]);
  5660. t3 = otl_to_upper(c1[2]);
  5661. t4 = otl_to_upper(c1[3]);
  5662. }
  5663. if (clen > 4)
  5664. t5 = otl_to_upper(c1[4]);
  5665. if ((type == 'C' && t2 == 'H') ||
  5666. (type == 'R' && t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '('))) {
  5667. char tmp[32];
  5668. char *t = tmp;
  5669. while ((*c1 != '[' && *c1 != '(') && *c1)
  5670. ++c1;
  5671. if (*c1)
  5672. ++c1;
  5673. while ((*c1 != ']' && *c1 != ')') && *c1)
  5674. *t++ = *c1++;
  5675. *t = 0;
  5676. if (*tmp == 0)
  5677. // declaration <char> is invalid
  5678. return nullptr;
  5679. if (*c1 == 0)
  5680. // missing ] or )
  5681. return nullptr;
  5682. size = atoi(tmp);
  5683. #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE)
  5684. if (type == 'C')
  5685. size += 1;
  5686. #endif
  5687. if (size < 2)
  5688. // minimum size of <char[XXX]> should be at 2
  5689. return nullptr;
  5690. }
  5691. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  5692. if (type == 'N' && t2 == 'C' && t3 == 'H') {
  5693. char tmp[32];
  5694. char *t = tmp;
  5695. while ((*c1 != '[' && *c1 != '(') && *c1)
  5696. ++c1;
  5697. if (*c1)
  5698. ++c1;
  5699. while ((*c1 != ']' && *c1 != ')') && *c1)
  5700. *t++ = *c1++;
  5701. *t = 0;
  5702. if (*tmp == 0)
  5703. return nullptr;
  5704. size = atoi(tmp);
  5705. #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE)
  5706. size += 1;
  5707. #endif
  5708. }
  5709. #endif
  5710. if (status == in && (vstat == in || vstat == io))
  5711. ;
  5712. else if (status == out && (vstat == out || vstat == io || vstat == def))
  5713. ;
  5714. else if (status == def)
  5715. ;
  5716. else
  5717. return nullptr;
  5718. OTL_CHECK_BIND_VARS
  5719. int pl_tab_flag = 0;
  5720. if (apl_tab_size) {
  5721. array_size = apl_tab_size;
  5722. pl_tab_flag = 1;
  5723. } else
  5724. array_size = prev_array_size;
  5725. otl_tmpl_variable<TVariableStruct> *v =
  5726. new otl_tmpl_variable<TVariableStruct>;
  5727. v->copy_name(name);
  5728. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  5729. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  5730. if (strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) {
  5731. v->init(false, otl_var_char, otl_numeric_type_1_str_size,
  5732. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5733. &adb.get_connect_struct(), pl_tab_flag);
  5734. } else
  5735. #endif
  5736. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  5737. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  5738. if (strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) {
  5739. v->init(false, otl_var_char, otl_numeric_type_2_str_size,
  5740. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5741. &adb.get_connect_struct(), pl_tab_flag);
  5742. } else
  5743. #endif
  5744. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  5745. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  5746. if (strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) {
  5747. v->init(false, otl_var_char, otl_numeric_type_3_str_size,
  5748. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5749. &adb.get_connect_struct(), pl_tab_flag);
  5750. } else
  5751. #endif
  5752. {
  5753. switch (type) {
  5754. case 'B':
  5755. if (t2 == 'L')
  5756. v->init(false, otl_var_blob, adb.get_max_long_size(),
  5757. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5758. &adb.get_connect_struct());
  5759. #if defined(OTL_BIGINT)
  5760. else if (t2 == 'I')
  5761. v->init(false, TConnectStruct::var_bigint,
  5762. TConnectStruct::bigint_size,
  5763. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5764. &adb.get_connect_struct(), pl_tab_flag);
  5765. #endif
  5766. else if (t2 == 'F')
  5767. v->init(false, otl_var_bfloat, sizeof(float),
  5768. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5769. &adb.get_connect_struct(), pl_tab_flag);
  5770. else if (t2 == 'D')
  5771. v->init(false, otl_var_bdouble, sizeof(double),
  5772. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5773. &adb.get_connect_struct(), pl_tab_flag);
  5774. break;
  5775. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  5776. case 'N':
  5777. if (t2 == 'C' && (t3 == 'L' || t3 == 'H')) {
  5778. if (t3 == 'L') {
  5779. v->init(false, otl_var_nclob, adb.get_max_long_size(),
  5780. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5781. &adb.get_connect_struct());
  5782. v->set_ftype(otl_var_clob);
  5783. } else if (t3 == 'H') {
  5784. v->init(false, otl_var_nchar, size,
  5785. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5786. &adb.get_connect_struct(), pl_tab_flag);
  5787. v->set_ftype(otl_var_char);
  5788. }
  5789. } else {
  5790. delete v;
  5791. v = nullptr;
  5792. }
  5793. break;
  5794. #endif
  5795. case 'C':
  5796. if (t2 == 'H') {
  5797. v->init(false, otl_var_char, size,
  5798. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5799. &adb.get_connect_struct(), pl_tab_flag);
  5800. if (t5 == 'Z')
  5801. v->get_var_struct().set_charz_flag(true);
  5802. } else if (t2 == 'L')
  5803. v->init(false, otl_var_clob, adb.get_max_long_size(),
  5804. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5805. &adb.get_connect_struct());
  5806. else {
  5807. delete v;
  5808. v = nullptr;
  5809. }
  5810. break;
  5811. case 'D':
  5812. if (t2 == 'O')
  5813. v->init(false, otl_var_double, sizeof(double),
  5814. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5815. &adb.get_connect_struct(), pl_tab_flag);
  5816. else if (t2 == 'B' && t3 == '2') {
  5817. if (t4 == 'T')
  5818. v->init(false, otl_var_db2time, sizeof(TTimestampStruct),
  5819. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5820. &adb.get_connect_struct(), pl_tab_flag);
  5821. else if (t4 == 'D')
  5822. v->init(false, otl_var_db2date, sizeof(TTimestampStruct),
  5823. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5824. &adb.get_connect_struct(), pl_tab_flag);
  5825. else {
  5826. delete v;
  5827. v = nullptr;
  5828. }
  5829. } else {
  5830. delete v;
  5831. v = nullptr;
  5832. }
  5833. break;
  5834. case 'F':
  5835. v->init(false, otl_var_float, sizeof(float),
  5836. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5837. &adb.get_connect_struct(), pl_tab_flag);
  5838. break;
  5839. case 'I':
  5840. v->init(false, otl_var_int, sizeof(int),
  5841. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5842. &adb.get_connect_struct(), pl_tab_flag);
  5843. break;
  5844. case 'U':
  5845. if (t2 == 'N')
  5846. v->init(false, otl_var_unsigned_int, sizeof(unsigned),
  5847. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5848. &adb.get_connect_struct(), pl_tab_flag);
  5849. #if defined(OTL_UBIGINT)
  5850. else if (t2 == 'B')
  5851. v->init(false, TConnectStruct::var_ubigint,
  5852. TConnectStruct::ubigint_size,
  5853. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5854. &adb.get_connect_struct(), pl_tab_flag);
  5855. #endif
  5856. break;
  5857. case 'R':
  5858. if (t2 == 'E' && t3 == 'F')
  5859. v->init(false, otl_var_refcur, 1,
  5860. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5861. &adb.get_connect_struct(), 0);
  5862. else if (t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '('))
  5863. v->init(false, otl_var_raw, size,
  5864. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5865. &adb.get_connect_struct(), pl_tab_flag);
  5866. else if (t2 == 'A' && t3 == 'W')
  5867. v->init(false, otl_var_raw_long, adb.get_max_long_size(),
  5868. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5869. &adb.get_connect_struct());
  5870. break;
  5871. case 'S':
  5872. #if defined(OTL_ORA_SDO_GEOMETRY)
  5873. if(t2 == 'D')
  5874. v->init(false, otl_var_sdo_geometry, adb.get_max_long_size(),
  5875. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5876. &adb.get_connect_struct(),0,adb.get_connect_struct().getGeometryTDO());
  5877. else
  5878. #endif
  5879. v->init(false, otl_var_short, sizeof(short),
  5880. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5881. &adb.get_connect_struct(), pl_tab_flag);
  5882. break;
  5883. case 'L':
  5884. if (t2 == 'O' && t3 == 'N')
  5885. v->init(false, otl_var_long_int, sizeof(long),
  5886. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5887. &adb.get_connect_struct(), pl_tab_flag);
  5888. else if (t2 == 'T' && t3 == 'Z')
  5889. v->init(false, otl_var_ltz_timestamp, sizeof(TTimestampStruct),
  5890. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5891. &adb.get_connect_struct(), pl_tab_flag);
  5892. else {
  5893. delete v;
  5894. v = nullptr;
  5895. }
  5896. break;
  5897. case 'T':
  5898. if (t2 == 'Z')
  5899. v->init(false, otl_var_tz_timestamp, sizeof(TTimestampStruct),
  5900. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5901. &adb.get_connect_struct(), pl_tab_flag);
  5902. else if (t2 == 'I' && t3 == 'M')
  5903. v->init(false, otl_var_timestamp, sizeof(TTimestampStruct),
  5904. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5905. &adb.get_connect_struct(), pl_tab_flag);
  5906. else {
  5907. delete v;
  5908. v = nullptr;
  5909. }
  5910. break;
  5911. case 'V':
  5912. v->init(false, otl_var_varchar_long, adb.get_max_long_size(),
  5913. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  5914. &adb.get_connect_struct());
  5915. break;
  5916. default:
  5917. delete v;
  5918. v = nullptr;
  5919. break;
  5920. }
  5921. }
  5922. return v;
  5923. }
  5924. void alloc_host_var_list(otl_tmpl_variable<TVariableStruct> **&vl,
  5925. int &vl_len, OTL_TMPL_CONNECT &adb,
  5926. const int status = def) {
  5927. int j;
  5928. vl_len = 0;
  5929. if (!hv[0]) {
  5930. vl = nullptr;
  5931. return;
  5932. }
  5933. otl_auto_array_ptr<otl_tmpl_variable<TVariableStruct> *> loc_ptr(
  5934. container_size_);
  5935. otl_tmpl_variable<TVariableStruct> **tmp_vl = loc_ptr.get_ptr();
  5936. int i = 0;
  5937. while (hv[i]) {
  5938. otl_tmpl_variable<TVariableStruct> *vp =
  5939. alloc_var(hv[i], inout[i], status, adb, pl_tab_size[i]);
  5940. if (vp == nullptr) {
  5941. int j2;
  5942. for (j2 = 0; j2 < vl_len; ++j2)
  5943. delete tmp_vl[j2];
  5944. vl_len = 0;
  5945. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_12, otl_error_code_12,
  5946. stm_label_ ? stm_label_ : stm_text_, hv[i])));
  5947. }
  5948. vp->set_name_pos(i + 1);
  5949. if (vp) {
  5950. ++vl_len;
  5951. tmp_vl[vl_len - 1] = vp;
  5952. }
  5953. ++i;
  5954. }
  5955. if (vl_len > 0) {
  5956. vl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,vl_len)];
  5957. for (j = 0; j < vl_len; ++j)
  5958. vl[j] = tmp_vl[j];
  5959. }
  5960. }
  5961. private:
  5962. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  5963. public:
  5964. otl_tmpl_ext_hv_decl(const otl_tmpl_ext_hv_decl<
  5965. TVariableStruct, TTimestampStruct, TExceptionStruct, TConnectStruct,
  5966. TCursorStruct> &) = delete;
  5967. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  5968. TConnectStruct, TCursorStruct> &
  5969. operator=(const otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  5970. TExceptionStruct, TConnectStruct,
  5971. TCursorStruct> &) = delete;
  5972. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  5973. otl_tmpl_ext_hv_decl(
  5974. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  5975. TConnectStruct, TCursorStruct> &&) = delete;
  5976. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  5977. TConnectStruct, TCursorStruct> &
  5978. operator=(
  5979. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  5980. TConnectStruct, TCursorStruct> &&) = delete;
  5981. #endif
  5982. private:
  5983. #else
  5984. otl_tmpl_ext_hv_decl(const otl_tmpl_ext_hv_decl<
  5985. TVariableStruct, TTimestampStruct, TExceptionStruct, TConnectStruct,
  5986. TCursorStruct> &)
  5987. : hv(nullptr), inout(nullptr), pl_tab_size(0), array_size(0),
  5988. prev_array_size(0), vst(), len(0), stm_text_(nullptr),
  5989. stm_label_(nullptr), container_size_(0), has_plsql_tabs_or_refcur_(0) {}
  5990. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  5991. TConnectStruct, TCursorStruct> &
  5992. operator=(const otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  5993. TExceptionStruct, TConnectStruct,
  5994. TCursorStruct> &) {
  5995. return *this;
  5996. }
  5997. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  5998. otl_tmpl_ext_hv_decl(
  5999. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  6000. TConnectStruct, TCursorStruct> &&)
  6001. : hv(nullptr), inout(nullptr), pl_tab_size(0), array_size(0),
  6002. prev_array_size(0), vst(), len(0), stm_text_(nullptr),
  6003. stm_label_(nullptr), container_size_(0), has_plsql_tabs_or_refcur_(0) {}
  6004. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  6005. TConnectStruct, TCursorStruct> &
  6006. operator=(
  6007. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  6008. TConnectStruct, TCursorStruct> &&) {
  6009. return *this;
  6010. }
  6011. #endif
  6012. #endif
  6013. };
  6014. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  6015. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
  6016. OTL_TYPE_NAME TSelectCursorStruct>
  6017. class otl_tmpl_select_cursor : public OTL_TMPL_CURSOR {
  6018. protected:
  6019. int cur_row;
  6020. int cur_size;
  6021. int row_count;
  6022. int array_size;
  6023. int prefetch_array_size;
  6024. TSelectCursorStruct select_cursor_struct;
  6025. otl_select_struct_override local_override;
  6026. void *master_stream_ptr_;
  6027. public:
  6028. TSelectCursorStruct &get_select_cursor_struct() {
  6029. return select_cursor_struct;
  6030. }
  6031. otl_tmpl_select_cursor(OTL_TMPL_CONNECT &pdb, void *master_stream_ptr,
  6032. const otl_stream_buffer_size_type arr_size = 1,
  6033. const char *sqlstm_label = nullptr)
  6034. : OTL_TMPL_CURSOR(pdb), cur_row(-1), cur_size(0), row_count(0),
  6035. array_size(0), prefetch_array_size(0), select_cursor_struct(),
  6036. local_override(), master_stream_ptr_(master_stream_ptr) {
  6037. local_override.reset();
  6038. if (sqlstm_label != nullptr) {
  6039. if (this->stm_label != nullptr) {
  6040. delete[] this->stm_label;
  6041. this->stm_label = nullptr;
  6042. }
  6043. size_t len = strlen(sqlstm_label) + 1;
  6044. this->stm_label = new char[len];
  6045. OTL_STRCPY_S(this->stm_label, len, sqlstm_label);
  6046. }
  6047. select_cursor_struct.set_arr_size(arr_size, array_size,
  6048. prefetch_array_size);
  6049. select_cursor_struct.init(array_size);
  6050. }
  6051. otl_tmpl_select_cursor() : OTL_TMPL_CURSOR(), master_stream_ptr_(nullptr) {}
  6052. void open(OTL_TMPL_CONNECT &db, otl_stream_buffer_size_type arr_size = 1) {
  6053. local_override.reset();
  6054. cur_row = -1;
  6055. row_count = 0;
  6056. cur_size = 0;
  6057. array_size = arr_size;
  6058. OTL_TMPL_CURSOR::open(db);
  6059. }
  6060. void close(const char = 'N') {
  6061. local_override.reset();
  6062. OTL_TMPL_CURSOR::close();
  6063. }
  6064. OTL_NODISCARD int first(void) {
  6065. if (!OTL_TMPL_CURSOR::connected)
  6066. return 0;
  6067. select_cursor_struct.set_prefetch_size(prefetch_array_size);
  6068. int rc = select_cursor_struct.first(this->cursor_struct, cur_row, cur_size,
  6069. row_count, this->eof_data, array_size);
  6070. OTL_TRACE_FIRST_FETCH
  6071. if (!rc) {
  6072. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  6073. OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label
  6074. ? this->stm_label
  6075. : this->stm_text)));
  6076. }
  6077. return cur_size != 0;
  6078. }
  6079. OTL_NODISCARD int next_throw(void) {
  6080. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  6081. OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label
  6082. ? this->stm_label
  6083. : this->stm_text)));
  6084. }
  6085. OTL_NODISCARD int next(void) {
  6086. if (!this->connected)
  6087. return 0;
  6088. if (cur_row == -1)
  6089. return first();
  6090. int rc = select_cursor_struct.next(this->cursor_struct, cur_row, cur_size,
  6091. row_count, this->eof_data, array_size);
  6092. if (!rc) {
  6093. return next_throw();
  6094. }
  6095. OTL_TRACE_NEXT_FETCH
  6096. return cur_size != 0;
  6097. }
  6098. private:
  6099. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  6100. public:
  6101. otl_tmpl_select_cursor(const otl_tmpl_select_cursor &) = delete;
  6102. otl_tmpl_select_cursor &operator=(const otl_tmpl_select_cursor &) = delete;
  6103. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  6104. otl_tmpl_select_cursor(otl_tmpl_select_cursor &&) = delete;
  6105. otl_tmpl_select_cursor &operator=(otl_tmpl_select_cursor &&) = delete;
  6106. #endif
  6107. private:
  6108. #else
  6109. otl_tmpl_select_cursor(const otl_tmpl_select_cursor &)
  6110. : OTL_TMPL_CURSOR(), cur_row(-1), cur_size(0), row_count(0),
  6111. array_size(0), prefetch_array_size(0), select_cursor_struct(),
  6112. local_override() {}
  6113. otl_tmpl_select_cursor &operator=(const otl_tmpl_select_cursor &) {
  6114. return *this;
  6115. }
  6116. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  6117. otl_tmpl_select_cursor(otl_tmpl_select_cursor &&)
  6118. : OTL_TMPL_CURSOR(), cur_row(-1), cur_size(0), row_count(0),
  6119. array_size(0), prefetch_array_size(0), select_cursor_struct(),
  6120. local_override() {}
  6121. otl_tmpl_select_cursor &operator=(otl_tmpl_select_cursor &&) { return *this; }
  6122. #endif
  6123. #endif
  6124. };
  6125. #if defined(OTL_ORA8) || defined(OTL_ODBC)
  6126. #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  6127. #define OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_mode_enum::
  6128. enum class otl_lob_stream_mode_enum : unsigned char {
  6129. otl_lob_stream_read_mode = 1,
  6130. otl_lob_stream_write_mode = 2,
  6131. otl_lob_stream_zero_mode = 3
  6132. };
  6133. #else
  6134. #define OTL_LOB_STREAM_MODE_ENUM
  6135. typedef unsigned char otl_lob_stream_mode_enum;
  6136. const otl_lob_stream_mode_enum otl_lob_stream_read_mode = 1;
  6137. const otl_lob_stream_mode_enum otl_lob_stream_write_mode = 2;
  6138. const otl_lob_stream_mode_enum otl_lob_stream_zero_mode = 3;
  6139. #endif
  6140. #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED)
  6141. #define OTL_LOB_STREAM_PIECE_ENUM otl_lob_stream_piece_enum::
  6142. enum class otl_lob_stream_piece_enum : unsigned char {
  6143. otl_lob_stream_first_piece = 1,
  6144. otl_lob_stream_next_piece = 2,
  6145. otl_lob_stream_las_piece = 3
  6146. };
  6147. #else
  6148. #define OTL_LOB_STREAM_MODE_ENUM
  6149. typedef unsigned char otl_lob_stream_piece_enum;
  6150. const otl_lob_stream_piece_enum otl_lob_stream_first_piece = 1;
  6151. const otl_lob_stream_piece_enum otl_lob_stream_next_piece = 2;
  6152. const otl_lob_stream_piece_enum otl_lob_stream_last_piece = 3;
  6153. #endif
  6154. class otl_lob_stream_generic {
  6155. protected:
  6156. int mode;
  6157. int retcode;
  6158. int ndx;
  6159. int offset;
  6160. int lob_len;
  6161. int in_destructor;
  6162. int eof_flag;
  6163. int lob_is_null;
  6164. bool ora_lob;
  6165. public:
  6166. OTL_NODISCARD int get_ora_lob() const { return ora_lob; }
  6167. otl_lob_stream_generic(const bool aora_lob = true)
  6168. : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0),
  6169. eof_flag(0), lob_is_null(0), ora_lob(aora_lob) {}
  6170. virtual ~otl_lob_stream_generic() OTL_THROWS_OTL_EXCEPTION2 {}
  6171. virtual void init(void *avar, void *aconnect, void *acursor, int andx,
  6172. int amode, const int alob_is_null = 0) = 0;
  6173. virtual void set_len(const int new_len = 0) = 0;
  6174. virtual otl_lob_stream_generic &operator<<(const otl_long_string &s) = 0;
  6175. virtual otl_lob_stream_generic &operator>>(otl_long_string &s) = 0;
  6176. #if (defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)) && \
  6177. !defined(OTL_UNICODE)
  6178. virtual otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s) = 0;
  6179. virtual otl_lob_stream_generic &operator>>(OTL_STRING_CONTAINER &s) = 0;
  6180. virtual void setStringBuffer(const int chunk_size) = 0;
  6181. #endif
  6182. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  6183. virtual otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s) = 0;
  6184. #endif
  6185. OTL_NODISCARD virtual int eof(void) = 0;
  6186. OTL_NODISCARD virtual int len(void) = 0;
  6187. OTL_NODISCARD virtual bool is_initialized(void) = 0;
  6188. virtual void close(bool dont_throw_size_doesnt_match_exception = false) = 0;
  6189. private:
  6190. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  6191. public:
  6192. otl_lob_stream_generic(const otl_lob_stream_generic &) = delete;
  6193. otl_lob_stream_generic &operator=(const otl_lob_stream_generic &) = delete;
  6194. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  6195. otl_lob_stream_generic(otl_lob_stream_generic &&) = delete;
  6196. otl_lob_stream_generic &operator=(otl_lob_stream_generic &&) = delete;
  6197. #endif
  6198. private:
  6199. #else
  6200. otl_lob_stream_generic(const otl_lob_stream_generic &)
  6201. : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0),
  6202. eof_flag(0), lob_is_null(0), ora_lob(false) {}
  6203. otl_lob_stream_generic &operator=(const otl_lob_stream_generic &) {
  6204. return *this;
  6205. }
  6206. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  6207. otl_lob_stream_generic(otl_lob_stream_generic &&)
  6208. : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0),
  6209. eof_flag(0), lob_is_null(0), ora_lob(false) {}
  6210. otl_lob_stream_generic &operator=(otl_lob_stream_generic &&) { return *this; }
  6211. #endif
  6212. #endif
  6213. };
  6214. #endif
  6215. #if defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) || \
  6216. defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) || \
  6217. defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  6218. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6219. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6220. #endif
  6221. #else
  6222. #if defined(_MSC_VER) && (_MSC_VER <= 1300)
  6223. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6224. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6225. #endif
  6226. #endif
  6227. #if defined(__SUNPRO_CC) || defined(__HP_aCC) || defined(__BORLANDC__)
  6228. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6229. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6230. #endif
  6231. #endif
  6232. #if defined(__IBMC__) || defined(__IBMCPP__) || defined(__xlC__)
  6233. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6234. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6235. #endif
  6236. #endif
  6237. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
  6238. (__GNUC__ * 100 + __GNUC_MINOR__ == 400)
  6239. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6240. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6241. #endif
  6242. #endif
  6243. #if defined(__GNUC__) && (__GNUC__ <= 3)
  6244. #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6245. #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT
  6246. #endif
  6247. #endif
  6248. #endif
  6249. #if defined(OTL_ORA_SDO_GEOMETRY)
  6250. struct oci_spatial_geometry;
  6251. #endif
  6252. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) || \
  6253. defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  6254. #include <array>
  6255. #endif
  6256. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  6257. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
  6258. OTL_TYPE_NAME TSelectCursorStruct, OTL_TYPE_NAME TTimestampStruct>
  6259. class otl_tmpl_select_stream : public OTL_TMPL_SELECT_CURSOR {
  6260. protected:
  6261. otl_column_desc *sl_desc;
  6262. otl_tmpl_variable<TVariableStruct> *sl;
  6263. int sl_len;
  6264. int null_fetched;
  6265. int cur_col;
  6266. int cur_in;
  6267. int executed;
  6268. int eof_status;
  6269. char var_info[256];
  6270. otl_select_struct_override *override_;
  6271. int delay_next;
  6272. bool lob_stream_mode;
  6273. long _rfc;
  6274. long rewind_calls;
  6275. public:
  6276. OTL_NODISCARD int get_select_row_count() const {
  6277. return this->cur_row == -1 ? 0 : this->cur_size - this->cur_row;
  6278. }
  6279. OTL_NODISCARD int get_prefetched_row_count() const { return this->row_count; }
  6280. OTL_NODISCARD int get_row_count() const { return this->row_count; }
  6281. OTL_NODISCARD int get_sl_len() const { return sl_len; }
  6282. OTL_NODISCARD otl_tmpl_variable<TVariableStruct> *get_sl() { return sl; }
  6283. OTL_NODISCARD otl_column_desc *get_sl_desc() { return sl_desc; }
  6284. OTL_NODISCARD long get_rfc() const { return _rfc; }
  6285. void cleanup(void) {
  6286. int i;
  6287. delete[] sl;
  6288. for (i = 0; i < this->vl_len; ++i)
  6289. delete this->vl[i];
  6290. delete[] this->vl;
  6291. delete[] sl_desc;
  6292. }
  6293. virtual ~otl_tmpl_select_stream() OTL_THROWS_OTL_EXCEPTION3 { cleanup(); }
  6294. otl_tmpl_select_stream(otl_select_struct_override *aoverride,
  6295. const otl_stream_buffer_size_type arr_size,
  6296. const char *sqlstm, OTL_TMPL_CONNECT &pdb,
  6297. const int implicit_select = otl_explicit_select,
  6298. const char *sqlstm_label = nullptr)
  6299. : OTL_TMPL_SELECT_CURSOR(pdb, aoverride->get_master_stream_ptr(),
  6300. arr_size, sqlstm_label),
  6301. sl_desc(nullptr), sl(nullptr), sl_len(0), null_fetched(0), cur_col(0),
  6302. cur_in(0), executed(0), eof_status(0), var_info(), override_(nullptr),
  6303. delay_next(0), lob_stream_mode(false), _rfc(0), rewind_calls(0) {
  6304. int i;
  6305. this->select_cursor_struct.set_select_type(implicit_select);
  6306. sl = nullptr;
  6307. sl_len = 0;
  6308. _rfc = 0;
  6309. null_fetched = 0;
  6310. lob_stream_mode = aoverride->get_lob_stream_mode();
  6311. this->retcode = 0;
  6312. sl_desc = nullptr;
  6313. executed = 0;
  6314. cur_in = 0;
  6315. this->stm_text = nullptr;
  6316. eof_status = 1;
  6317. override_ = aoverride;
  6318. bool out_or_inout_variable_flag = false;
  6319. bool bind_var_terminator_is_missing = false;
  6320. {
  6321. size_t len = strlen(sqlstm) + 1;
  6322. this->stm_text = new char[len];
  6323. OTL_STRCPY_S(this->stm_text, len, sqlstm);
  6324. otl_select_struct_override *temp_local_override = &this->local_override;
  6325. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  6326. TConnectStruct, TCursorStruct>
  6327. hvd(this->stm_text, 1, this->stm_label, &temp_local_override, &pdb);
  6328. if (hvd.get_vst(1) > 0 || hvd.get_vst(2) > 0)
  6329. out_or_inout_variable_flag = true;
  6330. hvd.alloc_host_var_list(this->vl, this->vl_len, pdb);
  6331. if (temp_local_override != &this->local_override)
  6332. delete temp_local_override;
  6333. bind_var_terminator_is_missing = hvd.bind_var_terminator_is_missing();
  6334. }
  6335. if (out_or_inout_variable_flag) {
  6336. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_39, otl_error_code_39,
  6337. this->stm_label ? this->stm_label
  6338. : this->stm_text)));
  6339. }
  6340. if (bind_var_terminator_is_missing) {
  6341. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_43, otl_error_code_43,
  6342. this->stm_label ? this->stm_label
  6343. : this->stm_text)));
  6344. }
  6345. try {
  6346. if(implicit_select == otl_direct_exec_select)
  6347. this->parse(1);
  6348. else
  6349. this->parse();
  6350. if (this->select_cursor_struct.get_implicit_cursor()!=otl_implicit_select) {
  6351. get_select_list();
  6352. bind_all();
  6353. } else {
  6354. for (i = 0; i < this->vl_len; ++i)
  6355. this->bind(*this->vl[i]);
  6356. }
  6357. if (this->vl_len == 0) {
  6358. rewind();
  6359. null_fetched = 0;
  6360. }
  6361. }
  6362. catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) {
  6363. cleanup();
  6364. throw;
  6365. }
  6366. if (bind_var_terminator_is_missing) {
  6367. } // this is to fix a compiler warning
  6368. }
  6369. void rewind(void) {
  6370. OTL_TRACE_STREAM_EXECUTION
  6371. int i;
  6372. _rfc = 0;
  6373. ++rewind_calls;
  6374. if (!this->select_cursor_struct.close_select(this->cursor_struct)) {
  6375. OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label
  6376. ? this->stm_label
  6377. : this->stm_text)));
  6378. }
  6379. if(this->select_cursor_struct.get_implicit_cursor()==otl_direct_exec_select &&
  6380. rewind_calls>1){
  6381. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_47, otl_error_code_47,
  6382. this->stm_label ? this->stm_label
  6383. : this->stm_text)));
  6384. }
  6385. if (this->select_cursor_struct.get_implicit_cursor()==otl_implicit_select) {
  6386. this->exec(1, 0, otl_sql_exec_from_select_cursor_class);
  6387. if (sl) {
  6388. delete[] sl;
  6389. sl = nullptr;
  6390. }
  6391. get_select_list();
  6392. for (i = 0; i < sl_len; ++i)
  6393. this->bind(sl[i]);
  6394. }
  6395. eof_status = this->first();
  6396. null_fetched = 0;
  6397. cur_col = -1;
  6398. cur_in = 0;
  6399. executed = 1;
  6400. delay_next = 0;
  6401. }
  6402. void clean(void) {
  6403. _rfc = 0;
  6404. this->cursor_struct.set_canceled(false);
  6405. null_fetched = 0;
  6406. cur_col = -1;
  6407. cur_in = 0;
  6408. executed = 0;
  6409. eof_status = 0;
  6410. delay_next = 0;
  6411. this->cur_row = -1;
  6412. this->row_count = 0;
  6413. this->cur_size = 0;
  6414. if (!this->select_cursor_struct.close_select(this->cursor_struct)) {
  6415. OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label
  6416. ? this->stm_label
  6417. : this->stm_text)));
  6418. }
  6419. }
  6420. OTL_NODISCARD int is_null(void) { return null_fetched; }
  6421. OTL_NODISCARD int eof(void) {
  6422. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  6423. if (cur_col == sl_len - 1) {
  6424. get_next();
  6425. cur_col = -1;
  6426. } else {
  6427. if (delay_next) {
  6428. look_ahead();
  6429. delay_next = 0;
  6430. }
  6431. }
  6432. return !eof_status;
  6433. #else
  6434. if (delay_next) {
  6435. look_ahead();
  6436. delay_next = 0;
  6437. }
  6438. return !eof_status;
  6439. #endif
  6440. }
  6441. OTL_NODISCARD int eof_intern(void) { return !eof_status; }
  6442. void skip_to_end_of_row() {
  6443. check_if_executed();
  6444. if (eof_intern())
  6445. return;
  6446. while (cur_col < sl_len - 1) {
  6447. ++cur_col;
  6448. null_fetched = sl[cur_col].is_null(this->cur_row);
  6449. }
  6450. eof_status = this->next();
  6451. cur_col = 0;
  6452. if (!eof_intern())
  6453. cur_col = -1;
  6454. ++_rfc;
  6455. }
  6456. void skip_to_next_var() {
  6457. check_if_executed();
  6458. if (eof_intern())
  6459. return;
  6460. get_next();
  6461. look_ahead();
  6462. }
  6463. void bind_all(void) {
  6464. int i;
  6465. for (i = 0; i < this->vl_len; ++i)
  6466. this->bind(*this->vl[i]);
  6467. for (i = 0; i < sl_len; ++i)
  6468. this->bind(sl[i]);
  6469. }
  6470. void get_select_list(void) {
  6471. int j;
  6472. otl_auto_array_ptr<otl_column_desc> loc_ptr(otl_var_list_size);
  6473. otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr();
  6474. int sld_tmp_len = 0;
  6475. int ftype, elem_size, i;
  6476. for (i = 1; this->describe_column(sl_desc_tmp[i - 1], i); ++i) {
  6477. int temp_code_type = otl_tmpl_variable<TVariableStruct>::int2ext(
  6478. sl_desc_tmp[i - 1].dbtype);
  6479. if (temp_code_type == otl_unsupported_type) {
  6480. #ifdef OTL_ORA_SDO_GEOMETRY
  6481. if(sl_desc_tmp[i - 1].name_type &&
  6482. strcmp(sl_desc_tmp[i - 1].name_type, "SDO_GEOMETRY") != 0){
  6483. otl_var_info_col3(i - 1, sl_desc_tmp[i - 1].dbtype,
  6484. sl_desc_tmp[i - 1].name, this->var_info,
  6485. sizeof(this->var_info));
  6486. OTL_THROW((OTL_TMPL_EXCEPTION(
  6487. otl_error_msg_27, otl_error_code_27,
  6488. this->stm_label ? this->stm_label : this->stm_text, this->var_info)));
  6489. }
  6490. #else
  6491. otl_var_info_col3(i - 1, sl_desc_tmp[i - 1].dbtype,
  6492. sl_desc_tmp[i - 1].name, this->var_info,
  6493. sizeof(this->var_info));
  6494. OTL_THROW((OTL_TMPL_EXCEPTION(
  6495. otl_error_msg_27, otl_error_code_27,
  6496. this->stm_label ? this->stm_label : this->stm_text, this->var_info)));
  6497. #endif // OTL_ORA_SDO_GEOMETRY
  6498. }
  6499. ++sld_tmp_len;
  6500. if (sld_tmp_len == loc_ptr.get_arr_size()) {
  6501. loc_ptr.double_size();
  6502. sl_desc_tmp = loc_ptr.get_ptr();
  6503. }
  6504. }
  6505. sl_len = sld_tmp_len;
  6506. if (sl) {
  6507. delete[] sl;
  6508. sl = nullptr;
  6509. }
  6510. sl = new otl_tmpl_variable<TVariableStruct>[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  6511. int max_long_size = this->adb->get_max_long_size();
  6512. for (j = 0; j < sl_len; ++j) {
  6513. otl_tmpl_variable<TVariableStruct>::map_ftype(
  6514. sl_desc_tmp[j], max_long_size, ftype, elem_size,
  6515. this->local_override.getLen() > 0 ? this->local_override : *override_,
  6516. j + 1, this->adb->get_connect_struct().get_connection_type());
  6517. sl[j].copy_pos(j + 1);
  6518. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  6519. if (sl_desc_tmp[j].charset_form == 2)
  6520. sl[j].get_var_struct().set_nls_flag(true);
  6521. #endif
  6522. sl[j].init(true, ftype, elem_size,
  6523. OTL_SCAST(otl_stream_buffer_size_type, (this->array_size)),
  6524. &this->adb->get_connect_struct()
  6525. #if defined(OTL_ORA_SDO_GEOMETRY)
  6526. ,0, sl_desc_tmp[j].colOCIType
  6527. #endif
  6528. );
  6529. sl[j].get_var_struct().set_lob_stream_mode(this->lob_stream_mode);
  6530. }
  6531. if (sl_desc) {
  6532. delete[] sl_desc;
  6533. sl_desc = nullptr;
  6534. }
  6535. sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  6536. for (j = 0; j < sl_len; ++j)
  6537. sl_desc[j] = sl_desc_tmp[j];
  6538. }
  6539. void check_if_executed_throw(void) {
  6540. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  6541. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_2, otl_error_code_2,
  6542. this->stm_label ? this->stm_label : this->stm_text,
  6543. nullptr)));
  6544. }
  6545. void check_if_executed(void) {
  6546. if (!executed) {
  6547. check_if_executed_throw();
  6548. }
  6549. }
  6550. OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) {
  6551. int out_type_code;
  6552. if (actual_data_type != 0)
  6553. out_type_code = actual_data_type;
  6554. else
  6555. out_type_code = type_code;
  6556. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  6557. out_type_code, var_info, sizeof(var_info));
  6558. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  6559. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0,
  6560. this->stm_label ? this->stm_label : this->stm_text,
  6561. var_info)));
  6562. }
  6563. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  6564. void strict_check_throw(int type_code) {
  6565. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), type_code,
  6566. var_info, sizeof(var_info));
  6567. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  6568. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0,
  6569. this->stm_label ? this->stm_label : this->stm_text,
  6570. var_info)));
  6571. }
  6572. #endif
  6573. OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) {
  6574. switch (sl[cur_col].get_ftype()) {
  6575. case otl_var_timestamp:
  6576. case otl_var_tz_timestamp:
  6577. case otl_var_ltz_timestamp:
  6578. if (type_code == otl_var_timestamp)
  6579. return 1;
  6580. break;
  6581. default:
  6582. #if defined(OTL_CHECK_OUT_TYPE_FUNC)
  6583. if ((sl[cur_col].get_ftype() == type_code) ||
  6584. OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code))
  6585. return 1;
  6586. break;
  6587. #else
  6588. if (sl[cur_col].get_ftype() == type_code)
  6589. return 1;
  6590. break;
  6591. #endif
  6592. }
  6593. return check_type_throw(type_code, actual_data_type);
  6594. }
  6595. void get_next(void) {
  6596. if (cur_col < sl_len - 1) {
  6597. ++cur_col;
  6598. null_fetched = sl[cur_col].is_null(this->cur_row);
  6599. } else {
  6600. eof_status = this->next();
  6601. cur_col = 0;
  6602. }
  6603. }
  6604. void look_ahead(void) {
  6605. if (cur_col == sl_len - 1) {
  6606. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  6607. #else
  6608. eof_status = this->next();
  6609. cur_col = -1;
  6610. #endif
  6611. ++_rfc;
  6612. }
  6613. }
  6614. OTL_TMPL_SELECT_STREAM &operator>>(char &c) {
  6615. check_if_executed();
  6616. if (eof_intern())
  6617. return *this;
  6618. get_next();
  6619. if (check_type(otl_var_char) && !eof_intern()) {
  6620. c = *OTL_RCAST(char *, sl[cur_col].val(this->cur_row));
  6621. look_ahead();
  6622. }
  6623. return *this;
  6624. }
  6625. OTL_TMPL_SELECT_STREAM &operator>>(unsigned char &c) {
  6626. check_if_executed();
  6627. if (eof_intern())
  6628. return *this;
  6629. get_next();
  6630. if (check_type(otl_var_char) && !eof_intern()) {
  6631. c = *OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  6632. look_ahead();
  6633. }
  6634. return *this;
  6635. }
  6636. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  6637. OTL_TMPL_SELECT_STREAM &operator>>(OTL_STRING_CONTAINER &s) {
  6638. check_if_executed();
  6639. if (eof_intern())
  6640. return *this;
  6641. get_next();
  6642. switch (sl[cur_col].get_ftype()) {
  6643. case otl_var_raw: {
  6644. int len2;
  6645. if (!eof_intern()) {
  6646. unsigned char *c =
  6647. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  6648. if (sl[cur_col].get_var_struct().get_otl_adapter() ==
  6649. OTL_ADAPTER_ENUM otl_ora8_adapter) {
  6650. len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c));
  6651. c += sizeof(short int);
  6652. } else
  6653. len2 = sl[cur_col].get_len(this->cur_row);
  6654. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  6655. !defined(OTL_USER_DEFINED_STRING_CLASS_ON))
  6656. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len2));
  6657. #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE))
  6658. s.assign(OTL_RCAST(char *, c), len2);
  6659. #elif defined(OTL_ACE)
  6660. s.set(OTL_RCAST(char *, c), len2, 1);
  6661. #endif
  6662. look_ahead();
  6663. }
  6664. } break;
  6665. case otl_var_char:
  6666. if (!eof_intern()) {
  6667. #if defined(OTL_ACE)
  6668. s.set(OTL_RCAST(char *, sl[cur_col].val(this->cur_row)), 1);
  6669. #else
  6670. s = OTL_RCAST(char *, sl[cur_col].val(this->cur_row));
  6671. #endif
  6672. look_ahead();
  6673. }
  6674. break;
  6675. #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \
  6676. defined(OTL_ACE)
  6677. case otl_var_varchar_long:
  6678. case otl_var_raw_long:
  6679. if (!eof_intern()) {
  6680. unsigned char *c =
  6681. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  6682. int len = sl[cur_col].get_len(this->cur_row);
  6683. int buf_sz = sl[cur_col].get_elem_size();
  6684. if (len > buf_sz || len<0)
  6685. len = buf_sz;
  6686. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  6687. !defined(OTL_USER_DEFINED_STRING_CLASS_ON))
  6688. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len));
  6689. #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE))
  6690. s.assign(OTL_RCAST(char *, c), len);
  6691. #elif defined(OTL_ACE)
  6692. s.set(OTL_RCAST(char *, c), len, 1);
  6693. #endif
  6694. look_ahead();
  6695. }
  6696. break;
  6697. case otl_var_blob:
  6698. case otl_var_clob:
  6699. if (!eof_intern()) {
  6700. int len = 0;
  6701. int max_long_sz = this->adb->get_max_long_size();
  6702. otl_auto_array_ptr<unsigned char> loc_ptr(max_long_sz);
  6703. unsigned char *temp_buf = loc_ptr.get_ptr();
  6704. int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf,
  6705. max_long_sz, len);
  6706. if (rc == 0) {
  6707. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  6708. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  6709. this->stm_label ? this->stm_label
  6710. : this->stm_text)));
  6711. }
  6712. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  6713. !defined(OTL_USER_DEFINED_STRING_CLASS_ON))
  6714. s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len));
  6715. #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE))
  6716. s.assign(OTL_RCAST(char *, temp_buf), len);
  6717. #elif defined(OTL_ACE)
  6718. s.set(OTL_RCAST(char *, temp_buf), len, 1);
  6719. #endif
  6720. look_ahead();
  6721. }
  6722. break;
  6723. #endif
  6724. default:
  6725. (void)check_type(otl_var_char);
  6726. } // switch
  6727. return *this;
  6728. }
  6729. #endif
  6730. OTL_TMPL_SELECT_STREAM &operator>>(char *s) {
  6731. check_if_executed();
  6732. if (eof_intern())
  6733. return *this;
  6734. get_next();
  6735. if (check_type(otl_var_char) && !eof_intern()) {
  6736. otl_strcpy(
  6737. OTL_RCAST(unsigned char *, s),
  6738. OTL_RCAST(const unsigned char *, sl[cur_col].val(this->cur_row)));
  6739. look_ahead();
  6740. }
  6741. return *this;
  6742. }
  6743. void getString(char *s, int max_size) {
  6744. check_if_executed();
  6745. if (eof_intern())
  6746. return;
  6747. get_next();
  6748. if (check_type(otl_var_char) && !eof_intern()) {
  6749. if(max_size<sl[cur_col].get_len(this->cur_row)){
  6750. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), const_STD_CHAR_ARRAY_code,
  6751. var_info, sizeof(var_info));
  6752. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
  6753. TCursorStruct>(otl_error_msg_45,
  6754. otl_error_code_45,
  6755. this->stm_label ? this->stm_label : this->stm_text,
  6756. this->var_info)));
  6757. }
  6758. otl_strcpy(
  6759. OTL_RCAST(unsigned char *, s),
  6760. OTL_RCAST(const unsigned char *, sl[cur_col].val(this->cur_row)));
  6761. look_ahead();
  6762. }
  6763. }
  6764. #if defined(OTL_UNICODE_STRING_TYPE)
  6765. OTL_TMPL_SELECT_STREAM &operator<<(const OTL_UNICODE_STRING_TYPE &s) {
  6766. check_in_var();
  6767. if (check_in_type(otl_var_char, 1)) {
  6768. int overflow;
  6769. #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE)
  6770. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  6771. OTL_RCAST(unsigned char *,
  6772. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *,
  6773. s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())),
  6774. #else
  6775. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  6776. OTL_RCAST(unsigned char *,
  6777. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())),
  6778. #endif
  6779. overflow, this->vl[cur_in]->get_elem_size(),
  6780. OTL_SCAST(int, s.length()));
  6781. if (overflow) {
  6782. char temp_var_info[256];
  6783. otl_var_info_var(this->vl[cur_in]->get_name(),
  6784. this->vl[cur_in]->get_ftype(), otl_var_char,
  6785. temp_var_info, sizeof(temp_var_info));
  6786. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  6787. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  6788. OTL_THROW((OTL_TMPL_EXCEPTION(
  6789. otl_error_msg_4, otl_error_code_4,
  6790. this->stm_label ? this->stm_label : this->stm_text, temp_var_info,
  6791. OTL_RCAST(const void *, s.c_str()),
  6792. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  6793. #else
  6794. OTL_THROW((OTL_TMPL_EXCEPTION(
  6795. otl_error_msg_4, otl_error_code_4,
  6796. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  6797. #endif
  6798. }
  6799. this->vl[cur_in]->set_not_null(0);
  6800. }
  6801. get_in_next();
  6802. return *this;
  6803. }
  6804. #endif
  6805. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  6806. OTL_TMPL_SELECT_STREAM &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) {
  6807. check_in_var();
  6808. if (check_in_type(otl_var_char, 1)) {
  6809. int overflow;
  6810. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  6811. OTL_RCAST(unsigned char *,
  6812. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())),
  6813. overflow, this->vl[cur_in]->get_elem_size(),
  6814. OTL_SCAST(int, s.length()));
  6815. if (overflow) {
  6816. char temp_var_info[256];
  6817. otl_var_info_var(this->vl[cur_in]->get_name(),
  6818. this->vl[cur_in]->get_ftype(), otl_var_char,
  6819. temp_var_info, sizeof(temp_var_info));
  6820. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  6821. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  6822. OTL_THROW((OTL_TMPL_EXCEPTION(
  6823. otl_error_msg_4, otl_error_code_4,
  6824. this->stm_label ? this->stm_label : this->stm_text, temp_var_info,
  6825. OTL_RCAST(const void *, s.data()),
  6826. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  6827. #else
  6828. OTL_THROW((OTL_TMPL_EXCEPTION(
  6829. otl_error_msg_4, otl_error_code_4,
  6830. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  6831. #endif
  6832. }
  6833. this->vl[cur_in]->set_not_null(0);
  6834. }
  6835. get_in_next();
  6836. return *this;
  6837. }
  6838. #endif
  6839. #if defined(OTL_UNICODE_STRING_TYPE)
  6840. OTL_TMPL_SELECT_STREAM &operator>>(OTL_UNICODE_STRING_TYPE &s) {
  6841. check_if_executed();
  6842. if (eof_intern())
  6843. return *this;
  6844. get_next();
  6845. switch (sl[cur_col].get_ftype()) {
  6846. case otl_var_char:
  6847. if (!eof_intern()) {
  6848. #if defined(OTL_ODBC) || defined(DB2_CLI)
  6849. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  6850. #else
  6851. #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR)
  6852. OTL_UNICODE_CHAR_TYPE *temp_s =
  6853. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  6854. OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s);
  6855. #else
  6856. OTL_UNICODE_CHAR_TYPE *temp_s =
  6857. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  6858. s.assign(temp_s + 1, *temp_s);
  6859. #endif
  6860. #endif
  6861. look_ahead();
  6862. }
  6863. break;
  6864. case otl_var_varchar_long:
  6865. if (!eof_intern()) {
  6866. #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES)
  6867. int source_len = sl[cur_col].get_var_struct().get_len(this->cur_row);
  6868. OTL_CHAR *source =
  6869. OTL_RCAST(OTL_CHAR *, sl[cur_col].val(this->cur_row));
  6870. s.assign(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, source),
  6871. OTL_SCAST(size_t, source_len));
  6872. #else
  6873. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  6874. #endif
  6875. look_ahead();
  6876. }
  6877. break;
  6878. case otl_var_clob:
  6879. if (!eof_intern()) {
  6880. int len = 0;
  6881. int max_long_sz = this->adb->get_max_long_size();
  6882. otl_auto_array_ptr<unsigned short> loc_ptr(max_long_sz);
  6883. unsigned char *temp_buf = OTL_RCAST(unsigned char *, loc_ptr.get_ptr());
  6884. int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf,
  6885. max_long_sz, len);
  6886. if (rc == 0) {
  6887. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  6888. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  6889. this->stm_label ? this->stm_label
  6890. : this->stm_text)));
  6891. }
  6892. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, temp_buf);
  6893. look_ahead();
  6894. }
  6895. break;
  6896. default:
  6897. (void)check_type(otl_var_char);
  6898. }
  6899. return *this;
  6900. }
  6901. #endif
  6902. OTL_TMPL_SELECT_STREAM &operator>>(unsigned char *s) {
  6903. check_if_executed();
  6904. if (eof_intern())
  6905. return *this;
  6906. get_next();
  6907. if (check_type(otl_var_char) && !eof_intern()) {
  6908. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  6909. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)),
  6910. sl[cur_col].get_len(this->cur_row));
  6911. look_ahead();
  6912. }
  6913. return *this;
  6914. }
  6915. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  6916. void getString(char16_t *s, int max_size) {
  6917. check_if_executed();
  6918. if (eof_intern())
  6919. return;
  6920. get_next();
  6921. if (check_type(otl_var_char) && !eof_intern()) {
  6922. if(max_size<sl[cur_col].get_len(this->cur_row)){
  6923. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), const_STD_UNICODE_CHAR_ARRAY_code,
  6924. var_info, sizeof(var_info));
  6925. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
  6926. TCursorStruct>(otl_error_msg_46,
  6927. otl_error_code_46,
  6928. this->stm_label ? this->stm_label : this->stm_text,
  6929. this->var_info)));
  6930. }
  6931. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  6932. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)),
  6933. sl[cur_col].get_len(this->cur_row));
  6934. look_ahead();
  6935. }
  6936. }
  6937. #endif
  6938. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  6939. #if !defined(OTL_D1)
  6940. #define OTL_D1(T, T_type) \
  6941. OTL_TMPL_SELECT_STREAM &operator>>(T &n) { \
  6942. check_if_executed(); \
  6943. if (eof_intern()) \
  6944. return *this; \
  6945. get_next(); \
  6946. if (!eof_intern()) { \
  6947. int match_found = otl_numeric_convert_T<T, T_type>( \
  6948. sl[cur_col].get_ftype(), sl[cur_col].val(this->cur_row), n); \
  6949. if (!match_found) \
  6950. strict_check_throw(T_type); \
  6951. look_ahead(); \
  6952. } \
  6953. return *this; \
  6954. }
  6955. #endif
  6956. #else
  6957. #if defined(OTL_ORA_SDO_GEOMETRY)
  6958. OTL_TMPL_SELECT_STREAM &operator >> (oci_spatial_geometry &s) {
  6959. check_if_executed();
  6960. if(eof_intern())
  6961. return *this;
  6962. get_next();
  6963. if(check_type(otl_var_sdo_geometry) && !eof_intern()){
  6964. (void)sl[cur_col].get_var_struct().read_geometry(s, this->cur_row);
  6965. look_ahead();
  6966. }
  6967. return *this;
  6968. }
  6969. #endif
  6970. #if !defined(OTL_D1)
  6971. #define OTL_D1(T, T_type) \
  6972. OTL_TMPL_SELECT_STREAM &operator>>(T &n) { \
  6973. check_if_executed(); \
  6974. if (eof_intern()) \
  6975. return *this; \
  6976. get_next(); \
  6977. if (!eof_intern()) { \
  6978. int match_found = otl_numeric_convert_T( \
  6979. sl[cur_col].get_ftype(), sl[cur_col].val(this->cur_row), n); \
  6980. if (!match_found) { \
  6981. if (check_type(otl_var_double, T_type)) \
  6982. n = OTL_PCONV(T, double, sl[cur_col].val(this->cur_row)); \
  6983. } \
  6984. look_ahead(); \
  6985. } \
  6986. return *this; \
  6987. }
  6988. #endif
  6989. #endif
  6990. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  6991. OTL_D1(int, otl_var_int)
  6992. #if defined(OTL_BIGINT)
  6993. OTL_D1(OTL_BIGINT, otl_var_bigint)
  6994. #endif
  6995. #if defined(OTL_UBIGINT)
  6996. OTL_D1(OTL_UBIGINT, otl_var_ubigint)
  6997. #endif
  6998. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  6999. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \
  7000. !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  7001. OTL_D1(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  7002. #endif
  7003. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  7004. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \
  7005. !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS)
  7006. OTL_D1(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  7007. #endif
  7008. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  7009. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \
  7010. !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  7011. OTL_D1(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  7012. #endif
  7013. OTL_D1(unsigned, otl_var_unsigned_int)
  7014. OTL_D1(long, otl_var_long_int)
  7015. OTL_D1(short, otl_var_short)
  7016. OTL_D1(float, otl_var_float)
  7017. OTL_D1(double, otl_var_double)
  7018. #else
  7019. template<OTL_TYPE_NAME T,const int T_type> OTL_D1(T,T_type)
  7020. #endif
  7021. OTL_TMPL_SELECT_STREAM &operator>>(TTimestampStruct &t) {
  7022. check_if_executed();
  7023. if (eof_intern())
  7024. return *this;
  7025. get_next();
  7026. if (check_type(otl_var_timestamp) && !eof_intern()) {
  7027. TTimestampStruct *tm =
  7028. OTL_RCAST(TTimestampStruct *, sl[cur_col].val(this->cur_row));
  7029. int rc = sl[cur_col].get_var_struct().read_dt(&t, tm,
  7030. sizeof(TTimestampStruct));
  7031. if (rc == 0) {
  7032. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7033. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7034. this->stm_label ? this->stm_label
  7035. : this->stm_text)));
  7036. }
  7037. look_ahead();
  7038. }
  7039. return *this;
  7040. }
  7041. OTL_TMPL_SELECT_STREAM &operator>>(otl_long_string &s) {
  7042. check_if_executed();
  7043. if (eof_intern())
  7044. return *this;
  7045. get_next();
  7046. switch (sl[cur_col].get_ftype()) {
  7047. case otl_var_raw_long: {
  7048. if (s.get_unicode_flag()) {
  7049. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  7050. this->stm_label ? this->stm_label
  7051. : this->stm_text)));
  7052. }
  7053. if (!eof_intern()) {
  7054. unsigned char *c =
  7055. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  7056. int len2 = sl[cur_col].get_len(this->cur_row);
  7057. if (len2 > s.get_buf_size())
  7058. len2 = s.get_buf_size();
  7059. otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype());
  7060. s.set_len(len2);
  7061. look_ahead();
  7062. }
  7063. } break;
  7064. case otl_var_varchar_long: {
  7065. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  7066. if (s.get_unicode_flag() != in_unicode_mode) {
  7067. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  7068. this->stm_label ? this->stm_label
  7069. : this->stm_text)));
  7070. }
  7071. if (!eof_intern()) {
  7072. if (sl[cur_col].get_var_struct().get_otl_adapter() ==
  7073. OTL_ADAPTER_ENUM otl_ora8_adapter) {
  7074. #if defined(OTL_UNICODE)
  7075. int len2 = 0;
  7076. OTL_CHAR *source =
  7077. OTL_RCAST(OTL_CHAR *, sl[cur_col].val(this->cur_row));
  7078. OTL_CHAR *target = OTL_RCAST(OTL_CHAR *, s.v);
  7079. #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES)
  7080. int source_len = sl[cur_col].get_var_struct().get_len(this->cur_row);
  7081. while (*source && len2 < s.get_buf_size() && len2 < source_len) {
  7082. *target++ = *source++;
  7083. ++len2;
  7084. }
  7085. #else
  7086. while (*source && len2 < s.get_buf_size()) {
  7087. *target++ = *source++;
  7088. ++len2;
  7089. }
  7090. #endif
  7091. s.null_terminate_string(len2);
  7092. s.set_len(len2);
  7093. look_ahead();
  7094. #else
  7095. unsigned char *c =
  7096. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  7097. int len2 = sl[cur_col].get_len(this->cur_row);
  7098. if (len2 > s.get_buf_size())
  7099. len2 = s.get_buf_size();
  7100. otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype());
  7101. s.null_terminate_string(len2);
  7102. s.set_len(len2);
  7103. look_ahead();
  7104. #endif
  7105. } else {
  7106. unsigned char *c =
  7107. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  7108. int len2 = sl[cur_col].get_len(this->cur_row);
  7109. if (len2 > s.get_buf_size())
  7110. len2 = s.get_buf_size();
  7111. otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype());
  7112. s.null_terminate_string(len2);
  7113. s.set_len(len2);
  7114. look_ahead();
  7115. }
  7116. }
  7117. } break;
  7118. case otl_var_raw: {
  7119. if (s.get_unicode_flag()) {
  7120. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  7121. this->stm_label ? this->stm_label
  7122. : this->stm_text)));
  7123. }
  7124. if (!eof_intern()) {
  7125. unsigned char *c =
  7126. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  7127. if (sl[cur_col].get_var_struct().get_otl_adapter() ==
  7128. OTL_ADAPTER_ENUM otl_ora8_adapter) {
  7129. int len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c));
  7130. otl_memcpy(s.v, c + sizeof(short int), len2, sl[cur_col].get_ftype());
  7131. s.set_len(len2);
  7132. } else {
  7133. int len2 = sl[cur_col].get_len(this->cur_row);
  7134. if (len2 > s.get_buf_size())
  7135. len2 = s.get_buf_size();
  7136. otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype());
  7137. s.set_len(len2);
  7138. }
  7139. look_ahead();
  7140. }
  7141. } break;
  7142. case otl_var_blob:
  7143. case otl_var_clob: {
  7144. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  7145. if (!s.get_unicode_flag() && in_unicode_mode &&
  7146. sl[cur_col].get_ftype() == otl_var_clob) {
  7147. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  7148. this->stm_label ? this->stm_label
  7149. : this->stm_text)));
  7150. } else if (s.get_unicode_flag() &&
  7151. sl[cur_col].get_ftype() == otl_var_blob) {
  7152. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  7153. this->stm_label ? this->stm_label
  7154. : this->stm_text)));
  7155. }
  7156. if (!eof_intern()) {
  7157. int len = 0;
  7158. int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, s.v,
  7159. s.get_buf_size(), len);
  7160. if (rc == 0) {
  7161. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7162. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7163. this->stm_label ? this->stm_label
  7164. : this->stm_text)));
  7165. }
  7166. if (len > s.get_buf_size())
  7167. len = s.get_buf_size();
  7168. s.set_len(len);
  7169. if (sl[cur_col].get_ftype() == otl_var_clob)
  7170. s.null_terminate_string(len);
  7171. look_ahead();
  7172. }
  7173. } break;
  7174. default: {
  7175. char tmp_var_info[256];
  7176. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  7177. otl_var_long_string, tmp_var_info, sizeof(tmp_var_info));
  7178. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7179. OTL_THROW((OTL_TMPL_EXCEPTION(
  7180. otl_error_msg_0, otl_error_code_0,
  7181. this->stm_label ? this->stm_label : this->stm_text, tmp_var_info)));
  7182. }
  7183. }
  7184. return *this;
  7185. }
  7186. #if defined(OTL_ORA8) || defined(OTL_ODBC)
  7187. OTL_TMPL_SELECT_STREAM &operator>>(otl_lob_stream_generic &s) {
  7188. check_if_executed();
  7189. if (eof_intern())
  7190. return *this;
  7191. get_next();
  7192. if (s.get_ora_lob() && (sl[cur_col].get_ftype() == otl_var_blob ||
  7193. sl[cur_col].get_ftype() == otl_var_clob) &&
  7194. !eof_intern()) {
  7195. s.init(OTL_RCAST(void *, &sl[cur_col]), OTL_RCAST(void *, this->adb),
  7196. OTL_RCAST(void *, this), this->cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode),
  7197. this->is_null());
  7198. delay_next = 1;
  7199. } else if ((sl[cur_col].get_ftype() == otl_var_varchar_long ||
  7200. sl[cur_col].get_ftype() == otl_var_raw_long) &&
  7201. !eof_intern()) {
  7202. s.init(OTL_RCAST(void *, &sl[cur_col]), OTL_RCAST(void *, this->adb),
  7203. OTL_RCAST(void *, this), this->cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode));
  7204. delay_next = 1;
  7205. } else {
  7206. char tmp_var_info[256];
  7207. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  7208. otl_var_long_string, tmp_var_info, sizeof(tmp_var_info));
  7209. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7210. OTL_THROW((OTL_TMPL_EXCEPTION(
  7211. otl_error_msg_0, otl_error_code_0,
  7212. this->stm_label ? this->stm_label : this->stm_text, tmp_var_info)));
  7213. }
  7214. return *this;
  7215. }
  7216. #endif
  7217. int check_in_type_throw(int type_code) {
  7218. otl_var_info_var(this->vl[cur_in]->get_name(),
  7219. this->vl[cur_in]->get_ftype(), type_code, var_info,
  7220. sizeof(var_info));
  7221. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  7222. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0,
  7223. this->stm_label ? this->stm_label : this->stm_text,
  7224. var_info)));
  7225. }
  7226. OTL_NODISCARD int check_in_type(int type_code, int tsize) {
  7227. switch (this->vl[cur_in]->get_ftype()) {
  7228. case otl_var_char:
  7229. if (type_code == otl_var_char)
  7230. return 1;
  7231. break;
  7232. case otl_var_raw:
  7233. if (type_code == otl_var_raw)
  7234. return 1;
  7235. break;
  7236. case otl_var_db2date:
  7237. case otl_var_db2time:
  7238. case otl_var_timestamp:
  7239. case otl_var_tz_timestamp:
  7240. case otl_var_ltz_timestamp:
  7241. if (type_code == otl_var_timestamp)
  7242. return 1;
  7243. break;
  7244. default:
  7245. #if defined(OTL_CHECK_IN_TYPE_FUNC)
  7246. if ((this->vl[cur_in]->get_ftype() == type_code &&
  7247. this->vl[cur_in]->get_elem_size() == tsize) ||
  7248. OTL_CHECK_IN_TYPE_FUNC(this->vl[cur_in]->get_ftype(),type_code))
  7249. return 1;
  7250. break;
  7251. #else
  7252. if (this->vl[cur_in]->get_ftype() == type_code &&
  7253. this->vl[cur_in]->get_elem_size() == tsize)
  7254. return 1;
  7255. break;
  7256. #endif
  7257. }
  7258. return check_in_type_throw(type_code);
  7259. }
  7260. void check_in_var_throw(void) {
  7261. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7262. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_1, otl_error_code_1,
  7263. this->stm_label ? this->stm_label : this->stm_text,
  7264. nullptr)));
  7265. }
  7266. void check_in_var(void) {
  7267. if (this->vl_len == 0)
  7268. check_in_var_throw();
  7269. }
  7270. void get_in_next(void) {
  7271. if (cur_in == this->vl_len - 1)
  7272. rewind();
  7273. else {
  7274. ++cur_in;
  7275. executed = 0;
  7276. }
  7277. }
  7278. OTL_TMPL_SELECT_STREAM &operator<<(const otl_null & /* n */) {
  7279. check_in_var();
  7280. this->vl[cur_in]->set_null(0);
  7281. get_in_next();
  7282. return *this;
  7283. }
  7284. OTL_TMPL_SELECT_STREAM &operator<<(const char c) {
  7285. check_in_var();
  7286. if (check_in_type(otl_var_char, 1)) {
  7287. char *tmp = OTL_RCAST(char *, this->vl[cur_in]->val());
  7288. tmp[0] = c;
  7289. tmp[1] = 0;
  7290. this->vl[cur_in]->set_not_null(0);
  7291. }
  7292. get_in_next();
  7293. return *this;
  7294. }
  7295. OTL_TMPL_SELECT_STREAM &operator<<(const unsigned char c) {
  7296. check_in_var();
  7297. if (check_in_type(otl_var_char, 1)) {
  7298. unsigned char *tmp = OTL_RCAST(unsigned char *, this->vl[cur_in]->val());
  7299. tmp[0] = c;
  7300. tmp[1] = 0;
  7301. this->vl[cur_in]->set_not_null(0);
  7302. }
  7303. get_in_next();
  7304. return *this;
  7305. }
  7306. OTL_TMPL_SELECT_STREAM &operator<<(const char *s) {
  7307. check_in_var();
  7308. if (check_in_type(otl_var_char, 1)) {
  7309. int overflow;
  7310. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  7311. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow,
  7312. this->vl[cur_in]->get_elem_size());
  7313. if (overflow) {
  7314. char tmp_var_info[256];
  7315. otl_var_info_var(this->vl[cur_in]->get_name(),
  7316. this->vl[cur_in]->get_ftype(), otl_var_char,
  7317. tmp_var_info, sizeof(tmp_var_info));
  7318. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7319. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  7320. OTL_THROW((OTL_TMPL_EXCEPTION(
  7321. otl_error_msg_4, otl_error_code_4,
  7322. this->stm_label ? this->stm_label : this->stm_text, tmp_var_info,
  7323. OTL_RCAST(const void *, s),
  7324. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  7325. #else
  7326. OTL_THROW((OTL_TMPL_EXCEPTION(
  7327. otl_error_msg_4, otl_error_code_4,
  7328. this->stm_label ? this->stm_label : this->stm_text, tmp_var_info)));
  7329. #endif
  7330. }
  7331. this->vl[cur_in]->set_not_null(0);
  7332. }
  7333. get_in_next();
  7334. return *this;
  7335. }
  7336. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  7337. template<const size_t N>
  7338. OTL_TMPL_SELECT_STREAM &operator<<(const std::array<char,N>& s){
  7339. (*this)<<s.data();
  7340. return *this;
  7341. }
  7342. #endif
  7343. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  7344. template<const size_t N>
  7345. OTL_TMPL_SELECT_STREAM &operator<<(const std::array<char16_t,N>& s){
  7346. (*this)<<OTL_RCAST(unsigned char*,OTL_CCAST(char16_t*,s.data()));
  7347. return *this;
  7348. }
  7349. #endif
  7350. OTL_TMPL_SELECT_STREAM &operator<<(const otl_long_string &s) {
  7351. check_in_var();
  7352. switch (this->vl[cur_in]->get_ftype()) {
  7353. case otl_var_varchar_long: {
  7354. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  7355. if (!s.get_unicode_flag() && in_unicode_mode) {
  7356. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  7357. this->stm_label ? this->stm_label
  7358. : this->stm_text)));
  7359. }
  7360. unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0));
  7361. int len = OTL_CCAST(otl_long_string *, &s)->len();
  7362. this->vl[cur_in]->set_not_null(0);
  7363. if (len > this->vl[cur_in]->actual_elem_size()) {
  7364. otl_var_info_var(this->vl[cur_in]->get_name(),
  7365. this->vl[cur_in]->get_ftype(), otl_var_long_string,
  7366. var_info, sizeof(var_info));
  7367. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7368. OTL_THROW((OTL_TMPL_EXCEPTION(
  7369. otl_error_msg_5, otl_error_code_5,
  7370. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  7371. }
  7372. otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype());
  7373. this->vl[cur_in]->set_len(len, 0);
  7374. } break;
  7375. case otl_var_raw_long: {
  7376. if (s.get_unicode_flag()) {
  7377. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  7378. this->stm_label ? this->stm_label
  7379. : this->stm_text)));
  7380. }
  7381. unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0));
  7382. int len = OTL_CCAST(otl_long_string *, &s)->len();
  7383. if (len > this->vl[cur_in]->actual_elem_size()) {
  7384. otl_var_info_var(this->vl[cur_in]->get_name(),
  7385. this->vl[cur_in]->get_ftype(), otl_var_char, var_info,
  7386. sizeof(var_info));
  7387. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7388. OTL_THROW((OTL_TMPL_EXCEPTION(
  7389. otl_error_msg_5, otl_error_code_5,
  7390. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  7391. }
  7392. this->vl[cur_in]->set_not_null(0);
  7393. otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype());
  7394. this->vl[cur_in]->set_len(len, 0);
  7395. } break;
  7396. case otl_var_raw: {
  7397. if (s.get_unicode_flag()) {
  7398. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  7399. this->stm_label ? this->stm_label
  7400. : this->stm_text)));
  7401. }
  7402. unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0));
  7403. int len = OTL_CCAST(otl_long_string *, &s)->len();
  7404. if (len > this->vl[cur_in]->actual_elem_size()) {
  7405. otl_var_info_var(this->vl[cur_in]->get_name(),
  7406. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  7407. sizeof(var_info));
  7408. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7409. OTL_THROW((OTL_TMPL_EXCEPTION(
  7410. otl_error_msg_5, otl_error_code_5,
  7411. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  7412. }
  7413. this->vl[cur_in]->set_not_null(0);
  7414. if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() ==
  7415. OTL_ADAPTER_ENUM otl_ora8_adapter) &&
  7416. this->vl[cur_in]->get_ftype() == otl_var_raw) {
  7417. otl_memcpy(c + sizeof(unsigned short), s.v, len,
  7418. this->vl[cur_in]->get_ftype());
  7419. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  7420. OTL_SCAST(unsigned short, len);
  7421. this->vl[cur_in]->set_len(len, 0);
  7422. } else {
  7423. otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype());
  7424. this->vl[cur_in]->set_len(len, 0);
  7425. }
  7426. } break;
  7427. }
  7428. get_in_next();
  7429. return *this;
  7430. }
  7431. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  7432. OTL_TMPL_SELECT_STREAM &operator<<(const OTL_STRING_CONTAINER &s) {
  7433. check_in_var();
  7434. if (this->vl[cur_in]->get_ftype() == otl_var_raw) {
  7435. unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0));
  7436. int len = OTL_SCAST(int, s.length());
  7437. if (len > this->vl[cur_in]->actual_elem_size()) {
  7438. otl_var_info_var(this->vl[cur_in]->get_name(),
  7439. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  7440. sizeof(var_info));
  7441. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7442. OTL_THROW((OTL_TMPL_EXCEPTION(
  7443. otl_error_msg_5, otl_error_code_5,
  7444. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  7445. }
  7446. this->vl[cur_in]->set_not_null(0);
  7447. if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() ==
  7448. OTL_ADAPTER_ENUM otl_ora8_adapter)) {
  7449. otl_memcpy(c + sizeof(unsigned short),
  7450. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  7451. len, this->vl[cur_in]->get_ftype());
  7452. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  7453. OTL_SCAST(unsigned short, len);
  7454. this->vl[cur_in]->set_len(len, 0);
  7455. } else {
  7456. otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  7457. len, this->vl[cur_in]->get_ftype());
  7458. this->vl[cur_in]->set_len(len, 0);
  7459. }
  7460. } else if (this->vl[cur_in]->get_ftype() == otl_var_char) {
  7461. int overflow;
  7462. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  7463. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  7464. overflow, this->vl[cur_in]->get_elem_size(),
  7465. OTL_SCAST(int, s.length()));
  7466. if (overflow) {
  7467. char temp_var_info[256];
  7468. otl_var_info_var(this->vl[cur_in]->get_name(),
  7469. this->vl[cur_in]->get_ftype(), otl_var_char,
  7470. temp_var_info, sizeof(temp_var_info));
  7471. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7472. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  7473. OTL_THROW((OTL_TMPL_EXCEPTION(
  7474. otl_error_msg_4, otl_error_code_4,
  7475. this->stm_label ? this->stm_label : this->stm_text, temp_var_info,
  7476. OTL_RCAST(const void *, s.c_str()),
  7477. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  7478. #else
  7479. OTL_THROW((OTL_TMPL_EXCEPTION(
  7480. otl_error_msg_4, otl_error_code_4,
  7481. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  7482. #endif
  7483. }
  7484. this->vl[cur_in]->set_not_null(0);
  7485. } else
  7486. check_in_type_throw(otl_var_char);
  7487. get_in_next();
  7488. return *this;
  7489. }
  7490. #endif
  7491. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  7492. OTL_TMPL_SELECT_STREAM &operator<<(OTL_STD_STRING_VIEW_CLASS s) {
  7493. check_in_var();
  7494. if (this->vl[cur_in]->get_ftype() == otl_var_raw) {
  7495. unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0));
  7496. int len = OTL_SCAST(int, s.length());
  7497. if (len > this->vl[cur_in]->actual_elem_size()) {
  7498. otl_var_info_var(this->vl[cur_in]->get_name(),
  7499. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  7500. sizeof(var_info));
  7501. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7502. OTL_THROW((OTL_TMPL_EXCEPTION(
  7503. otl_error_msg_5, otl_error_code_5,
  7504. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  7505. }
  7506. this->vl[cur_in]->set_not_null(0);
  7507. if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() ==
  7508. OTL_ADAPTER_ENUM otl_ora8_adapter)) {
  7509. otl_memcpy(c + sizeof(unsigned short),
  7510. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  7511. len, this->vl[cur_in]->get_ftype());
  7512. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  7513. OTL_SCAST(unsigned short, len);
  7514. this->vl[cur_in]->set_len(len, 0);
  7515. } else {
  7516. otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  7517. len, this->vl[cur_in]->get_ftype());
  7518. this->vl[cur_in]->set_len(len, 0);
  7519. }
  7520. } else if (this->vl[cur_in]->get_ftype() == otl_var_char) {
  7521. int overflow;
  7522. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  7523. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  7524. overflow, this->vl[cur_in]->get_elem_size(),
  7525. OTL_SCAST(int, s.length()));
  7526. if (overflow) {
  7527. char temp_var_info[256];
  7528. otl_var_info_var(this->vl[cur_in]->get_name(),
  7529. this->vl[cur_in]->get_ftype(), otl_var_char,
  7530. temp_var_info, sizeof(temp_var_info));
  7531. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7532. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  7533. OTL_THROW((OTL_TMPL_EXCEPTION(
  7534. otl_error_msg_4, otl_error_code_4,
  7535. this->stm_label ? this->stm_label : this->stm_text, temp_var_info,
  7536. OTL_RCAST(const void *, s.data()),
  7537. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  7538. #else
  7539. OTL_THROW((OTL_TMPL_EXCEPTION(
  7540. otl_error_msg_4, otl_error_code_4,
  7541. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  7542. #endif
  7543. }
  7544. this->vl[cur_in]->set_not_null(0);
  7545. } else
  7546. check_in_type_throw(otl_var_char);
  7547. get_in_next();
  7548. return *this;
  7549. }
  7550. #endif
  7551. OTL_TMPL_SELECT_STREAM &operator<<(const unsigned char *s) {
  7552. check_in_var();
  7553. if (check_in_type(otl_var_char, 1)) {
  7554. int overflow;
  7555. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()),
  7556. OTL_CCAST(unsigned char *, s), overflow,
  7557. this->vl[cur_in]->get_elem_size());
  7558. if (overflow) {
  7559. char temp_var_info[256];
  7560. otl_var_info_var(this->vl[cur_in]->get_name(),
  7561. this->vl[cur_in]->get_ftype(), otl_var_char,
  7562. temp_var_info, sizeof(temp_var_info));
  7563. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7564. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  7565. OTL_THROW((OTL_TMPL_EXCEPTION(
  7566. otl_error_msg_4, otl_error_code_4,
  7567. this->stm_label ? this->stm_label : this->stm_text, temp_var_info,
  7568. OTL_RCAST(const void *, s),
  7569. OTL_SCAST(int, this->vl[cur_in]->get_elem_size()))));
  7570. #else
  7571. OTL_THROW((OTL_TMPL_EXCEPTION(
  7572. otl_error_msg_4, otl_error_code_4,
  7573. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  7574. #endif
  7575. }
  7576. this->vl[cur_in]->set_not_null(0);
  7577. }
  7578. get_in_next();
  7579. return *this;
  7580. }
  7581. #if !defined(OTL_D2)
  7582. #define OTL_D2(T, T_type) \
  7583. OTL_TMPL_SELECT_STREAM &operator<<(const T n) { \
  7584. check_in_var(); \
  7585. if (check_in_type(T_type, sizeof(T))) { \
  7586. *OTL_RCAST(T *, this->vl[cur_in]->val()) = n; \
  7587. } \
  7588. this->vl[cur_in]->set_not_null(0); \
  7589. get_in_next(); \
  7590. return *this; \
  7591. }
  7592. #endif
  7593. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  7594. OTL_D2(int, otl_var_int)
  7595. OTL_D2(unsigned, otl_var_unsigned_int)
  7596. #if defined(OTL_BIGINT)
  7597. OTL_D2(OTL_BIGINT, otl_var_bigint)
  7598. #endif
  7599. #if defined(OTL_UBIGINT)
  7600. OTL_D2(OTL_UBIGINT, otl_var_ubigint)
  7601. #endif
  7602. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  7603. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  7604. OTL_D2(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  7605. #endif
  7606. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  7607. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  7608. OTL_D2(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  7609. #endif
  7610. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  7611. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  7612. OTL_D2(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  7613. #endif
  7614. OTL_D2(long, otl_var_long_int)
  7615. OTL_D2(short, otl_var_short)
  7616. OTL_D2(float, otl_var_float)
  7617. OTL_D2(double, otl_var_double)
  7618. #else
  7619. template<OTL_TYPE_NAME T,const int T_type> OTL_D2(T,T_type)
  7620. #endif
  7621. OTL_TMPL_SELECT_STREAM &operator<<(const TTimestampStruct &t) {
  7622. check_in_var();
  7623. if (check_in_type(otl_var_timestamp, sizeof(TTimestampStruct))) {
  7624. TTimestampStruct *tm =
  7625. OTL_RCAST(TTimestampStruct *, this->vl[cur_in]->val());
  7626. int rc = this->vl[cur_in]->get_var_struct().write_dt(
  7627. tm, &t, sizeof(TTimestampStruct));
  7628. if (rc == 0) {
  7629. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7630. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7631. this->stm_label ? this->stm_label
  7632. : this->stm_text)));
  7633. }
  7634. }
  7635. this->vl[cur_in]->set_not_null(0);
  7636. get_in_next();
  7637. return *this;
  7638. }
  7639. #if defined(OTL_ORA_SDO_GEOMETRY)
  7640. OTL_TMPL_SELECT_STREAM &operator << (const oci_spatial_geometry &s){
  7641. check_in_var();
  7642. if(check_in_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){
  7643. int rc = this->vl[cur_in]->get_var_struct().write_geometry(s, cur_in);
  7644. if(rc == 0){
  7645. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  7646. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7647. this->stm_label ? this->stm_label
  7648. : this->stm_text)));
  7649. }
  7650. }
  7651. get_in_next();
  7652. return *this;
  7653. }
  7654. #endif
  7655. private:
  7656. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  7657. public:
  7658. otl_tmpl_select_stream(const otl_tmpl_select_stream &) = delete;
  7659. otl_tmpl_select_stream &operator=(const otl_tmpl_select_stream &) = delete;
  7660. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  7661. otl_tmpl_select_stream(otl_tmpl_select_stream &&) = delete;
  7662. otl_tmpl_select_stream &operator=(otl_tmpl_select_stream &&) = delete;
  7663. #endif
  7664. private:
  7665. #else
  7666. otl_tmpl_select_stream(const otl_tmpl_select_stream &)
  7667. : OTL_TMPL_SELECT_CURSOR(), sl_desc(nullptr), sl(nullptr), sl_len(0),
  7668. null_fetched(0), cur_col(0), cur_in(0), executed(0), eof_status(0),
  7669. var_info(), override_(nullptr), delay_next(0), lob_stream_mode(false),
  7670. _rfc(0) {}
  7671. otl_tmpl_select_stream &operator=(const otl_tmpl_select_stream &) {
  7672. return *this;
  7673. }
  7674. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  7675. otl_tmpl_select_stream(otl_tmpl_select_stream &&)
  7676. : OTL_TMPL_SELECT_CURSOR(), sl_desc(nullptr), sl(nullptr), sl_len(0),
  7677. null_fetched(0), cur_col(0), cur_in(0), executed(0), eof_status(0),
  7678. var_info(), override_(nullptr), delay_next(0), lob_stream_mode(false),
  7679. _rfc(0) {}
  7680. otl_tmpl_select_stream &operator=(otl_tmpl_select_stream &&) { return *this; }
  7681. #endif
  7682. #endif
  7683. };
  7684. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  7685. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
  7686. OTL_TYPE_NAME TTimestampStruct>
  7687. class otl_tmpl_out_stream : public OTL_TMPL_CURSOR {
  7688. protected:
  7689. int auto_commit_flag;
  7690. int dirty;
  7691. int cur_x;
  7692. int cur_y;
  7693. otl_stream_buffer_size_type array_size;
  7694. int in_exception_flag;
  7695. int in_destruct_flag;
  7696. int should_delete_flag;
  7697. char var_info[256];
  7698. bool flush_flag;
  7699. bool flush_flag2;
  7700. bool lob_stream_mode;
  7701. void *master_stream_ptr_;
  7702. public:
  7703. OTL_NODISCARD int get_dirty_buf_len() const {
  7704. if (dirty)
  7705. return cur_y + 1;
  7706. else
  7707. return 0;
  7708. }
  7709. void set_flush_flag(const bool aflush_flag) { flush_flag = aflush_flag; }
  7710. void set_flush_flag2(const bool aflush_flag2) { flush_flag2 = aflush_flag2; }
  7711. void cleanup(void) {
  7712. int i;
  7713. if (should_delete_flag) {
  7714. for (i = 0; i < this->vl_len; ++i)
  7715. delete this->vl[i];
  7716. }
  7717. delete[] this->vl;
  7718. }
  7719. otl_tmpl_out_stream(OTL_TMPL_CONNECT &pdb, void *master_stream_ptr,
  7720. const bool alob_stream_mode = false,
  7721. const char *sqlstm_label = nullptr)
  7722. : OTL_TMPL_CURSOR(pdb), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0),
  7723. array_size(0), in_exception_flag(0), in_destruct_flag(0),
  7724. should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0),
  7725. lob_stream_mode(0), master_stream_ptr_(master_stream_ptr) {
  7726. if (sqlstm_label != nullptr) {
  7727. if (this->stm_label != nullptr) {
  7728. delete[] this->stm_label;
  7729. this->stm_label = nullptr;
  7730. }
  7731. size_t len = strlen(sqlstm_label) + 1;
  7732. this->stm_label = new char[len];
  7733. OTL_STRCPY_S(this->stm_label, len, sqlstm_label);
  7734. }
  7735. should_delete_flag = 1;
  7736. in_exception_flag = 0;
  7737. in_destruct_flag = 0;
  7738. dirty = 0;
  7739. auto_commit_flag = 1;
  7740. flush_flag = true;
  7741. flush_flag2 = true;
  7742. lob_stream_mode = alob_stream_mode;
  7743. this->cursor_struct.reset_last_param_data_token();
  7744. this->cursor_struct.reset_last_sql_param_data_status();
  7745. this->cursor_struct.reset_sql_param_data_count();
  7746. cur_x = -1;
  7747. cur_y = 0;
  7748. this->stm_text = nullptr;
  7749. }
  7750. virtual ~otl_tmpl_out_stream() OTL_THROWS_OTL_EXCEPTION3 {
  7751. in_destruct_flag = 1;
  7752. this->in_destructor = 1;
  7753. if (dirty && !in_exception_flag && flush_flag && flush_flag2)
  7754. flush();
  7755. cleanup();
  7756. in_destruct_flag = 0;
  7757. }
  7758. void reset_to_last_valid_row() {
  7759. if (cur_y > 0) {
  7760. --cur_y;
  7761. this->in_exception_flag = 0;
  7762. cur_x = this->vl_len - 1;
  7763. }
  7764. }
  7765. virtual void flush(const int rowoff = 0, const bool force_flush = false) {
  7766. int i, rc;
  7767. this->_rpc = 0;
  7768. if (!dirty)
  7769. return;
  7770. if (!flush_flag2)
  7771. return;
  7772. if (force_flush) {
  7773. if (rowoff > cur_y) {
  7774. clean();
  7775. return;
  7776. }
  7777. int temp_rc;
  7778. OTL_TRACE_STREAM_EXECUTION2
  7779. this->exec(OTL_SCAST(otl_stream_buffer_size_type, (cur_y + 1)), rowoff,
  7780. otl_sql_exec_from_cursor_class);
  7781. for (i = 0; i < this->vl_len; ++i) {
  7782. temp_rc = this->vl[i]->get_var_struct().put_blob();
  7783. if (temp_rc == 0) {
  7784. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7785. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7786. this->stm_label ? this->stm_label
  7787. : this->stm_text)));
  7788. }
  7789. }
  7790. if (auto_commit_flag)
  7791. this->adb->commit();
  7792. clean();
  7793. return;
  7794. }
  7795. #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  7796. if (otl_uncaught_exception()) {
  7797. clean();
  7798. return;
  7799. }
  7800. #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  7801. if (otl_uncaught_exception()) {
  7802. clean();
  7803. return;
  7804. }
  7805. #endif
  7806. if (this->retcode == 0 || this->adb->get_retcode() == 0) {
  7807. clean();
  7808. return;
  7809. }
  7810. if (cur_x != this->vl_len - 1) {
  7811. in_exception_flag = 1;
  7812. #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  7813. if (otl_uncaught_exception()) {
  7814. clean();
  7815. return;
  7816. }
  7817. #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  7818. if (otl_uncaught_exception()) {
  7819. clean();
  7820. return;
  7821. }
  7822. #endif
  7823. OTL_THROW((OTL_TMPL_EXCEPTION(
  7824. otl_error_msg_3, otl_error_code_3,
  7825. this->stm_label ? this->stm_label : this->stm_text, nullptr)));
  7826. }
  7827. if (in_destruct_flag) {
  7828. OTL_TRACE_STREAM_EXECUTION2
  7829. this->retcode = this->cursor_struct.exec(cur_y + 1, rowoff,
  7830. otl_sql_exec_from_cursor_class);
  7831. for (i = 0; i < this->vl_len; ++i) {
  7832. rc = this->vl[i]->get_var_struct().put_blob();
  7833. if (rc == 0) {
  7834. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7835. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7836. this->stm_label ? this->stm_label
  7837. : this->stm_text)));
  7838. }
  7839. }
  7840. if (!this->retcode) {
  7841. clean();
  7842. in_exception_flag = 1;
  7843. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7844. OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label
  7845. ? this->stm_label
  7846. : this->stm_text)));
  7847. }
  7848. if (auto_commit_flag) {
  7849. this->adb->set_retcode(this->adb->get_connect_struct().commit());
  7850. if (!this->adb->get_retcode()) {
  7851. clean();
  7852. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7853. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7854. this->stm_label ? this->stm_label
  7855. : this->stm_text)));
  7856. }
  7857. }
  7858. } else {
  7859. int temp_rc;
  7860. OTL_TRACE_STREAM_EXECUTION2
  7861. this->exec(OTL_SCAST(otl_stream_buffer_size_type, (cur_y + 1)), rowoff,
  7862. otl_sql_exec_from_cursor_class);
  7863. long curr_rpc = this->get_rpc();
  7864. for (i = 0; i < this->vl_len; ++i) {
  7865. otl_adapter_enum otl_adapter_type =
  7866. this->vl[i]->get_const_var_struct().get_otl_adapter();
  7867. if (!(otl_adapter_type == OTL_ADAPTER_ENUM otl_ora8_adapter &&
  7868. curr_rpc == 0)) {
  7869. temp_rc = this->vl[i]->get_var_struct().put_blob();
  7870. if (temp_rc == 0) {
  7871. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  7872. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  7873. this->stm_label ? this->stm_label
  7874. : this->stm_text)));
  7875. }
  7876. }
  7877. }
  7878. if (auto_commit_flag)
  7879. this->adb->commit();
  7880. if (rowoff > 0)
  7881. clean();
  7882. else
  7883. clean(0);
  7884. }
  7885. }
  7886. virtual void clean(const int clean_up_error_flag = 0) {
  7887. if (clean_up_error_flag) {
  7888. this->retcode = 1;
  7889. this->in_exception_flag = 0;
  7890. }
  7891. if (!dirty)
  7892. return;
  7893. cur_x = -1;
  7894. cur_y = 0;
  7895. dirty = 0;
  7896. }
  7897. bool get_error_state(void) const {
  7898. if (this->retcode == 0 || this->in_exception_flag == 1)
  7899. return true;
  7900. else
  7901. return false;
  7902. }
  7903. void set_commit(int auto_commit = 0) { auto_commit_flag = auto_commit; }
  7904. void get_next(void) {
  7905. if (cur_x < this->vl_len - 1)
  7906. ++cur_x;
  7907. else {
  7908. if (cur_y < array_size - 1) {
  7909. ++cur_y;
  7910. cur_x = 0;
  7911. } else {
  7912. flush();
  7913. cur_x = 0;
  7914. }
  7915. }
  7916. dirty = 1;
  7917. }
  7918. OTL_NODISCARD int check_type_throw(int type_code) {
  7919. in_exception_flag = 1;
  7920. otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(),
  7921. type_code, var_info, sizeof(var_info));
  7922. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  7923. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0,
  7924. this->stm_label ? this->stm_label : this->stm_text,
  7925. var_info)));
  7926. }
  7927. OTL_NODISCARD int check_type(int type_code, int tsize) {
  7928. switch (this->vl[cur_x]->get_ftype()) {
  7929. case otl_var_char:
  7930. if (type_code == otl_var_char)
  7931. return 1;
  7932. break;
  7933. case otl_var_bfloat:
  7934. if (type_code == otl_var_float)
  7935. return 1;
  7936. break;
  7937. case otl_var_bdouble:
  7938. if (type_code == otl_var_double)
  7939. return 1;
  7940. break;
  7941. case otl_var_db2time:
  7942. case otl_var_tz_timestamp:
  7943. case otl_var_ltz_timestamp:
  7944. case otl_var_db2date:
  7945. if (type_code == otl_var_timestamp)
  7946. return 1;
  7947. break;
  7948. case otl_var_refcur:
  7949. if (type_code == otl_var_refcur)
  7950. return 1;
  7951. break;
  7952. default:
  7953. #if defined(OTL_CHECK_IN_TYPE_FUNC)
  7954. if ((this->vl[cur_x]->get_ftype() == type_code &&
  7955. this->vl[cur_x]->get_elem_size() == tsize) ||
  7956. OTL_CHECK_IN_TYPE_FUNC(this->vl[cur_x]->get_ftype(),type_code))
  7957. return 1;
  7958. break;
  7959. #else
  7960. if (this->vl[cur_x]->get_ftype() == type_code &&
  7961. this->vl[cur_x]->get_elem_size() == tsize)
  7962. return 1;
  7963. break;
  7964. #endif
  7965. }
  7966. return check_type_throw(type_code);
  7967. }
  7968. void check_buf(void) {
  7969. if (cur_x == this->vl_len - 1 && cur_y == array_size - 1)
  7970. flush();
  7971. }
  7972. OTL_TMPL_OUT_STREAM &operator<<(const char c) {
  7973. if (this->vl_len > 0) {
  7974. get_next();
  7975. if (check_type(otl_var_char, 1)) {
  7976. char *tmp = OTL_RCAST(char *, this->vl[cur_x]->val(cur_y));
  7977. tmp[0] = c;
  7978. tmp[1] = 0;
  7979. this->vl[cur_x]->set_not_null(cur_y);
  7980. }
  7981. check_buf();
  7982. }
  7983. return *this;
  7984. }
  7985. OTL_TMPL_OUT_STREAM &operator<<(const unsigned char c) {
  7986. if (this->vl_len > 0) {
  7987. get_next();
  7988. if (check_type(otl_var_char, 1)) {
  7989. unsigned char *tmp =
  7990. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  7991. tmp[0] = c;
  7992. tmp[1] = 0;
  7993. this->vl[cur_x]->set_not_null(cur_y);
  7994. }
  7995. check_buf();
  7996. }
  7997. return *this;
  7998. }
  7999. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  8000. OTL_TMPL_OUT_STREAM &operator<<(const OTL_STRING_CONTAINER &s) {
  8001. if (this->vl_len > 0) {
  8002. get_next();
  8003. switch (this->vl[cur_x]->get_ftype()) {
  8004. #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \
  8005. defined(OTL_ACE)
  8006. case otl_var_raw: {
  8007. unsigned char *c =
  8008. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8009. int len = OTL_SCAST(int, s.length());
  8010. this->vl[cur_x]->set_not_null(cur_y);
  8011. if (len > this->vl[cur_x]->actual_elem_size()) {
  8012. otl_var_info_var(this->vl[cur_x]->get_name(),
  8013. this->vl[cur_x]->get_ftype(), otl_var_long_string,
  8014. var_info, sizeof(var_info));
  8015. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8016. OTL_THROW((OTL_TMPL_EXCEPTION(
  8017. otl_error_msg_5, otl_error_code_5,
  8018. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8019. }
  8020. if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() ==
  8021. OTL_ADAPTER_ENUM otl_ora8_adapter)) {
  8022. otl_memcpy(c + sizeof(unsigned short),
  8023. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  8024. len, this->vl[cur_x]->get_ftype());
  8025. *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) =
  8026. OTL_SCAST(unsigned short, len);
  8027. this->vl[cur_x]->set_len(len, cur_y);
  8028. } else {
  8029. otl_memcpy(c,
  8030. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  8031. len, this->vl[cur_x]->get_ftype());
  8032. this->vl[cur_x]->set_len(len, cur_y);
  8033. }
  8034. } break;
  8035. #endif
  8036. case otl_var_char: {
  8037. int overflow;
  8038. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8039. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  8040. overflow, this->vl[cur_x]->get_elem_size(),
  8041. OTL_SCAST(int, s.length()));
  8042. if (overflow) {
  8043. otl_var_info_var(this->vl[cur_x]->get_name(),
  8044. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8045. sizeof(var_info));
  8046. in_exception_flag = 1;
  8047. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8048. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8049. OTL_THROW((OTL_TMPL_EXCEPTION(
  8050. otl_error_msg_4, otl_error_code_4,
  8051. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8052. OTL_RCAST(const void *, s.c_str()),
  8053. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8054. #else
  8055. OTL_THROW((OTL_TMPL_EXCEPTION(
  8056. otl_error_msg_4, otl_error_code_4,
  8057. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8058. #endif
  8059. }
  8060. this->vl[cur_x]->set_not_null(cur_y);
  8061. } break;
  8062. #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \
  8063. defined(OTL_ACE)
  8064. case otl_var_varchar_long:
  8065. case otl_var_raw_long: {
  8066. unsigned char *c =
  8067. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8068. int len = OTL_SCAST(int, s.length());
  8069. this->vl[cur_x]->set_not_null(cur_y);
  8070. if (len > this->vl[cur_x]->actual_elem_size()) {
  8071. otl_var_info_var(this->vl[cur_x]->get_name(),
  8072. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8073. sizeof(var_info));
  8074. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8075. OTL_THROW((OTL_TMPL_EXCEPTION(
  8076. otl_error_msg_5, otl_error_code_5,
  8077. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8078. }
  8079. otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  8080. len, this->vl[cur_x]->get_ftype());
  8081. this->vl[cur_x]->set_len(len, cur_y);
  8082. } break;
  8083. case otl_var_blob:
  8084. case otl_var_clob: {
  8085. int len = OTL_SCAST(int, s.length());
  8086. if (len > this->vl[cur_x]->actual_elem_size()) {
  8087. otl_var_info_var(this->vl[cur_x]->get_name(),
  8088. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8089. sizeof(var_info));
  8090. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8091. OTL_THROW((OTL_TMPL_EXCEPTION(
  8092. otl_error_msg_5, otl_error_code_5,
  8093. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8094. }
  8095. this->vl[cur_x]->set_not_null(cur_y);
  8096. (void)this->vl[cur_x]->get_var_struct().save_blob
  8097. (OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, 0);
  8098. } break;
  8099. #endif
  8100. default:
  8101. (void)check_type(otl_var_char, 1);
  8102. } // switch
  8103. check_buf();
  8104. }
  8105. return *this;
  8106. }
  8107. #endif
  8108. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  8109. OTL_TMPL_OUT_STREAM &operator<<(OTL_STD_STRING_VIEW_CLASS s) {
  8110. if (this->vl_len > 0) {
  8111. get_next();
  8112. switch (this->vl[cur_x]->get_ftype()) {
  8113. case otl_var_raw: {
  8114. unsigned char *c =
  8115. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8116. int len = OTL_SCAST(int, s.length());
  8117. this->vl[cur_x]->set_not_null(cur_y);
  8118. if (len > this->vl[cur_x]->actual_elem_size()) {
  8119. otl_var_info_var(this->vl[cur_x]->get_name(),
  8120. this->vl[cur_x]->get_ftype(), otl_var_long_string,
  8121. var_info, sizeof(var_info));
  8122. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8123. OTL_THROW((OTL_TMPL_EXCEPTION(
  8124. otl_error_msg_5, otl_error_code_5,
  8125. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8126. }
  8127. if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() ==
  8128. OTL_ADAPTER_ENUM otl_ora8_adapter)) {
  8129. otl_memcpy(c + sizeof(unsigned short),
  8130. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  8131. len, this->vl[cur_x]->get_ftype());
  8132. *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) =
  8133. OTL_SCAST(unsigned short, len);
  8134. this->vl[cur_x]->set_len(len, cur_y);
  8135. } else {
  8136. otl_memcpy(c,
  8137. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  8138. len, this->vl[cur_x]->get_ftype());
  8139. this->vl[cur_x]->set_len(len, cur_y);
  8140. }
  8141. } break;
  8142. case otl_var_char: {
  8143. int overflow;
  8144. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8145. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  8146. overflow, this->vl[cur_x]->get_elem_size(),
  8147. OTL_SCAST(int, s.length()));
  8148. if (overflow) {
  8149. otl_var_info_var(this->vl[cur_x]->get_name(),
  8150. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8151. sizeof(var_info));
  8152. in_exception_flag = 1;
  8153. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8154. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8155. OTL_THROW((OTL_TMPL_EXCEPTION(
  8156. otl_error_msg_4, otl_error_code_4,
  8157. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8158. OTL_RCAST(const void *, s.data()),
  8159. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8160. #else
  8161. OTL_THROW((OTL_TMPL_EXCEPTION(
  8162. otl_error_msg_4, otl_error_code_4,
  8163. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8164. #endif
  8165. }
  8166. this->vl[cur_x]->set_not_null(cur_y);
  8167. } break;
  8168. case otl_var_varchar_long:
  8169. case otl_var_raw_long: {
  8170. unsigned char *c =
  8171. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8172. int len = OTL_SCAST(int, s.length());
  8173. this->vl[cur_x]->set_not_null(cur_y);
  8174. if (len > this->vl[cur_x]->actual_elem_size()) {
  8175. otl_var_info_var(this->vl[cur_x]->get_name(),
  8176. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8177. sizeof(var_info));
  8178. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8179. OTL_THROW((OTL_TMPL_EXCEPTION(
  8180. otl_error_msg_5, otl_error_code_5,
  8181. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8182. }
  8183. otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  8184. len, this->vl[cur_x]->get_ftype());
  8185. this->vl[cur_x]->set_len(len, cur_y);
  8186. } break;
  8187. case otl_var_blob:
  8188. case otl_var_clob: {
  8189. int len = OTL_SCAST(int, s.length());
  8190. if (len > this->vl[cur_x]->actual_elem_size()) {
  8191. otl_var_info_var(this->vl[cur_x]->get_name(),
  8192. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8193. sizeof(var_info));
  8194. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8195. OTL_THROW((OTL_TMPL_EXCEPTION(
  8196. otl_error_msg_5, otl_error_code_5,
  8197. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8198. }
  8199. this->vl[cur_x]->set_not_null(cur_y);
  8200. (void)this->vl[cur_x]->get_var_struct().save_blob
  8201. (OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, 0);
  8202. } break;
  8203. default:
  8204. (void)check_type(otl_var_char, 1);
  8205. } // switch
  8206. check_buf();
  8207. }
  8208. return *this;
  8209. }
  8210. #endif
  8211. #if defined(OTL_UNICODE_STRING_TYPE)
  8212. OTL_TMPL_OUT_STREAM &operator<<(const OTL_UNICODE_STRING_TYPE &s) {
  8213. if (this->vl_len > 0) {
  8214. get_next();
  8215. switch (this->vl[cur_x]->get_ftype()) {
  8216. case otl_var_char: {
  8217. int overflow;
  8218. #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE)
  8219. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8220. OTL_RCAST(unsigned char *,
  8221. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *,
  8222. s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())),
  8223. #else
  8224. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8225. OTL_RCAST(unsigned char *,
  8226. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())),
  8227. #endif
  8228. overflow, this->vl[cur_x]->get_elem_size(),
  8229. OTL_SCAST(int, s.length()));
  8230. if (overflow) {
  8231. otl_var_info_var(this->vl[cur_x]->get_name(),
  8232. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8233. sizeof(var_info));
  8234. in_exception_flag = 1;
  8235. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8236. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8237. OTL_THROW((OTL_TMPL_EXCEPTION(
  8238. otl_error_msg_4, otl_error_code_4,
  8239. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8240. OTL_RCAST(const void *, s.c_str()),
  8241. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8242. #else
  8243. OTL_THROW((OTL_TMPL_EXCEPTION(
  8244. otl_error_msg_4, otl_error_code_4,
  8245. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8246. #endif
  8247. }
  8248. this->vl[cur_x]->set_not_null(cur_y);
  8249. break;
  8250. }
  8251. case otl_var_varchar_long: {
  8252. unsigned char *c =
  8253. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8254. int len = OTL_SCAST(int, s.length());
  8255. this->vl[cur_x]->set_not_null(cur_y);
  8256. if (len > this->vl[cur_x]->actual_elem_size()) {
  8257. otl_var_info_var(this->vl[cur_x]->get_name(),
  8258. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8259. sizeof(var_info));
  8260. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8261. OTL_THROW((OTL_TMPL_EXCEPTION(
  8262. otl_error_msg_5, otl_error_code_5,
  8263. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8264. }
  8265. #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE)
  8266. otl_memcpy(c,
  8267. OTL_RCAST(unsigned char *,
  8268. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *,
  8269. s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())),
  8270. #else
  8271. otl_memcpy(c, OTL_RCAST(unsigned char *,
  8272. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())),
  8273. #endif
  8274. len, this->vl[cur_x]->get_ftype());
  8275. this->vl[cur_x]->set_len(len, cur_y);
  8276. break;
  8277. }
  8278. case otl_var_clob: {
  8279. int len = OTL_SCAST(int, s.length());
  8280. if (len > this->vl[cur_x]->actual_elem_size()) {
  8281. otl_var_info_var(this->vl[cur_x]->get_name(),
  8282. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8283. sizeof(var_info));
  8284. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8285. OTL_THROW((OTL_TMPL_EXCEPTION(
  8286. otl_error_msg_5, otl_error_code_5,
  8287. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8288. }
  8289. this->vl[cur_x]->set_not_null(cur_y);
  8290. (void)this->vl[cur_x]->get_var_struct().save_blob
  8291. #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE)
  8292. (OTL_RCAST(const unsigned char *,
  8293. s.OTL_C_STR_FOR_UNICODE_STRING_TYPE()),
  8294. #else
  8295. (OTL_RCAST(const unsigned char *, s.c_str()),
  8296. #endif
  8297. len, 0);
  8298. } break;
  8299. default:
  8300. (void)check_type(otl_var_char, 1);
  8301. }
  8302. check_buf();
  8303. }
  8304. return *this;
  8305. }
  8306. #endif
  8307. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  8308. OTL_TMPL_OUT_STREAM &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) {
  8309. if (this->vl_len > 0) {
  8310. get_next();
  8311. switch (this->vl[cur_x]->get_ftype()) {
  8312. case otl_var_char: {
  8313. int overflow;
  8314. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8315. OTL_RCAST(unsigned char *,
  8316. OTL_CCAST(OTL_UNICODE_CHAR_TYPE*, s.data())),
  8317. overflow, this->vl[cur_x]->get_elem_size(),
  8318. OTL_SCAST(int, s.length()));
  8319. if (overflow) {
  8320. otl_var_info_var(this->vl[cur_x]->get_name(),
  8321. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8322. sizeof(var_info));
  8323. in_exception_flag = 1;
  8324. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8325. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8326. OTL_THROW((OTL_TMPL_EXCEPTION(
  8327. otl_error_msg_4, otl_error_code_4,
  8328. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8329. OTL_RCAST(const void *, s.data()),
  8330. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8331. #else
  8332. OTL_THROW((OTL_TMPL_EXCEPTION(
  8333. otl_error_msg_4, otl_error_code_4,
  8334. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8335. #endif
  8336. }
  8337. this->vl[cur_x]->set_not_null(cur_y);
  8338. break;
  8339. }
  8340. case otl_var_varchar_long: {
  8341. unsigned char *c =
  8342. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8343. int len = OTL_SCAST(int, s.length());
  8344. this->vl[cur_x]->set_not_null(cur_y);
  8345. if (len > this->vl[cur_x]->actual_elem_size()) {
  8346. otl_var_info_var(this->vl[cur_x]->get_name(),
  8347. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8348. sizeof(var_info));
  8349. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8350. OTL_THROW((OTL_TMPL_EXCEPTION(
  8351. otl_error_msg_5, otl_error_code_5,
  8352. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8353. }
  8354. otl_memcpy(c, OTL_RCAST(unsigned char *,
  8355. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())),
  8356. len, this->vl[cur_x]->get_ftype());
  8357. this->vl[cur_x]->set_len(len, cur_y);
  8358. break;
  8359. }
  8360. case otl_var_clob: {
  8361. int len = OTL_SCAST(int, s.length());
  8362. if (len > this->vl[cur_x]->actual_elem_size()) {
  8363. otl_var_info_var(this->vl[cur_x]->get_name(),
  8364. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8365. sizeof(var_info));
  8366. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8367. OTL_THROW((OTL_TMPL_EXCEPTION(
  8368. otl_error_msg_5, otl_error_code_5,
  8369. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8370. }
  8371. this->vl[cur_x]->set_not_null(cur_y);
  8372. (void)this->vl[cur_x]->get_var_struct().save_blob
  8373. (OTL_RCAST(const unsigned char *, s.data()),
  8374. len, 0);
  8375. } break;
  8376. default:
  8377. (void)check_type(otl_var_char, 1);
  8378. }
  8379. check_buf();
  8380. }
  8381. return *this;
  8382. }
  8383. #endif
  8384. OTL_TMPL_OUT_STREAM &operator<<(const char *s) {
  8385. if (this->vl_len > 0) {
  8386. get_next();
  8387. if (check_type(otl_var_char, 1)) {
  8388. int overflow;
  8389. otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8390. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow,
  8391. this->vl[cur_x]->get_elem_size());
  8392. if (overflow) {
  8393. otl_var_info_var(this->vl[cur_x]->get_name(),
  8394. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8395. sizeof(var_info));
  8396. in_exception_flag = 1;
  8397. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8398. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8399. OTL_THROW((OTL_TMPL_EXCEPTION(
  8400. otl_error_msg_4, otl_error_code_4,
  8401. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8402. OTL_RCAST(const void *, s),
  8403. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8404. #else
  8405. OTL_THROW((OTL_TMPL_EXCEPTION(
  8406. otl_error_msg_4, otl_error_code_4,
  8407. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8408. #endif
  8409. }
  8410. this->vl[cur_x]->set_not_null(cur_y);
  8411. }
  8412. check_buf();
  8413. }
  8414. return *this;
  8415. }
  8416. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  8417. template<const size_t N>
  8418. OTL_TMPL_OUT_STREAM &operator<<(const std::array<char16_t,N>& s){
  8419. (*this)<<OTL_RCAST(const unsigned char*,s.data());
  8420. return *this;
  8421. }
  8422. #endif
  8423. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  8424. template<const size_t N>
  8425. OTL_TMPL_OUT_STREAM &operator<<(const std::array<char,N>& s){
  8426. (*this)<<s.data();
  8427. return *this;
  8428. }
  8429. #endif
  8430. OTL_TMPL_OUT_STREAM &operator<<(const unsigned char *s) {
  8431. if (this->vl_len > 0) {
  8432. get_next();
  8433. if (check_type(otl_var_char, 1)) {
  8434. int overflow;
  8435. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)),
  8436. OTL_CCAST(unsigned char *, s), overflow,
  8437. this->vl[cur_x]->get_elem_size());
  8438. if (overflow) {
  8439. otl_var_info_var(this->vl[cur_x]->get_name(),
  8440. this->vl[cur_x]->get_ftype(), otl_var_char, var_info,
  8441. sizeof(var_info));
  8442. in_exception_flag = 1;
  8443. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8444. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8445. OTL_THROW((OTL_TMPL_EXCEPTION(
  8446. otl_error_msg_4, otl_error_code_4,
  8447. this->stm_label ? this->stm_label : this->stm_text, var_info,
  8448. OTL_RCAST(const void *, s),
  8449. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8450. #else
  8451. OTL_THROW((OTL_TMPL_EXCEPTION(
  8452. otl_error_msg_4, otl_error_code_4,
  8453. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8454. #endif
  8455. }
  8456. this->vl[cur_x]->set_not_null(cur_y);
  8457. }
  8458. check_buf();
  8459. }
  8460. return *this;
  8461. }
  8462. #if !defined(OTL_D3)
  8463. #define OTL_D3(T, T_type) \
  8464. OTL_TMPL_OUT_STREAM &operator<<(const T n) { \
  8465. if (this->vl_len > 0) { \
  8466. get_next(); \
  8467. if (check_type(T_type, sizeof(T))) { \
  8468. *OTL_RCAST(T *, this->vl[cur_x]->val(cur_y)) = n; \
  8469. this->vl[cur_x]->set_not_null(cur_y); \
  8470. } \
  8471. check_buf(); \
  8472. } \
  8473. return *this; \
  8474. }
  8475. #endif
  8476. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  8477. OTL_D3(int, otl_var_int)
  8478. #if defined(OTL_BIGINT)
  8479. OTL_D3(OTL_BIGINT, otl_var_bigint)
  8480. #endif
  8481. #if defined(OTL_UBIGINT)
  8482. OTL_D3(OTL_UBIGINT, otl_var_ubigint)
  8483. #endif
  8484. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  8485. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  8486. OTL_D3(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  8487. #endif
  8488. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  8489. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  8490. OTL_D3(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  8491. #endif
  8492. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  8493. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  8494. OTL_D3(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  8495. #endif
  8496. OTL_D3(unsigned, otl_var_unsigned_int)
  8497. OTL_D3(long, otl_var_long_int)
  8498. OTL_D3(short, otl_var_short)
  8499. OTL_D3(float, otl_var_float)
  8500. OTL_D3(double, otl_var_double)
  8501. #else
  8502. template<OTL_TYPE_NAME T,const int T_type> OTL_D3(T,T_type)
  8503. #endif
  8504. #if defined(OTL_PL_TAB)
  8505. OTL_TMPL_OUT_STREAM &operator<<(otl_pl_tab_generic &tab) {
  8506. if (this->vl_len > 0) {
  8507. get_next();
  8508. if (check_type(tab.get_vtype(), tab.get_elem_size())) {
  8509. int i, tmp_len;
  8510. if (tab.len() <= this->vl[cur_x]->get_array_size())
  8511. tmp_len = tab.len();
  8512. else
  8513. tmp_len = this->vl[cur_x]->get_array_size();
  8514. this->vl[cur_x]->set_pl_tab_len(tmp_len);
  8515. if (tab.get_vtype() == otl_var_char) {
  8516. int i2;
  8517. for (i2 = 0; i2 < tmp_len; ++i2) {
  8518. int overflow;
  8519. otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(i2)),
  8520. OTL_RCAST(unsigned char *, tab.val(i2)), overflow,
  8521. this->vl[cur_x]->get_elem_size());
  8522. if (overflow) {
  8523. char tmp_var_info[256];
  8524. otl_var_info_var(this->vl[cur_x]->get_name(),
  8525. this->vl[cur_x]->get_ftype(), otl_var_char,
  8526. tmp_var_info, sizeof(tmp_var_info));
  8527. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8528. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8529. OTL_THROW((OTL_TMPL_EXCEPTION(
  8530. otl_error_msg_4, otl_error_code_4,
  8531. this->stm_label ? this->stm_label : this->stm_text,
  8532. tmp_var_info, OTL_RCAST(const void *, tab.val(i2)),
  8533. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8534. #else
  8535. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_4, otl_error_code_4,
  8536. this->stm_label ? this->stm_label
  8537. : this->stm_text,
  8538. tmp_var_info)));
  8539. #endif
  8540. }
  8541. }
  8542. } else if (tab.get_vtype() == otl_var_timestamp) {
  8543. otl_datetime *ext_dt = OTL_RCAST(otl_datetime *, tab.get_p_v());
  8544. otl_oracle_date *int_dt =
  8545. OTL_RCAST(otl_oracle_date *, this->vl[cur_x]->val());
  8546. int j;
  8547. for (j = 0; j < tmp_len; ++j) {
  8548. convert_date(*int_dt, *ext_dt);
  8549. ++int_dt;
  8550. ++ext_dt;
  8551. }
  8552. } else
  8553. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8554. OTL_RCAST(char *, tab.val()),
  8555. OTL_SCAST(size_t, tab.get_elem_size() * tmp_len));
  8556. for (i = 0; i < tmp_len; ++i) {
  8557. if (tab.is_null(i))
  8558. this->vl[cur_x]->set_null(i);
  8559. else
  8560. this->vl[cur_x]->set_not_null(i);
  8561. }
  8562. }
  8563. check_buf();
  8564. }
  8565. return *this;
  8566. }
  8567. #endif
  8568. #if defined(OTL_PL_TAB) && defined(OTL_STL)
  8569. OTL_TMPL_OUT_STREAM &operator<<(otl_pl_vec_generic &vec) {
  8570. if (this->vl_len > 0) {
  8571. get_next();
  8572. if (check_type(vec.get_vtype(), vec.get_elem_size())) {
  8573. int i, tmp_len;
  8574. if (vec.len() <= this->vl[cur_x]->get_array_size())
  8575. tmp_len = vec.len();
  8576. else
  8577. tmp_len = this->vl[cur_x]->get_array_size();
  8578. this->vl[cur_x]->set_pl_tab_len(tmp_len);
  8579. switch (vec.get_vtype()) {
  8580. case otl_var_char:
  8581. int i2;
  8582. for (i2 = 0; i2 < tmp_len; ++i2) {
  8583. int overflow;
  8584. otl_strcpy(
  8585. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(i2)),
  8586. OTL_RCAST(
  8587. unsigned char *,
  8588. OTL_CCAST(char *,
  8589. (*OTL_RCAST(STD_NAMESPACE_PREFIX
  8590. vector<OTL_STRING_CONTAINER> *,
  8591. vec.get_p_v()))[OTL_SCAST(size_t, i2)]
  8592. .c_str())),
  8593. overflow, this->vl[cur_x]->get_elem_size(),
  8594. OTL_SCAST(
  8595. int,
  8596. (*OTL_RCAST(
  8597. STD_NAMESPACE_PREFIX vector<OTL_STRING_CONTAINER> *,
  8598. vec.get_p_v()))[OTL_SCAST(size_t, i2)].length()));
  8599. if (overflow) {
  8600. char temp_var_info[256];
  8601. otl_var_info_var(this->vl[cur_x]->get_name(),
  8602. this->vl[cur_x]->get_ftype(), otl_var_char,
  8603. temp_var_info, sizeof(temp_var_info));
  8604. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8605. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  8606. OTL_THROW((OTL_TMPL_EXCEPTION(
  8607. otl_error_msg_4, otl_error_code_4,
  8608. this->stm_label ? this->stm_label : this->stm_text,
  8609. temp_var_info,
  8610. OTL_RCAST(
  8611. const void *,
  8612. (*OTL_RCAST(
  8613. STD_NAMESPACE_PREFIX vector<OTL_STRING_CONTAINER> *,
  8614. vec.get_p_v()))[i2].c_str()),
  8615. OTL_SCAST(int, this->vl[cur_x]->get_elem_size()))));
  8616. #else
  8617. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_4, otl_error_code_4,
  8618. this->stm_label ? this->stm_label
  8619. : this->stm_text,
  8620. temp_var_info)));
  8621. #endif
  8622. }
  8623. }
  8624. break;
  8625. case otl_var_timestamp: {
  8626. otl_oracle_date *int_dt =
  8627. OTL_RCAST(otl_oracle_date *, this->vl[cur_x]->val());
  8628. int j;
  8629. otl_datetime *ext_dt;
  8630. for (j = 0; j < tmp_len; ++j) {
  8631. ext_dt = OTL_RCAST(
  8632. otl_datetime *,
  8633. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<otl_datetime> *,
  8634. vec.get_p_v()))[OTL_SCAST(size_t, j)]);
  8635. convert_date(*int_dt, *ext_dt);
  8636. ++int_dt;
  8637. }
  8638. } break;
  8639. case otl_var_int:
  8640. if (tmp_len > 0)
  8641. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8642. OTL_RCAST(char *,
  8643. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<int> *,
  8644. vec.get_p_v()))[0]),
  8645. sizeof(int) * OTL_SCAST(size_t, tmp_len));
  8646. break;
  8647. case otl_var_double:
  8648. if (tmp_len > 0)
  8649. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8650. OTL_RCAST(char *,
  8651. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<double> *,
  8652. vec.get_p_v()))[0]),
  8653. sizeof(double) * OTL_SCAST(size_t, tmp_len));
  8654. break;
  8655. case otl_var_bdouble:
  8656. if (tmp_len > 0)
  8657. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8658. OTL_RCAST(char *,
  8659. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<double> *,
  8660. vec.get_p_v()))[0]),
  8661. sizeof(double) * OTL_SCAST(size_t, tmp_len));
  8662. break;
  8663. case otl_var_float:
  8664. if (tmp_len > 0)
  8665. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8666. OTL_RCAST(char *,
  8667. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<float> *,
  8668. vec.get_p_v()))[0]),
  8669. sizeof(float) * OTL_SCAST(size_t, tmp_len));
  8670. break;
  8671. case otl_var_bfloat:
  8672. if (tmp_len > 0)
  8673. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8674. OTL_RCAST(char *,
  8675. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<float> *,
  8676. vec.get_p_v()))[0]),
  8677. sizeof(float) * OTL_SCAST(size_t, tmp_len));
  8678. break;
  8679. case otl_var_unsigned_int:
  8680. if (tmp_len > 0)
  8681. memcpy(
  8682. OTL_RCAST(char *, this->vl[cur_x]->val()),
  8683. OTL_RCAST(char *,
  8684. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<unsigned> *,
  8685. vec.get_p_v()))[0]),
  8686. sizeof(unsigned) * OTL_SCAST(size_t, tmp_len));
  8687. break;
  8688. case otl_var_short:
  8689. if (tmp_len > 0)
  8690. memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()),
  8691. OTL_RCAST(char *,
  8692. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<short> *,
  8693. vec.get_p_v()))[0]),
  8694. sizeof(short) * OTL_SCAST(size_t, tmp_len));
  8695. break;
  8696. case otl_var_long_int:
  8697. if (tmp_len > 0)
  8698. memcpy(
  8699. OTL_RCAST(char *, this->vl[cur_x]->val()),
  8700. OTL_RCAST(char *,
  8701. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<long int> *,
  8702. vec.get_p_v()))[0]),
  8703. sizeof(long int) * OTL_SCAST(size_t, tmp_len));
  8704. break;
  8705. }
  8706. for (i = 0; i < tmp_len; ++i) {
  8707. if (vec.is_null(i))
  8708. this->vl[cur_x]->set_null(i);
  8709. else
  8710. this->vl[cur_x]->set_not_null(i);
  8711. }
  8712. }
  8713. check_buf();
  8714. }
  8715. return *this;
  8716. }
  8717. #endif
  8718. OTL_TMPL_OUT_STREAM &operator<<(const otl_null & /* n */) {
  8719. if (this->vl_len > 0) {
  8720. get_next();
  8721. this->vl[cur_x]->set_null(cur_y);
  8722. check_buf();
  8723. }
  8724. return *this;
  8725. }
  8726. OTL_TMPL_OUT_STREAM &operator<<(const TTimestampStruct &t) {
  8727. if (this->vl_len > 0) {
  8728. get_next();
  8729. if (check_type(otl_var_timestamp, sizeof(TTimestampStruct))) {
  8730. TTimestampStruct *tm =
  8731. OTL_RCAST(TTimestampStruct *, this->vl[cur_x]->val(cur_y));
  8732. this->vl[cur_x]->set_not_null(cur_y);
  8733. int rc = this->vl[cur_x]->get_var_struct().write_dt(
  8734. tm, &t, sizeof(TTimestampStruct));
  8735. if (rc == 0) {
  8736. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8737. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  8738. this->stm_label ? this->stm_label
  8739. : this->stm_text)));
  8740. }
  8741. }
  8742. check_buf();
  8743. }
  8744. return *this;
  8745. }
  8746. OTL_TMPL_OUT_STREAM &operator<<(const otl_long_string &s) {
  8747. if (this->vl_len > 0) {
  8748. get_next();
  8749. switch (this->vl[cur_x]->get_ftype()) {
  8750. case otl_var_varchar_long:
  8751. case otl_var_raw_long:
  8752. case otl_var_raw: {
  8753. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  8754. if (!s.get_unicode_flag() && in_unicode_mode &&
  8755. this->vl[cur_x]->get_ftype() == otl_var_varchar_long) {
  8756. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  8757. this->stm_label ? this->stm_label
  8758. : this->stm_text)));
  8759. } else if (s.get_unicode_flag() &&
  8760. this->vl[cur_x]->get_ftype() != otl_var_varchar_long) {
  8761. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  8762. this->stm_label ? this->stm_label
  8763. : this->stm_text)));
  8764. }
  8765. unsigned char *c =
  8766. OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y));
  8767. int len = OTL_CCAST(otl_long_string *, &s)->len();
  8768. this->vl[cur_x]->set_not_null(cur_y);
  8769. if (len > this->vl[cur_x]->actual_elem_size()) {
  8770. otl_var_info_var(this->vl[cur_x]->get_name(),
  8771. this->vl[cur_x]->get_ftype(), otl_var_long_string,
  8772. var_info, sizeof(var_info));
  8773. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8774. OTL_THROW((OTL_TMPL_EXCEPTION(
  8775. otl_error_msg_5, otl_error_code_5,
  8776. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8777. }
  8778. if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() ==
  8779. OTL_ADAPTER_ENUM otl_ora8_adapter) &&
  8780. this->vl[cur_x]->get_ftype() == otl_var_raw) {
  8781. otl_memcpy(c + sizeof(unsigned short), s.v, len,
  8782. this->vl[cur_x]->get_ftype());
  8783. *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) =
  8784. OTL_SCAST(unsigned short, len);
  8785. this->vl[cur_x]->set_len(len, cur_y);
  8786. } else {
  8787. otl_memcpy(c, s.v, len, this->vl[cur_x]->get_ftype());
  8788. this->vl[cur_x]->set_len(len, cur_y);
  8789. }
  8790. } break;
  8791. case otl_var_blob:
  8792. case otl_var_clob: {
  8793. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  8794. if (!s.get_unicode_flag() && in_unicode_mode &&
  8795. this->vl[cur_x]->get_ftype() == otl_var_clob) {
  8796. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  8797. this->stm_label ? this->stm_label
  8798. : this->stm_text)));
  8799. } else if (s.get_unicode_flag() &&
  8800. this->vl[cur_x]->get_ftype() == otl_var_blob) {
  8801. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  8802. this->stm_label ? this->stm_label
  8803. : this->stm_text)));
  8804. }
  8805. int len = OTL_CCAST(otl_long_string *, &s)->len();
  8806. if (len > this->vl[cur_x]->actual_elem_size()) {
  8807. otl_var_info_var(this->vl[cur_x]->get_name(),
  8808. this->vl[cur_x]->get_ftype(), otl_var_long_string,
  8809. var_info, sizeof(var_info));
  8810. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8811. OTL_THROW((OTL_TMPL_EXCEPTION(
  8812. otl_error_msg_5, otl_error_code_5,
  8813. this->stm_label ? this->stm_label : this->stm_text, var_info)));
  8814. }
  8815. this->vl[cur_x]->set_not_null(cur_y);
  8816. (void)this->vl[cur_x]->get_var_struct().save_blob(s.v, len, s.get_extern_buffer_flag());
  8817. } break;
  8818. }
  8819. check_buf();
  8820. }
  8821. return *this;
  8822. }
  8823. #if defined(OTL_ORA8) || defined(OTL_ODBC)
  8824. #define OTL_TMPL_CUR_DUMMY OTL_TMPL_CURSOR
  8825. OTL_TMPL_OUT_STREAM &operator<<(otl_lob_stream_generic &s) {
  8826. if (this->vl_len > 0) {
  8827. get_next();
  8828. if (((s.get_ora_lob() && this->vl[cur_x]->get_ftype() == otl_var_blob) ||
  8829. this->vl[cur_x]->get_ftype() == otl_var_clob) ||
  8830. (this->vl[cur_x]->get_ftype() == otl_var_varchar_long ||
  8831. this->vl[cur_x]->get_ftype() == otl_var_raw_long)) {
  8832. s.init(this->vl[cur_x], this->adb,
  8833. OTL_RCAST(OTL_TMPL_CUR_DUMMY *, this), 0,
  8834. OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode));
  8835. if (!s.get_ora_lob())
  8836. this->vl[cur_x]->set_not_null(cur_y);
  8837. }
  8838. check_buf();
  8839. } else {
  8840. char temp_var_info[256];
  8841. otl_var_info_var(this->vl[cur_x]->get_name(),
  8842. this->vl[cur_x]->get_ftype(), otl_var_long_string,
  8843. temp_var_info, sizeof(temp_var_info));
  8844. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8845. OTL_THROW((OTL_TMPL_EXCEPTION(
  8846. otl_error_msg_0, otl_error_code_0,
  8847. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  8848. }
  8849. return *this;
  8850. }
  8851. #undef OTL_TMPL_CUR_DUMMY
  8852. #endif
  8853. #if defined(OTL_ORA_SDO_GEOMETRY)
  8854. OTL_TMPL_OUT_STREAM &operator << (const oci_spatial_geometry &s){
  8855. if(this->vl_len > 0){
  8856. get_next();
  8857. if(check_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){
  8858. int rc = this->vl[cur_x]->get_var_struct().write_geometry(s, cur_y);
  8859. if(rc == 0){
  8860. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  8861. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  8862. this->stm_label ? this->stm_label
  8863. : this->stm_text)));
  8864. }
  8865. }
  8866. this->vl[cur_x]->set_not_null(cur_y);
  8867. check_buf();
  8868. }
  8869. return *this;
  8870. }
  8871. #endif
  8872. otl_tmpl_out_stream()
  8873. : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0),
  8874. array_size(0), in_exception_flag(0), in_destruct_flag(0),
  8875. should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0),
  8876. lob_stream_mode(0), master_stream_ptr_(nullptr) {}
  8877. private:
  8878. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  8879. public:
  8880. otl_tmpl_out_stream(const otl_tmpl_out_stream &) = delete;
  8881. otl_tmpl_out_stream &operator=(const otl_tmpl_out_stream &) = delete;
  8882. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  8883. otl_tmpl_out_stream(otl_tmpl_out_stream &&) = delete;
  8884. otl_tmpl_out_stream &operator=(otl_tmpl_out_stream &&) = delete;
  8885. #endif
  8886. private:
  8887. #else
  8888. otl_tmpl_out_stream(const otl_tmpl_out_stream &)
  8889. : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0),
  8890. array_size(0), in_exception_flag(0), in_destruct_flag(0),
  8891. should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0),
  8892. lob_stream_mode(0), master_stream_ptr_(nullptr) {}
  8893. otl_tmpl_out_stream &operator=(const otl_tmpl_out_stream &) { return *this; }
  8894. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  8895. otl_tmpl_out_stream(otl_tmpl_out_stream &&)
  8896. : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0),
  8897. array_size(0), in_exception_flag(0), in_destruct_flag(0),
  8898. should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0),
  8899. lob_stream_mode(0), master_stream_ptr_(nullptr) {}
  8900. otl_tmpl_out_stream &operator=(otl_tmpl_out_stream &&) { return *this; }
  8901. #endif
  8902. #endif
  8903. };
  8904. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  8905. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
  8906. OTL_TYPE_NAME TTimestampStruct>
  8907. class otl_tmpl_inout_stream : public OTL_TMPL_OUT_STREAM {
  8908. protected:
  8909. otl_tmpl_variable<TVariableStruct> **in_vl;
  8910. int iv_len;
  8911. int cur_in_x;
  8912. int cur_in_y;
  8913. int in_y_len;
  8914. int null_fetched;
  8915. otl_tmpl_variable<TVariableStruct> **avl;
  8916. int avl_len;
  8917. char var_info[256];
  8918. public:
  8919. void set_batch_error_mode(const bool batch_error_mode) {
  8920. OTL_TMPL_CURSOR::set_batch_error_mode(batch_error_mode);
  8921. }
  8922. OTL_NODISCARD int get_iv_len() const { return iv_len; }
  8923. OTL_NODISCARD otl_tmpl_variable<TVariableStruct> **get_in_vl() { return in_vl; }
  8924. void cleanup(void) {
  8925. int i;
  8926. for (i = 0; i < avl_len; ++i) {
  8927. delete avl[i];
  8928. }
  8929. delete[] avl;
  8930. delete[] in_vl;
  8931. }
  8932. otl_tmpl_inout_stream(otl_stream_buffer_size_type arr_size,
  8933. const char *sqlstm, OTL_TMPL_CONNECT &pdb,
  8934. void *master_stream_ptr,
  8935. const bool alob_stream_mode = false,
  8936. const char *sqlstm_label = nullptr)
  8937. : OTL_TMPL_OUT_STREAM(pdb, master_stream_ptr, alob_stream_mode,
  8938. sqlstm_label),
  8939. in_vl(nullptr), iv_len(0), cur_in_x(0), cur_in_y(0), in_y_len(0),
  8940. null_fetched(0), avl(nullptr), avl_len(0), var_info() {
  8941. int i, j;
  8942. this->dirty = 0;
  8943. this->auto_commit_flag = 1;
  8944. this->adb = &pdb;
  8945. this->in_exception_flag = 0;
  8946. this->stm_text = nullptr;
  8947. this->array_size = arr_size;
  8948. this->should_delete_flag = 0;
  8949. {
  8950. size_t len = strlen(sqlstm) + 1;
  8951. this->stm_text = new char[len];
  8952. OTL_STRCPY_S(this->stm_text, len, sqlstm);
  8953. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
  8954. TConnectStruct, TCursorStruct> hvd(this->stm_text,
  8955. arr_size);
  8956. if (hvd.has_plsql_tabs_or_refcur() && arr_size > 1) {
  8957. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  8958. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_33, otl_error_code_33,
  8959. this->stm_label ? this->stm_label
  8960. : this->stm_text)));
  8961. }
  8962. if (hvd.has_space_in_bind_variable()) {
  8963. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  8964. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_36, otl_error_code_36,
  8965. this->stm_label ? this->stm_label
  8966. : this->stm_text)));
  8967. }
  8968. if (hvd.bind_var_terminator_is_missing()) {
  8969. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  8970. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_43, otl_error_code_43,
  8971. this->stm_label ? this->stm_label
  8972. : this->stm_text)));
  8973. }
  8974. if (hvd.get_vst(otl_tmpl_ext_hv_decl<
  8975. TVariableStruct, TTimestampStruct, TExceptionStruct,
  8976. TConnectStruct, TCursorStruct>::def) == hvd.get_len()) {
  8977. this->should_delete_flag = 1;
  8978. hvd.alloc_host_var_list(this->vl, this->vl_len, pdb);
  8979. } else {
  8980. for (i = 0; i < hvd.get_len(); ++i) {
  8981. if (hvd.get_inout(i) ==
  8982. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  8983. TExceptionStruct, TConnectStruct,
  8984. TCursorStruct>::in)
  8985. ++this->vl_len;
  8986. else if (hvd.get_inout(i) ==
  8987. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  8988. TExceptionStruct, TConnectStruct,
  8989. TCursorStruct>::out)
  8990. ++iv_len;
  8991. else if (hvd.get_inout(i) ==
  8992. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  8993. TExceptionStruct, TConnectStruct,
  8994. TCursorStruct>::io) {
  8995. ++this->vl_len;
  8996. ++iv_len;
  8997. }
  8998. }
  8999. if (this->vl_len > 0) {
  9000. this->vl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,this->vl_len)];
  9001. }
  9002. if (iv_len > 0)
  9003. in_vl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,iv_len)];
  9004. avl_len = hvd.get_len();
  9005. if (hvd.get_len() > 0)
  9006. avl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,avl_len)];
  9007. iv_len = 0;
  9008. this->vl_len = 0;
  9009. for (j = 0; j < avl_len; ++j) {
  9010. #if defined(OTL_STREAM_LEGACY_BUFFER_SIZE_TYPE)
  9011. if (hvd.pl_tab_size[j] > 32767) {
  9012. char tmp_var_info[256];
  9013. otl_var_info_var(hvd[j], otl_var_none, otl_var_none, tmp_var_info,
  9014. sizeof(tmp_var_info));
  9015. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  9016. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_6, otl_error_code_6,
  9017. this->stm_label ? this->stm_label
  9018. : this->stm_text,
  9019. tmp_var_info)));
  9020. }
  9021. #endif
  9022. otl_tmpl_variable<TVariableStruct> *v = hvd.alloc_var(
  9023. hvd[j], hvd.get_inout(j),
  9024. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  9025. TExceptionStruct, TConnectStruct,
  9026. TCursorStruct>::def,
  9027. pdb, hvd.get_pl_tab_size(j));
  9028. if (v == nullptr) {
  9029. int k;
  9030. if (avl != nullptr)
  9031. for (k = 0; k < j; ++k) {
  9032. delete avl[k];
  9033. avl[k] = nullptr;
  9034. }
  9035. delete[] avl;
  9036. avl = nullptr;
  9037. this->vl_len = 0;
  9038. OTL_THROW((OTL_TMPL_EXCEPTION(
  9039. otl_error_msg_12, otl_error_code_12,
  9040. hvd.stm_label() ? hvd.stm_label() : hvd.stm_text(), hvd[j])));
  9041. }
  9042. if (v != nullptr)
  9043. v->set_name_pos(j + 1);
  9044. if (avl != nullptr)
  9045. avl[j] = v;
  9046. if (hvd.get_inout(j) ==
  9047. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  9048. TExceptionStruct, TConnectStruct,
  9049. TCursorStruct>::in) {
  9050. ++this->vl_len;
  9051. this->vl[this->vl_len - 1] = v;
  9052. v->set_param_type(otl_input_param);
  9053. } else if (hvd.get_inout(j) ==
  9054. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  9055. TExceptionStruct, TConnectStruct,
  9056. TCursorStruct>::out) {
  9057. ++iv_len;
  9058. in_vl[iv_len - 1] = v;
  9059. v->set_param_type(otl_output_param);
  9060. } else if (hvd.get_inout(j) ==
  9061. otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
  9062. TExceptionStruct, TConnectStruct,
  9063. TCursorStruct>::io) {
  9064. ++this->vl_len;
  9065. ++iv_len;
  9066. this->vl[this->vl_len - 1] = v;
  9067. if (in_vl != nullptr)
  9068. in_vl[iv_len - 1] = v;
  9069. v->set_param_type(otl_inout_param);
  9070. }
  9071. }
  9072. }
  9073. }
  9074. try {
  9075. this->parse();
  9076. for (i = 0; i < this->vl_len; ++i) {
  9077. if (this->vl[i]->get_var_struct().get_otl_adapter() ==
  9078. OTL_ADAPTER_ENUM otl_odbc_adapter) {
  9079. this->vl[i]->get_var_struct().set_lob_stream_mode(
  9080. this->lob_stream_mode);
  9081. this->vl[i]->get_var_struct().set_vparam_type(
  9082. this->vl[i]->get_param_type());
  9083. if (this->vl[i]->get_ftype() == otl_var_varchar_long ||
  9084. this->vl[i]->get_ftype() == otl_var_raw_long) {
  9085. this->vl[i]->set_not_null(0);
  9086. }
  9087. }
  9088. this->bind(*(this->vl[i]));
  9089. }
  9090. for (j = 0; j < iv_len; ++j)
  9091. this->bind(*in_vl[j]);
  9092. rewind();
  9093. }
  9094. catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) {
  9095. cleanup();
  9096. throw;
  9097. }
  9098. }
  9099. virtual ~otl_tmpl_inout_stream() OTL_THROWS_OTL_EXCEPTION3 {
  9100. this->in_destructor = 1;
  9101. if (!this->in_exception_flag)
  9102. flush();
  9103. cleanup();
  9104. }
  9105. OTL_NODISCARD int eof(void) {
  9106. if (iv_len == 0)
  9107. return 1;
  9108. if (in_y_len == 0)
  9109. return 1;
  9110. if (cur_in_y <= in_y_len - 1)
  9111. return 0;
  9112. return 1;
  9113. }
  9114. void flush(const int rowoff = 0, const bool force_flush = false) {
  9115. if (this->vl_len == 0)
  9116. return;
  9117. in_y_len = this->cur_y + 1;
  9118. cur_in_y = 0;
  9119. cur_in_x = 0;
  9120. if (!this->in_exception_flag)
  9121. OTL_TMPL_OUT_STREAM::flush(rowoff, force_flush);
  9122. }
  9123. void clean(const int clean_up_error_flag = 0) {
  9124. if (this->vl_len != 0) {
  9125. in_y_len = this->cur_y + 1;
  9126. cur_in_y = 0;
  9127. cur_in_x = 0;
  9128. }
  9129. OTL_TMPL_OUT_STREAM::clean(clean_up_error_flag);
  9130. }
  9131. void rewind(void) {
  9132. flush();
  9133. cur_in_x = 0;
  9134. cur_in_y = 0;
  9135. this->cur_x = -1;
  9136. this->cur_y = 0;
  9137. in_y_len = 0;
  9138. null_fetched = 0;
  9139. if (this->vl_len == 0) {
  9140. this->exec(this->array_size, 0, otl_sql_exec_from_cursor_class);
  9141. in_y_len = this->array_size;
  9142. cur_in_y = 0;
  9143. cur_in_x = 0;
  9144. }
  9145. }
  9146. OTL_NODISCARD int is_null(void) { return null_fetched; }
  9147. void skip_to_end_of_row() {
  9148. if (eof())
  9149. return;
  9150. if (iv_len == 0)
  9151. return;
  9152. if (in_y_len == 0)
  9153. return;
  9154. if (cur_in_y < in_y_len - 1) {
  9155. ++cur_in_y;
  9156. cur_in_x = 0;
  9157. } else {
  9158. cur_in_y = 0;
  9159. cur_in_x = 0;
  9160. in_y_len = 0;
  9161. }
  9162. }
  9163. void skip_to_next_var() {
  9164. if(eof())return;
  9165. if(iv_len==0)return;
  9166. if(in_y_len==0)return;
  9167. if(cur_in_y<in_y_len-1)
  9168. ++cur_in_y;
  9169. }
  9170. void get_in_next(void) {
  9171. if (iv_len == 0)
  9172. return;
  9173. if (in_y_len == 0)
  9174. return;
  9175. if (cur_in_x < iv_len - 1)
  9176. ++cur_in_x;
  9177. else {
  9178. if (cur_in_y < in_y_len - 1) {
  9179. ++cur_in_y;
  9180. cur_in_x = 0;
  9181. } else {
  9182. cur_in_y = 0;
  9183. cur_in_x = 0;
  9184. in_y_len = 0;
  9185. }
  9186. }
  9187. }
  9188. OTL_NODISCARD int check_in_type_throw(int type_code) {
  9189. this->in_exception_flag = 1;
  9190. otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(),
  9191. type_code, var_info, sizeof(var_info));
  9192. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  9193. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0,
  9194. this->stm_label ? this->stm_label : this->stm_text,
  9195. var_info)));
  9196. }
  9197. OTL_NODISCARD int check_in_type(int type_code, int tsize) {
  9198. switch (in_vl[cur_in_x]->get_ftype()) {
  9199. case otl_var_refcur:
  9200. if (type_code == otl_var_refcur)
  9201. return 1;
  9202. break;
  9203. case otl_var_db2time:
  9204. case otl_var_db2date:
  9205. if (type_code == otl_var_timestamp)
  9206. return 1;
  9207. break;
  9208. case otl_var_char:
  9209. if (type_code == otl_var_char)
  9210. return 1;
  9211. break;
  9212. case otl_var_bdouble:
  9213. if (type_code == otl_var_double)
  9214. return 1;
  9215. break;
  9216. case otl_var_bfloat:
  9217. if (type_code == otl_var_float)
  9218. return 1;
  9219. break;
  9220. default:
  9221. #if defined(OTL_CHECK_OUT_TYPE_FUNC)
  9222. if ((in_vl[cur_in_x]->get_ftype() == type_code &&
  9223. in_vl[cur_in_x]->get_elem_size() == tsize) ||
  9224. OTL_CHECK_OUT_TYPE_FUNC(in_vl[cur_in_x]->get_ftype(),type_code))
  9225. return 1;
  9226. break;
  9227. #else
  9228. if (in_vl[cur_in_x]->get_ftype() == type_code &&
  9229. in_vl[cur_in_x]->get_elem_size() == tsize)
  9230. return 1;
  9231. break;
  9232. #endif
  9233. }
  9234. return check_in_type_throw(type_code);
  9235. }
  9236. OTL_NODISCARD int is_null_intern(void) {
  9237. if (iv_len == 0)
  9238. return 0;
  9239. if (in_y_len == 0)
  9240. return 0;
  9241. if (in_y_len > 0)
  9242. return in_vl[cur_in_x]->is_null(cur_in_y);
  9243. return 0;
  9244. }
  9245. OTL_TMPL_INOUT_STREAM &operator>>(char &c) {
  9246. if (eof())
  9247. return *this;
  9248. if (check_in_type(otl_var_char, 1)) {
  9249. c = *OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y));
  9250. null_fetched = is_null_intern();
  9251. }
  9252. get_in_next();
  9253. return *this;
  9254. }
  9255. OTL_TMPL_INOUT_STREAM &operator>>(unsigned char &c) {
  9256. if (eof())
  9257. return *this;
  9258. if (check_in_type(otl_var_char, 1)) {
  9259. c = *OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y));
  9260. null_fetched = is_null_intern();
  9261. }
  9262. get_in_next();
  9263. return *this;
  9264. }
  9265. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  9266. OTL_TMPL_INOUT_STREAM &operator>>(OTL_STRING_CONTAINER &s) {
  9267. if (eof())
  9268. return *this;
  9269. switch (in_vl[cur_in_x]->get_ftype()) {
  9270. case otl_var_char: {
  9271. #if defined(OTL_ACE)
  9272. s.set(OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y)), 1);
  9273. #else
  9274. s = OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y));
  9275. #endif
  9276. null_fetched = is_null_intern();
  9277. } break;
  9278. #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE)
  9279. case otl_var_varchar_long:
  9280. case otl_var_raw_long: {
  9281. unsigned char *c =
  9282. OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y));
  9283. int len = in_vl[cur_in_x]->get_len();
  9284. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  9285. !defined(USER_DEFINED_STRING_CLASS))
  9286. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len));
  9287. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  9288. s.assign(OTL_RCAST(char *, c), len);
  9289. #elif defined(OTL_ACE)
  9290. s.set(OTL_RCAST(char *, c), len, 1);
  9291. #endif
  9292. null_fetched = is_null_intern();
  9293. } break;
  9294. case otl_var_blob:
  9295. case otl_var_clob: {
  9296. int len = 0;
  9297. int max_long_sz = this->adb->get_max_long_size();
  9298. otl_auto_array_ptr<unsigned char> loc_ptr(max_long_sz);
  9299. unsigned char *temp_buf = loc_ptr.get_ptr();
  9300. int rc = in_vl[cur_in_x]->get_var_struct().get_blob(cur_in_y, temp_buf,
  9301. max_long_sz, len);
  9302. if (rc == 0) {
  9303. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9304. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  9305. this->stm_label ? this->stm_label
  9306. : this->stm_text)));
  9307. }
  9308. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  9309. !defined(USER_DEFINED_STRING_CLASS))
  9310. s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len));
  9311. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  9312. s.assign(OTL_RCAST(char *, temp_buf), len);
  9313. #elif defined(OTL_ACE)
  9314. s.set(OTL_RCAST(char *, temp_buf), len, 1);
  9315. #endif
  9316. null_fetched = is_null_intern();
  9317. } break;
  9318. #endif
  9319. default:
  9320. (void)check_in_type(otl_var_char, 1);
  9321. break;
  9322. } // switch
  9323. get_in_next();
  9324. return *this;
  9325. }
  9326. #endif
  9327. OTL_TMPL_INOUT_STREAM &operator>>(char *s) {
  9328. if (eof())
  9329. return *this;
  9330. if (check_in_type(otl_var_char, 1)) {
  9331. otl_strcpy(
  9332. OTL_RCAST(unsigned char *, s),
  9333. OTL_RCAST(const unsigned char *, in_vl[cur_in_x]->val(cur_in_y)));
  9334. null_fetched = is_null_intern();
  9335. }
  9336. get_in_next();
  9337. return *this;
  9338. }
  9339. void getString(char *s, int max_size) {
  9340. if (eof())
  9341. return;
  9342. if (check_in_type(otl_var_char, 1)) {
  9343. otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(),
  9344. const_STD_CHAR_ARRAY_code, var_info, sizeof(var_info));
  9345. if(max_size<in_vl[cur_in_x]->get_len(cur_in_y)){
  9346. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
  9347. TCursorStruct>(otl_error_msg_45,
  9348. otl_error_code_45,
  9349. this->stm_label ? this->stm_label : this->stm_text,
  9350. this->var_info)));
  9351. }
  9352. otl_strcpy(
  9353. OTL_RCAST(unsigned char *, s),
  9354. OTL_RCAST(const unsigned char *, in_vl[cur_in_x]->val(cur_in_y)));
  9355. null_fetched = is_null_intern();
  9356. }
  9357. get_in_next();
  9358. }
  9359. #if defined(OTL_UNICODE_STRING_TYPE)
  9360. OTL_TMPL_INOUT_STREAM &operator>>(OTL_UNICODE_STRING_TYPE &s) {
  9361. if (eof())
  9362. return *this;
  9363. if (check_in_type(otl_var_char, 1)) {
  9364. #if defined(OTL_ODBC) || defined(DB2_CLI)
  9365. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y));
  9366. #else
  9367. #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR)
  9368. OTL_UNICODE_CHAR_TYPE *temp_s =
  9369. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y));
  9370. OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s);
  9371. #else
  9372. OTL_UNICODE_CHAR_TYPE *temp_s =
  9373. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y));
  9374. s.assign(temp_s + 1, *temp_s);
  9375. #endif
  9376. #endif
  9377. null_fetched = is_null_intern();
  9378. }
  9379. get_in_next();
  9380. return *this;
  9381. }
  9382. #endif
  9383. OTL_TMPL_INOUT_STREAM &operator>>(unsigned char *s) {
  9384. if (eof())
  9385. return *this;
  9386. if (check_in_type(otl_var_char, 1)) {
  9387. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  9388. OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)),
  9389. in_vl[cur_in_x]->get_len(cur_in_y));
  9390. null_fetched = is_null_intern();
  9391. }
  9392. get_in_next();
  9393. return *this;
  9394. }
  9395. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  9396. void getString(char16_t *s, int max_size) {
  9397. if (eof())
  9398. return;
  9399. if (check_in_type(otl_var_char, 1)) {
  9400. if(max_size<in_vl[cur_in_x]->get_len(cur_in_y))
  9401. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
  9402. TCursorStruct>(otl_error_msg_46,
  9403. otl_error_code_46,
  9404. this->stm_label ? this->stm_label : this->stm_text,
  9405. this->var_info)));
  9406. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  9407. OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)),
  9408. in_vl[cur_in_x]->get_len(cur_in_y));
  9409. null_fetched = is_null_intern();
  9410. }
  9411. get_in_next();
  9412. }
  9413. #endif
  9414. #if !defined(OTL_D4)
  9415. #define OTL_D4(T, T_type) \
  9416. OTL_TMPL_INOUT_STREAM &operator>>(T &n) { \
  9417. if (eof()) \
  9418. return *this; \
  9419. if (check_in_type(T_type, sizeof(T))) { \
  9420. n = *OTL_RCAST(T *, in_vl[cur_in_x]->val(cur_in_y)); \
  9421. null_fetched = is_null_intern(); \
  9422. } \
  9423. get_in_next(); \
  9424. return *this; \
  9425. }
  9426. #endif
  9427. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  9428. OTL_D4(int, otl_var_int)
  9429. OTL_D4(unsigned, otl_var_unsigned_int)
  9430. #if defined(OTL_BIGINT)
  9431. OTL_D4(OTL_BIGINT, otl_var_bigint)
  9432. #endif
  9433. #if defined(OTL_UBIGINT)
  9434. OTL_D4(OTL_UBIGINT, otl_var_ubigint)
  9435. #endif
  9436. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  9437. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  9438. OTL_D4(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  9439. #endif
  9440. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  9441. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  9442. OTL_D4(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  9443. #endif
  9444. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  9445. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  9446. OTL_D4(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  9447. #endif
  9448. OTL_D4(long, otl_var_long_int)
  9449. OTL_D4(short, otl_var_short)
  9450. OTL_D4(float, otl_var_float)
  9451. OTL_D4(double, otl_var_double)
  9452. #else
  9453. template<OTL_TYPE_NAME T,const int T_type> OTL_D4(T,T_type)
  9454. #endif
  9455. #if defined(OTL_PL_TAB)
  9456. OTL_TMPL_INOUT_STREAM &operator>>(otl_pl_tab_generic &tab) {
  9457. if (eof())
  9458. return *this;
  9459. if (check_in_type(tab.get_vtype(), tab.get_elem_size())) {
  9460. int i, tmp_len;
  9461. tmp_len = in_vl[cur_in_x]->get_pl_tab_len();
  9462. if (tab.get_tab_size() < tmp_len)
  9463. tmp_len = tab.get_tab_size();
  9464. tab.set_len(tmp_len);
  9465. if (tab.get_vtype() == otl_var_char) {
  9466. for (i = 0; i < tmp_len; ++i) {
  9467. int overflow;
  9468. otl_strcpy3(OTL_RCAST(unsigned char *, tab.val(i)),
  9469. OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(i)),
  9470. in_vl[cur_in_x]->get_len(i), overflow,
  9471. tab.get_elem_size());
  9472. }
  9473. } else if (tab.get_vtype() == otl_var_timestamp) {
  9474. otl_datetime *ext_dt = OTL_RCAST(otl_datetime *, tab.get_p_v());
  9475. otl_oracle_date *int_dt =
  9476. OTL_RCAST(otl_oracle_date *, in_vl[cur_in_x]->val());
  9477. int j;
  9478. for (j = 0; j < tmp_len; ++j) {
  9479. convert_date(*ext_dt, *int_dt);
  9480. ++int_dt;
  9481. ++ext_dt;
  9482. }
  9483. } else
  9484. memcpy(OTL_RCAST(char *, tab.val()),
  9485. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9486. OTL_SCAST(size_t, tab.get_elem_size() * tmp_len));
  9487. for (i = 0; i < tmp_len; ++i) {
  9488. if (in_vl[cur_in_x]->is_null(i))
  9489. tab.set_null(i);
  9490. else
  9491. tab.set_non_null(i);
  9492. }
  9493. null_fetched = 0;
  9494. }
  9495. get_in_next();
  9496. return *this;
  9497. }
  9498. #endif
  9499. #if defined(OTL_PL_TAB) && defined(OTL_STL)
  9500. OTL_TMPL_INOUT_STREAM &operator>>(otl_pl_vec_generic &vec) {
  9501. if (eof())
  9502. return *this;
  9503. if (check_in_type(vec.get_vtype(), vec.get_elem_size())) {
  9504. int i, tmp_len;
  9505. tmp_len = in_vl[cur_in_x]->get_pl_tab_len();
  9506. vec.set_len(tmp_len);
  9507. if (tmp_len > 0) {
  9508. switch (vec.get_vtype()) {
  9509. case otl_var_char:
  9510. for (i = 0; i < tmp_len; ++i) {
  9511. (*OTL_RCAST(STD_NAMESPACE_PREFIX vector<OTL_STRING_CONTAINER> *,
  9512. vec.get_p_v()))[OTL_SCAST(size_t, i)] =
  9513. OTL_RCAST(char *, in_vl[cur_in_x]->val(i));
  9514. }
  9515. break;
  9516. case otl_var_timestamp: {
  9517. otl_datetime *ext_dt;
  9518. otl_oracle_date *int_dt =
  9519. OTL_RCAST(otl_oracle_date *, in_vl[cur_in_x]->val());
  9520. int j;
  9521. for (j = 0; j < tmp_len; ++j) {
  9522. ext_dt = OTL_RCAST(
  9523. otl_datetime *,
  9524. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<otl_datetime> *,
  9525. vec.get_p_v()))[OTL_SCAST(size_t, j)]);
  9526. convert_date(*ext_dt, *int_dt);
  9527. ++int_dt;
  9528. }
  9529. } break;
  9530. case otl_var_int:
  9531. memcpy(
  9532. OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<int> *,
  9533. vec.get_p_v()))[0]),
  9534. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9535. sizeof(int) * OTL_SCAST(size_t, tmp_len));
  9536. break;
  9537. case otl_var_double:
  9538. memcpy(OTL_RCAST(char *,
  9539. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<double> *,
  9540. vec.get_p_v()))[0]),
  9541. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9542. sizeof(double) * OTL_SCAST(size_t, tmp_len));
  9543. break;
  9544. case otl_var_bdouble:
  9545. memcpy(OTL_RCAST(char *,
  9546. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<double> *,
  9547. vec.get_p_v()))[0]),
  9548. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9549. sizeof(double) * OTL_SCAST(size_t, tmp_len));
  9550. break;
  9551. case otl_var_float:
  9552. memcpy(OTL_RCAST(char *,
  9553. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<float> *,
  9554. vec.get_p_v()))[0]),
  9555. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9556. sizeof(float) * OTL_SCAST(size_t, tmp_len));
  9557. break;
  9558. case otl_var_bfloat:
  9559. memcpy(OTL_RCAST(char *,
  9560. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<float> *,
  9561. vec.get_p_v()))[0]),
  9562. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9563. sizeof(float) * OTL_SCAST(size_t, tmp_len));
  9564. break;
  9565. case otl_var_unsigned_int:
  9566. memcpy(OTL_RCAST(char *,
  9567. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<unsigned> *,
  9568. vec.get_p_v()))[0]),
  9569. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9570. sizeof(unsigned) * OTL_SCAST(size_t, tmp_len));
  9571. break;
  9572. case otl_var_short:
  9573. memcpy(OTL_RCAST(char *,
  9574. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<short> *,
  9575. vec.get_p_v()))[0]),
  9576. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9577. sizeof(short) * OTL_SCAST(size_t, tmp_len));
  9578. break;
  9579. case otl_var_long_int:
  9580. memcpy(OTL_RCAST(char *,
  9581. &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector<long int> *,
  9582. vec.get_p_v()))[0]),
  9583. OTL_RCAST(char *, in_vl[cur_in_x]->val()),
  9584. sizeof(long int) * OTL_SCAST(size_t, tmp_len));
  9585. break;
  9586. }
  9587. }
  9588. for (i = 0; i < tmp_len; ++i) {
  9589. if (in_vl[cur_in_x]->is_null(i))
  9590. vec.set_null(i);
  9591. else
  9592. vec.set_non_null(i);
  9593. }
  9594. null_fetched = 0;
  9595. }
  9596. get_in_next();
  9597. return *this;
  9598. }
  9599. #endif
  9600. OTL_TMPL_INOUT_STREAM &operator>>(TTimestampStruct &t) {
  9601. if (eof())
  9602. return *this;
  9603. if (check_in_type(otl_var_timestamp, sizeof(TTimestampStruct))) {
  9604. TTimestampStruct *tm =
  9605. OTL_RCAST(TTimestampStruct *, in_vl[cur_in_x]->val(cur_in_y));
  9606. int rc = in_vl[cur_in_x]->get_var_struct().read_dt(
  9607. &t, tm, sizeof(TTimestampStruct));
  9608. if (rc == 0) {
  9609. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9610. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  9611. this->stm_label ? this->stm_label
  9612. : this->stm_text)));
  9613. }
  9614. null_fetched = is_null_intern();
  9615. }
  9616. get_in_next();
  9617. return *this;
  9618. }
  9619. OTL_TMPL_INOUT_STREAM &operator>>(otl_long_string &s) {
  9620. int len = 0;
  9621. if (eof())
  9622. return *this;
  9623. switch (in_vl[cur_in_x]->get_ftype()) {
  9624. case otl_var_raw:
  9625. case otl_var_varchar_long:
  9626. case otl_var_raw_long: {
  9627. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  9628. if (!s.get_unicode_flag() && in_unicode_mode &&
  9629. in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long) {
  9630. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  9631. this->stm_label ? this->stm_label
  9632. : this->stm_text)));
  9633. } else if (s.get_unicode_flag() &&
  9634. in_vl[cur_in_x]->get_ftype() != otl_var_varchar_long) {
  9635. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  9636. this->stm_label ? this->stm_label
  9637. : this->stm_text)));
  9638. }
  9639. unsigned char *c =
  9640. OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y));
  9641. len = in_vl[cur_in_x]->get_len();
  9642. if (len > s.get_buf_size())
  9643. len = s.get_buf_size();
  9644. otl_memcpy(s.v, c, len, in_vl[cur_in_x]->get_ftype());
  9645. s.set_len(len);
  9646. if (in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long)
  9647. s.null_terminate_string(len);
  9648. null_fetched = is_null_intern();
  9649. } break;
  9650. case otl_var_clob:
  9651. case otl_var_blob: {
  9652. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  9653. if (!s.get_unicode_flag() && in_unicode_mode &&
  9654. in_vl[cur_in_x]->get_ftype() == otl_var_clob) {
  9655. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37,
  9656. this->stm_label ? this->stm_label
  9657. : this->stm_text)));
  9658. } else if (s.get_unicode_flag() &&
  9659. in_vl[cur_in_x]->get_ftype() == otl_var_blob) {
  9660. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38,
  9661. this->stm_label ? this->stm_label
  9662. : this->stm_text)));
  9663. }
  9664. int rc = in_vl[cur_in_x]->get_var_struct().get_blob(
  9665. cur_in_y, s.v, s.get_buf_size(), len);
  9666. if (rc == 0) {
  9667. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9668. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  9669. this->stm_label ? this->stm_label
  9670. : this->stm_text)));
  9671. }
  9672. if (len > s.get_buf_size())
  9673. len = s.get_buf_size();
  9674. s.set_len(len);
  9675. if (in_vl[cur_in_x]->get_ftype() == otl_var_clob)
  9676. s.null_terminate_string(len);
  9677. null_fetched = is_null_intern();
  9678. } break;
  9679. default: {
  9680. char temp_var_info[256];
  9681. otl_var_info_var(in_vl[cur_in_x]->get_name(),
  9682. in_vl[cur_in_x]->get_ftype(), otl_var_long_string,
  9683. temp_var_info, sizeof(temp_var_info));
  9684. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9685. OTL_THROW((OTL_TMPL_EXCEPTION(
  9686. otl_error_msg_0, otl_error_code_0,
  9687. this->stm_label ? this->stm_label : this->stm_text, temp_var_info)));
  9688. }
  9689. }
  9690. get_in_next();
  9691. return *this;
  9692. }
  9693. #if defined(OTL_ORA8) || defined(OTL_ODBC)
  9694. OTL_TMPL_INOUT_STREAM &operator>>(otl_lob_stream_generic &s) {
  9695. if (eof())
  9696. return *this;
  9697. if ((s.get_ora_lob() && in_vl[cur_in_x]->get_ftype() == otl_var_clob) ||
  9698. in_vl[cur_in_x]->get_ftype() == otl_var_blob) {
  9699. null_fetched = is_null_intern();
  9700. s.init(OTL_RCAST(void *, in_vl[cur_in_x]), OTL_RCAST(void *, this->adb),
  9701. OTL_RCAST(void *, this), 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode),
  9702. this->is_null());
  9703. } else if (in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long ||
  9704. in_vl[cur_in_x]->get_ftype() == otl_var_raw_long) {
  9705. s.init(OTL_RCAST(void *, in_vl[cur_in_x]), OTL_RCAST(void *, this->adb),
  9706. OTL_RCAST(void *, this), 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode));
  9707. } else {
  9708. char tmp_var_info[256];
  9709. otl_var_info_var(in_vl[cur_in_x]->get_name(),
  9710. in_vl[cur_in_x]->get_ftype(), otl_var_long_string,
  9711. tmp_var_info, sizeof(tmp_var_info));
  9712. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9713. OTL_THROW((OTL_TMPL_EXCEPTION(
  9714. otl_error_msg_0, otl_error_code_0,
  9715. this->stm_label ? this->stm_label : this->stm_text, tmp_var_info)));
  9716. }
  9717. get_in_next();
  9718. return *this;
  9719. }
  9720. #endif
  9721. #if defined(OTL_ORA_SDO_GEOMETRY)
  9722. OTL_TMPL_INOUT_STREAM &operator >> (oci_spatial_geometry &s){
  9723. if(eof())
  9724. return *this;
  9725. if(check_in_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){
  9726. int rc = in_vl[cur_in_x]->get_var_struct().read_geometry(s, cur_in_x);
  9727. if(rc == 0){
  9728. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  9729. OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(),
  9730. this->stm_label ? this->stm_label
  9731. : this->stm_text)));
  9732. }
  9733. null_fetched = is_null_intern();
  9734. }
  9735. get_in_next();
  9736. return *this;
  9737. }
  9738. #endif
  9739. otl_tmpl_inout_stream()
  9740. : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0),
  9741. cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0),
  9742. var_info() {}
  9743. private:
  9744. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  9745. public:
  9746. otl_tmpl_inout_stream(const otl_tmpl_inout_stream &) = delete;
  9747. otl_tmpl_inout_stream &operator=(const otl_tmpl_inout_stream &) = delete;
  9748. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  9749. otl_tmpl_inout_stream(otl_tmpl_inout_stream &&) = delete;
  9750. otl_tmpl_inout_stream &operator=(otl_tmpl_inout_stream &&) = delete;
  9751. #endif
  9752. private:
  9753. #else
  9754. otl_tmpl_inout_stream(const otl_tmpl_inout_stream &)
  9755. : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0),
  9756. cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0),
  9757. var_info() {}
  9758. otl_tmpl_inout_stream &operator=(const otl_tmpl_inout_stream &) {
  9759. return *this;
  9760. }
  9761. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  9762. otl_tmpl_inout_stream(otl_tmpl_inout_stream &&)
  9763. : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0),
  9764. cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0),
  9765. var_info() {}
  9766. otl_tmpl_inout_stream &operator=(otl_tmpl_inout_stream &&) { return *this; }
  9767. #endif
  9768. #endif
  9769. };
  9770. // ==================== OTL-Adapter for ODBC/CLI =========================
  9771. #if defined(OTL_ODBC)
  9772. // use recommended SQL type codes for temporal ODBC data types when
  9773. // ODBC 3.x is used
  9774. #if (defined(ODBCVER) && (ODBCVER >= 0x0300))
  9775. #define OTL_SQL_C_TIMESTAMP SQL_C_TYPE_TIMESTAMP
  9776. #define OTL_SQL_TIMESTAMP SQL_TYPE_TIMESTAMP
  9777. #define OTL_SQL_C_DATE SQL_C_TYPE_DATE
  9778. #define OTL_SQL_DATE SQL_TYPE_DATE
  9779. #define OTL_SQL_C_TIME SQL_C_TYPE_TIME
  9780. #define OTL_SQL_TIME SQL_TYPE_TIME
  9781. #else
  9782. #define OTL_SQL_C_TIMESTAMP SQL_C_TIMESTAMP
  9783. #define OTL_SQL_TIMESTAMP SQL_TIMESTAMP
  9784. #define OTL_SQL_C_DATE SQL_C_DATE
  9785. #define OTL_SQL_DATE SQL_DATE
  9786. #define OTL_SQL_C_TIME SQL_C_TIME
  9787. #define OTL_SQL_TIME SQL_TIME
  9788. #endif
  9789. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) && \
  9790. !defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  9791. #error OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT can only be used when \
  9792. OTL_ODBC_SQL_EXTENDED_FETCH_ON is defined
  9793. #endif
  9794. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  9795. #if !defined(OTL_DB2_CLI)
  9796. #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE
  9797. #define OTL_SQL_NULL_HANDLE_VAL nullptr
  9798. #else
  9799. #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE
  9800. #define OTL_SQL_NULL_HANDLE_VAL 0
  9801. #endif
  9802. #else
  9803. #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE
  9804. #define OTL_SQL_NULL_HANDLE_VAL 0
  9805. #endif
  9806. #if !defined(OTL_DB2_CLI) && !defined(OTL_ODBC_zOS)
  9807. // in case it's ODBC for Windows (!OTL_ODBC_UNIX), and windows.h is
  9808. // not included yet (_WINDOWS_ not defined yet), then include the file
  9809. // explicitly
  9810. #if !defined(OTL_ODBC_UNIX) && !defined(_WINDOWS_)
  9811. #include <windows.h>
  9812. #endif
  9813. #if defined(OTL_ODBC_UNIX) && defined(OTL_INFORMIX_CLI_64_BIT)
  9814. #include <infxsql.h>
  9815. #define OTL_HENV SQLHANDLE
  9816. #define OTL_HDBC SQLHANDLE
  9817. #define OTL_SQLHANDLE SQLHANDLE
  9818. #define OTL_SQLRETURN SQLRETURN
  9819. #define OTL_SQLSMALLINT SQLSMALLINT
  9820. #define OTL_SQLCHAR_PTR SQLCHAR *
  9821. #define OTL_SQLINTEGER_PTR SQLINTEGER *
  9822. #define OTL_SQLSMALLINT_PTR SQLSMALLINT *
  9823. #define OTL_SQLINTEGER SQLINTEGER
  9824. #define OTL_SQLHSTMT SQLHSTMT
  9825. #define OTL_SQLUSMALLINT SQLUSMALLINT
  9826. #define OTL_SQLPOINTER SQLPOINTER
  9827. #define OTL_SQLCHAR SQLCHAR
  9828. #define OTL_SQLUINTEGER SQLUINTEGER
  9829. #define OTL_SQLLEN SQLLEN
  9830. #define OTL_SQLLEN_PTR SQLLEN *
  9831. #define OTL_SQLULEN SQLULEN
  9832. #define OTL_SQLULEN_PTR SQLULEN *
  9833. #elif defined(OTL_ODBC_UNIX) && defined(OTL_INFORMIX_CLI)
  9834. #include <infxsql.h>
  9835. #define OTL_HENV SQLHANDLE
  9836. #define OTL_HDBC SQLHANDLE
  9837. #define OTL_SQLHANDLE SQLHANDLE
  9838. #define OTL_SQLRETURN SQLRETURN
  9839. #define OTL_SQLSMALLINT SQLSMALLINT
  9840. #define OTL_SQLCHAR_PTR SQLCHAR *
  9841. #define OTL_SQLINTEGER_PTR SQLINTEGER *
  9842. #define OTL_SQLSMALLINT_PTR SQLSMALLINT *
  9843. #define OTL_SQLINTEGER SQLINTEGER
  9844. #define OTL_SQLHSTMT SQLHSTMT
  9845. #define OTL_SQLUSMALLINT SQLUSMALLINT
  9846. #define OTL_SQLPOINTER SQLPOINTER
  9847. #define OTL_SQLCHAR SQLCHAR
  9848. #define OTL_SQLUINTEGER SQLUINTEGER
  9849. #define OTL_SQLLEN SQLINTEGER
  9850. #define OTL_SQLLEN_PTR SQLINTEGER *
  9851. #define OTL_SQLULEN SQLUINTEGER
  9852. #define OTL_SQLULEN_PTR SQLUINTEGER *
  9853. #else
  9854. #include <sql.h>
  9855. #include <sqlext.h>
  9856. #endif
  9857. #else
  9858. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
  9859. #pragma clang diagnostic push
  9860. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  9861. #endif
  9862. #include <sqlcli1.h>
  9863. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
  9864. #pragma clang diagnostic pop
  9865. #endif
  9866. #endif
  9867. #if defined(OTL_ODBC) && !defined(OTL_DB2_CLI)
  9868. #define OTL_SQL_XML (-152)
  9869. #endif
  9870. #if defined(OTL_ODBC) && defined(OTL_DB2_CLI)
  9871. #if defined(SQL_XML)
  9872. #define OTL_SQL_XML SQL_XML
  9873. #else
  9874. #define OTL_SQL_XML (-370)
  9875. #endif
  9876. #endif
  9877. #if defined(OTL_ODBC)
  9878. #if (ODBCVER >= 0x0300)
  9879. #define OTL_SQL_TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT
  9880. #define OTL_SQL_TIME_STRUCT SQL_TIME_STRUCT
  9881. #define OTL_SQL_DATE_STRUCT SQL_DATE_STRUCT
  9882. #else
  9883. #define OTL_SQL_TIMESTAMP_STRUCT TIMESTAMP_STRUCT
  9884. #define OTL_SQL_TIME_STRUCT TIME_STRUCT
  9885. #define OTL_SQL_DATE_STRUCT DATE_STRUCT
  9886. #endif
  9887. #if defined(OTL_DB2_CLI)
  9888. #define OTL_HENV SQLHANDLE
  9889. #define OTL_HDBC SQLHANDLE
  9890. #define OTL_SQLHANDLE SQLHANDLE
  9891. #define OTL_SQLRETURN SQLRETURN
  9892. #define OTL_SQLSMALLINT SQLSMALLINT
  9893. #define OTL_SQLCHAR_PTR SQLCHAR *
  9894. #define OTL_SQLINTEGER_PTR SQLINTEGER *
  9895. #define OTL_SQLSMALLINT_PTR SQLSMALLINT *
  9896. #define OTL_SQLINTEGER SQLINTEGER
  9897. #define OTL_SQLHSTMT SQLHSTMT
  9898. #define OTL_SQLUSMALLINT SQLUSMALLINT
  9899. #define OTL_SQLPOINTER SQLPOINTER
  9900. #define OTL_SQLCHAR SQLCHAR
  9901. #define OTL_SQLUINTEGER SQLUINTEGER
  9902. #if defined(OTL_IODBC_BSD) || defined(_WIN64)
  9903. #define OTL_SQLLEN SQLLEN
  9904. #define OTL_SQLULEN SQLULEN
  9905. #define OTL_SQLULEN_PTR SQLULEN *
  9906. #define OTL_SQLLEN_PTR SQLLEN *
  9907. #else // #if defined(OTL_IODBC_BSD)
  9908. #define OTL_SQLLEN SQLINTEGER
  9909. #define OTL_SQLLEN_PTR SQLINTEGER *
  9910. #define OTL_SQLULEN SQLUINTEGER
  9911. #define OTL_SQLULEN_PTR SQLUINTEGER *
  9912. #endif // #if defined(OTL_IODBC_BSD)
  9913. #else // #if defined(OTL_DB2_CLI)
  9914. #if (ODBCVER >= 0x0300)
  9915. #define OTL_HENV SQLHANDLE
  9916. #define OTL_HDBC SQLHANDLE
  9917. #define OTL_SQLHANDLE SQLHANDLE
  9918. #define OTL_SQLRETURN SQLRETURN
  9919. #define OTL_SQLSMALLINT SQLSMALLINT
  9920. #define OTL_SQLCHAR_PTR SQLCHAR *
  9921. #define OTL_SQLINTEGER_PTR SQLINTEGER *
  9922. #define OTL_SQLSMALLINT_PTR SQLSMALLINT *
  9923. #define OTL_SQLINTEGER SQLINTEGER
  9924. #define OTL_SQLHSTMT SQLHSTMT
  9925. #define OTL_SQLUSMALLINT SQLUSMALLINT
  9926. #define OTL_SQLPOINTER SQLPOINTER
  9927. #define OTL_SQLCHAR SQLCHAR
  9928. #define OTL_SQLUINTEGER SQLUINTEGER
  9929. #if defined(OTL_IODBC_BSD)
  9930. #define OTL_SQLLEN SQLLEN
  9931. #define OTL_SQLLEN_PTR SQLLEN *
  9932. #define OTL_SQLULEN SQLULEN
  9933. #define OTL_SQLULEN_PTR SQLULEN *
  9934. #else // #if defined(OTL_IODBC_BSD)
  9935. #if defined(__MVS__) // C++ in MVS
  9936. #define OTL_SQLLEN SQLINTEGER
  9937. #define OTL_SQLLEN_PTR SQLINTEGER *
  9938. #define OTL_SQLULEN SQLUINTEGER
  9939. #define OTL_SQLULEN_PTR SQLUINTEGER *
  9940. #else
  9941. #if !defined(OTL_SQLLEN)
  9942. #define OTL_SQLLEN SQLLEN
  9943. #define OTL_SQLLEN_PTR SQLLEN *
  9944. #define OTL_SQLULEN SQLULEN
  9945. #define OTL_SQLULEN_PTR SQLULEN *
  9946. #endif
  9947. #endif
  9948. #endif // #if defined(OTL_IODBC_BSD)
  9949. #else // #if (ODBCVER >= 0x0300)
  9950. #define OTL_HENV HENV
  9951. #define OTL_HDBC HDBC
  9952. #define OTL_SQLHANDLE HSTMT
  9953. #define OTL_SQLRETURN SQLRETURN
  9954. #define OTL_SQLSMALLINT SQLSMALLINT
  9955. #define OTL_SQLCHAR_PTR SQLCHAR *
  9956. #define OTL_SQLINTEGER_PTR SQLINTEGER *
  9957. #define OTL_SQLSMALLINT_PTR SQLSMALLINT *
  9958. #define OTL_SQLINTEGER SQLINTEGER
  9959. #define OTL_SQLHSTMT SQLHSTMT
  9960. #define OTL_SQLUSMALLINT SQLUSMALLINT
  9961. #define OTL_SQLPOINTER SQLPOINTER
  9962. #define OTL_SQLCHAR SQLCHAR
  9963. #define OTL_SQLUINTEGER SQLUINTEGER
  9964. #if defined(OTL_IODBC_BSD)
  9965. #define OTL_SQLLEN SQLLEN
  9966. #define OTL_SQLLEN_PTR SQLLEN *
  9967. #define OTL_SQLULEN SQLULEN
  9968. #define OTL_SQLULEN_PTR SQLULEN *
  9969. #else // #if defined(OTL_IODBC_BSD)
  9970. #define OTL_SQLLEN SQLLEN
  9971. #define OTL_SQLLEN_PTR SQLLEN *
  9972. #define OTL_SQLULEN SQLULEN
  9973. #define OTL_SQLULEN_PTR SQLULEN *
  9974. #endif // #if defined(OTL_IODBC_BSD)
  9975. #endif
  9976. #endif
  9977. #endif
  9978. OTL_ODBC_NAMESPACE_BEGIN
  9979. #if (defined(UNICODE) || defined(_UNICODE)) && defined(OTL_ODBC)
  9980. inline void otl_convert_char_to_SQLWCHAR
  9981. (SQLWCHAR *dst,
  9982. const unsigned char *src)
  9983. {
  9984. while (*src)
  9985. *dst++ = OTL_SCAST(SQLWCHAR, *src++);
  9986. *dst = 0;
  9987. }
  9988. inline void otl_convert_SQLWCHAR_to_char
  9989. (unsigned char *dst,
  9990. const SQLWCHAR *src)
  9991. {
  9992. while (*src)
  9993. *dst++ = OTL_SCAST(unsigned char, *src++);
  9994. *dst = 0;
  9995. }
  9996. #if defined(OTL_ODBC_CHAR_SQLWCHAR_CONVERSION_FUNCS)
  9997. OTL_ODBC_CHAR_SQLWCHAR_CONVERSION_FUNCS
  9998. #else
  9999. inline void otl_convert_char_to_SQLWCHAR_2
  10000. (SQLWCHAR *dst,
  10001. const unsigned char *src)
  10002. {
  10003. while (*src)
  10004. *dst++ = OTL_SCAST(SQLWCHAR, *src++);
  10005. *dst = 0;
  10006. }
  10007. inline void otl_convert_SQLWCHAR_to_char_2
  10008. (unsigned char *dst,
  10009. const SQLWCHAR *src)
  10010. {
  10011. while (*src)
  10012. *dst++ = OTL_SCAST(unsigned char, *src++);
  10013. *dst = 0;
  10014. }
  10015. #endif
  10016. OTL_NODISCARD inline size_t otl_strlen(const SQLWCHAR *s) {
  10017. size_t len = 0;
  10018. while (*s) {
  10019. ++s;
  10020. ++len;
  10021. }
  10022. return len;
  10023. }
  10024. #endif
  10025. typedef OTL_SQL_TIMESTAMP_STRUCT otl_time;
  10026. const int otl_odbc_date_prec = 23;
  10027. #if defined(OTL_ODBC_MSSQL_2008)
  10028. const int otl_odbc_date_scale = 7;
  10029. #elif defined(OTL_ODBC_MSSQL_2005)
  10030. const int otl_odbc_date_scale = 3;
  10031. #else
  10032. const int otl_odbc_date_scale = 0;
  10033. #endif
  10034. const int OTL_MAX_MSG_ARR = 512;
  10035. class otl_exc {
  10036. public:
  10037. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10038. SQLWCHAR msg[1000];
  10039. SQLWCHAR sqlstate[1000];
  10040. #if defined(OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION)
  10041. protected:
  10042. mutable unsigned char char_msg[1000];
  10043. public:
  10044. #endif
  10045. #else
  10046. unsigned char msg[1000];
  10047. unsigned char sqlstate[1000];
  10048. #endif
  10049. int code;
  10050. #if defined(OTL_EXTENDED_EXCEPTION)
  10051. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10052. SQLWCHAR **msg_arr;
  10053. SQLWCHAR **sqlstate_arr;
  10054. #else
  10055. char **msg_arr;
  10056. char **sqlstate_arr;
  10057. #endif
  10058. int *code_arr;
  10059. int arr_len;
  10060. #endif
  10061. enum {
  10062. disabled = 0,
  10063. enabled = 1
  10064. };
  10065. otl_exc()
  10066. : msg(), sqlstate(), code(0)
  10067. #if defined(OTL_EXTENDED_EXCEPTION)
  10068. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10069. ,
  10070. msg_arr(nullptr), sqlstate_arr(nullptr),
  10071. #else
  10072. ,
  10073. msg_arr(nullptr), sqlstate_arr(nullptr),
  10074. #endif
  10075. code_arr(nullptr), arr_len(0)
  10076. #endif
  10077. {
  10078. sqlstate[0] = 0;
  10079. msg[0] = 0;
  10080. }
  10081. #if defined(OTL_EXTENDED_EXCEPTION)
  10082. otl_exc(const otl_exc &ex)
  10083. :
  10084. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10085. msg(),
  10086. sqlstate(),
  10087. #else
  10088. msg(),
  10089. sqlstate(),
  10090. #endif
  10091. code(0),
  10092. #if defined(OTL_EXTENDED_EXCEPTION)
  10093. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10094. msg_arr(nullptr), sqlstate_arr(nullptr),
  10095. #else
  10096. msg_arr(nullptr), sqlstate_arr(nullptr),
  10097. #endif
  10098. code_arr(nullptr), arr_len(0)
  10099. #endif
  10100. {
  10101. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10102. otl_strcpy(OTL_RCAST(unsigned char *, msg),
  10103. OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.msg)));
  10104. otl_strcpy(
  10105. OTL_RCAST(unsigned char *, OTL_CCAST(SQLWCHAR *, sqlstate)),
  10106. OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.sqlstate)));
  10107. code = ex.code;
  10108. arr_len = 0;
  10109. msg_arr = nullptr;
  10110. sqlstate_arr = nullptr;
  10111. code_arr = nullptr;
  10112. if (ex.arr_len > 0) {
  10113. sqlstate_arr = new SQLWCHAR *[ex.arr_len];
  10114. msg_arr = new SQLWCHAR *[ex.arr_len];
  10115. code_arr = new int[ex.arr_len];
  10116. int i;
  10117. size_t msg_len, sqlstate_len;
  10118. for (i = 0; i < ex.arr_len; ++i) {
  10119. msg_len = otl_strlen(ex.msg_arr[i]);
  10120. sqlstate_len = otl_strlen(ex.sqlstate_arr[i]);
  10121. msg_arr[i] = new SQLWCHAR[msg_len + 1];
  10122. sqlstate_arr[i] = new SQLWCHAR[sqlstate_len + 1];
  10123. otl_strcpy(OTL_RCAST(unsigned char *, msg_arr[i]),
  10124. OTL_RCAST(const unsigned char *,
  10125. OTL_CCAST(SQLWCHAR *, ex.msg_arr[i])));
  10126. otl_strcpy(OTL_RCAST(unsigned char *, sqlstate_arr[i]),
  10127. OTL_RCAST(const unsigned char *,
  10128. OTL_CCAST(SQLWCHAR *, ex.sqlstate_arr[i])));
  10129. code_arr[i] = ex.code_arr[i];
  10130. }
  10131. arr_len = ex.arr_len;
  10132. }
  10133. #else
  10134. OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg),
  10135. OTL_RCAST(const char *, ex.msg));
  10136. OTL_STRCPY_S(OTL_RCAST(char *, sqlstate), sizeof(sqlstate),
  10137. OTL_RCAST(const char *, ex.sqlstate));
  10138. code = ex.code;
  10139. arr_len = 0;
  10140. msg_arr = nullptr;
  10141. sqlstate_arr = nullptr;
  10142. code_arr = nullptr;
  10143. if (ex.arr_len > 0) {
  10144. sqlstate_arr = new char *[OTL_SCAST(size_t,ex.arr_len)];
  10145. msg_arr = new char *[OTL_SCAST(size_t,ex.arr_len)];
  10146. code_arr = new int[OTL_SCAST(size_t,ex.arr_len)];
  10147. int i;
  10148. size_t msg_len, sqlstate_len;
  10149. for (i = 0; i < ex.arr_len; ++i) {
  10150. msg_len = strlen(ex.msg_arr[i]);
  10151. sqlstate_len = strlen(ex.sqlstate_arr[i]);
  10152. msg_arr[i] = new char[msg_len + 1];
  10153. sqlstate_arr[i] = new char[sqlstate_len + 1];
  10154. OTL_STRCPY_S(msg_arr[i], msg_len + 1, ex.msg_arr[i]);
  10155. OTL_STRCPY_S(sqlstate_arr[i], sqlstate_len + 1, ex.sqlstate_arr[i]);
  10156. code_arr[i] = ex.code_arr[i];
  10157. }
  10158. arr_len = ex.arr_len;
  10159. }
  10160. #endif
  10161. }
  10162. #endif
  10163. void init(const char *amsg, const int acode) {
  10164. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10165. otl_convert_char_to_SQLWCHAR(
  10166. msg, OTL_RCAST(unsigned char *, OTL_CCAST(char *, amsg)));
  10167. #else
  10168. OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg), amsg);
  10169. #endif
  10170. code = acode;
  10171. sqlstate[0] = 0;
  10172. #if defined(OTL_EXTENDED_EXCEPTION)
  10173. msg_arr = nullptr;
  10174. sqlstate_arr = nullptr;
  10175. code_arr = nullptr;
  10176. arr_len = 0;
  10177. #endif
  10178. }
  10179. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) && \
  10180. !defined(OTL_EXTENDED_EXCEPTION)
  10181. otl_exc(const otl_exc &) = default;
  10182. #endif
  10183. virtual ~otl_exc() {
  10184. #if defined(OTL_EXTENDED_EXCEPTION)
  10185. int i;
  10186. if (arr_len > 0) {
  10187. for (i = 0; i < arr_len; ++i) {
  10188. delete[] msg_arr[i];
  10189. delete[] sqlstate_arr[i];
  10190. }
  10191. delete[] msg_arr;
  10192. delete[] sqlstate_arr;
  10193. delete[] code_arr;
  10194. arr_len = 0;
  10195. msg_arr = nullptr;
  10196. sqlstate_arr = nullptr;
  10197. code_arr = nullptr;
  10198. }
  10199. #endif
  10200. }
  10201. private:
  10202. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  10203. public:
  10204. otl_exc &operator=(const otl_exc &) = delete;
  10205. private:
  10206. #else
  10207. otl_exc &operator=(const otl_exc &) { return *this; }
  10208. #if defined(_MSC_VER) && (_MSC_VER >= 1600)
  10209. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  10210. otl_exc(otl_exc &&)
  10211. : msg(), sqlstate(), code(0)
  10212. #if defined(OTL_EXTENDED_EXCEPTION)
  10213. ,
  10214. msg_arr(nullptr), sqlstate_arr(nullptr), code_arr(nullptr), arr_len(0)
  10215. #endif
  10216. {
  10217. }
  10218. otl_exc &operator=(otl_exc &&) { return *this; }
  10219. #endif
  10220. #endif
  10221. #endif
  10222. };
  10223. #if (ODBCVER >= 0x0300)
  10224. #if defined(OTL_EXTENDED_EXCEPTION)
  10225. inline void otl_fill_exception(otl_exc &exception_struct, OTL_SQLHANDLE handle,
  10226. OTL_SQLSMALLINT htype) {
  10227. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10228. OTL_SQLRETURN rc;
  10229. OTL_SQLSMALLINT msg_len = 0;
  10230. SQLWCHAR *tmp_msg_arr[OTL_MAX_MSG_ARR];
  10231. SQLWCHAR *tmp_sqlstate_arr[OTL_MAX_MSG_ARR];
  10232. int tmp_code_arr[OTL_MAX_MSG_ARR];
  10233. int tmp_arr_len = 0;
  10234. OTL_SQLSMALLINT tmp_msg_len = 0;
  10235. OTL_SQLSMALLINT tmp_sqlstate_len = 0;
  10236. int tmp_code;
  10237. SQLWCHAR tmp_msg[SQL_MAX_MESSAGE_LENGTH];
  10238. SQLWCHAR tmp_sqlstate[1000];
  10239. otl_strcpy(OTL_RCAST(unsigned char *, tmp_msg),
  10240. OTL_RCAST(const unsigned char *,
  10241. OTL_CCAST(SQLWCHAR *, exception_struct.msg)));
  10242. otl_strcpy(OTL_RCAST(unsigned char *, tmp_sqlstate),
  10243. OTL_RCAST(const unsigned char *,
  10244. OTL_CCAST(SQLWCHAR *, exception_struct.sqlstate)));
  10245. tmp_code = exception_struct.code;
  10246. do {
  10247. tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_sqlstate));
  10248. tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_msg));
  10249. ++tmp_arr_len;
  10250. tmp_msg_arr[tmp_arr_len - 1] = new SQLWCHAR[tmp_msg_len + 1];
  10251. tmp_sqlstate_arr[tmp_arr_len - 1] = new SQLWCHAR[tmp_sqlstate_len + 1];
  10252. otl_strcpy(
  10253. OTL_RCAST(unsigned char *, tmp_msg_arr[tmp_arr_len - 1]),
  10254. OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, tmp_msg)));
  10255. otl_strcpy(
  10256. OTL_RCAST(unsigned char *, tmp_sqlstate_arr[tmp_arr_len - 1]),
  10257. OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, tmp_sqlstate)));
  10258. tmp_code_arr[tmp_arr_len - 1] = tmp_code;
  10259. rc = SQLGetDiagRec(
  10260. htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1),
  10261. OTL_RCAST(SQLWCHAR *, tmp_sqlstate),
  10262. OTL_RCAST(OTL_SQLINTEGER_PTR, &tmp_code),
  10263. OTL_RCAST(SQLWCHAR *, tmp_msg), SQL_MAX_MESSAGE_LENGTH - 1,
  10264. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  10265. tmp_msg[msg_len] = 0;
  10266. if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) &&
  10267. tmp_arr_len == 1) {
  10268. int i;
  10269. for (i = 0; i < tmp_arr_len; ++i) {
  10270. delete[] tmp_msg_arr[i];
  10271. delete[] tmp_sqlstate_arr[i];
  10272. }
  10273. return;
  10274. }
  10275. } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR &&
  10276. tmp_arr_len < OTL_MAX_MSG_ARR);
  10277. exception_struct.arr_len = tmp_arr_len;
  10278. exception_struct.msg_arr = new SQLWCHAR *[tmp_arr_len];
  10279. exception_struct.sqlstate_arr = new SQLWCHAR *[tmp_arr_len];
  10280. exception_struct.code_arr = new int[tmp_arr_len];
  10281. memcpy(exception_struct.msg_arr, tmp_msg_arr,
  10282. tmp_arr_len * sizeof(SQLWCHAR *));
  10283. memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr,
  10284. tmp_arr_len * sizeof(SQLWCHAR *));
  10285. memcpy(exception_struct.code_arr, tmp_code_arr, tmp_arr_len * sizeof(int));
  10286. #elif defined(UNICODE) || defined(_UNICODE)
  10287. OTL_SQLRETURN rc;
  10288. OTL_SQLSMALLINT msg_len = 0;
  10289. char *tmp_msg_arr[OTL_MAX_MSG_ARR];
  10290. char *tmp_sqlstate_arr[OTL_MAX_MSG_ARR];
  10291. int tmp_code_arr[OTL_MAX_MSG_ARR];
  10292. int tmp_arr_len = 0;
  10293. OTL_SQLSMALLINT tmp_msg_len = 0;
  10294. OTL_SQLSMALLINT tmp_sqlstate_len = 0;
  10295. int tmp_code;
  10296. SQLWCHAR tmp_msg[SQL_MAX_MESSAGE_LENGTH];
  10297. SQLWCHAR tmp_sqlstate[1000];
  10298. otl_convert_char_to_SQLWCHAR(
  10299. tmp_msg, OTL_RCAST(const unsigned char *, exception_struct.msg));
  10300. otl_convert_char_to_SQLWCHAR(
  10301. tmp_sqlstate,
  10302. OTL_RCAST(const unsigned char *, exception_struct.sqlstate));
  10303. tmp_code = exception_struct.code;
  10304. do {
  10305. tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_sqlstate));
  10306. tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_msg));
  10307. ++tmp_arr_len;
  10308. tmp_msg_arr[tmp_arr_len - 1] = new char[tmp_msg_len + 1];
  10309. tmp_sqlstate_arr[tmp_arr_len - 1] = new char[tmp_sqlstate_len + 1];
  10310. otl_convert_SQLWCHAR_to_char(
  10311. OTL_RCAST(unsigned char *, tmp_msg_arr[tmp_arr_len - 1]), tmp_msg);
  10312. otl_convert_SQLWCHAR_to_char(
  10313. OTL_RCAST(unsigned char *, tmp_sqlstate_arr[tmp_arr_len - 1]),
  10314. tmp_sqlstate);
  10315. tmp_code_arr[tmp_arr_len - 1] = tmp_code;
  10316. rc = SQLGetDiagRec(
  10317. htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1),
  10318. tmp_sqlstate, OTL_RCAST(OTL_SQLINTEGER_PTR, &tmp_code), tmp_msg,
  10319. SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  10320. tmp_msg[msg_len] = 0;
  10321. if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) &&
  10322. tmp_arr_len == 1) {
  10323. int i;
  10324. for (i = 0; i < tmp_arr_len; ++i) {
  10325. delete[] tmp_msg_arr[i];
  10326. delete[] tmp_sqlstate_arr[i];
  10327. }
  10328. return;
  10329. }
  10330. } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR &&
  10331. tmp_arr_len < OTL_MAX_MSG_ARR);
  10332. exception_struct.arr_len = tmp_arr_len;
  10333. exception_struct.msg_arr = new char *[tmp_arr_len];
  10334. exception_struct.sqlstate_arr = new char *[tmp_arr_len];
  10335. exception_struct.code_arr = new int[tmp_arr_len];
  10336. memcpy(exception_struct.msg_arr, tmp_msg_arr, tmp_arr_len * sizeof(char *));
  10337. memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr,
  10338. tmp_arr_len * sizeof(char *));
  10339. memcpy(exception_struct.code_arr, tmp_code_arr, tmp_arr_len * sizeof(int));
  10340. #else
  10341. OTL_SQLRETURN rc;
  10342. OTL_SQLSMALLINT msg_len = 0;
  10343. char *tmp_msg_arr[OTL_MAX_MSG_ARR];
  10344. char *tmp_sqlstate_arr[OTL_MAX_MSG_ARR];
  10345. int tmp_code_arr[OTL_MAX_MSG_ARR];
  10346. int tmp_arr_len = 0;
  10347. OTL_SQLSMALLINT tmp_msg_len = 0;
  10348. OTL_SQLSMALLINT tmp_sqlstate_len = 0;
  10349. int tmp_code;
  10350. char tmp_msg[SQL_MAX_MESSAGE_LENGTH];
  10351. char tmp_sqlstate[1000];
  10352. OTL_STRCPY_S(tmp_msg, sizeof(tmp_msg),
  10353. OTL_RCAST(char *, exception_struct.msg));
  10354. OTL_STRCPY_S(tmp_sqlstate, sizeof(tmp_sqlstate),
  10355. OTL_RCAST(char *, exception_struct.sqlstate));
  10356. tmp_code = exception_struct.code;
  10357. do {
  10358. tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, strlen(tmp_sqlstate));
  10359. tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, strlen(tmp_msg));
  10360. ++tmp_arr_len;
  10361. tmp_msg_arr[tmp_arr_len - 1] = new char[OTL_SCAST(size_t,tmp_msg_len + 1)];
  10362. tmp_sqlstate_arr[tmp_arr_len - 1] = new char[OTL_SCAST(size_t,tmp_sqlstate_len + 1)];
  10363. OTL_STRCPY_S(tmp_msg_arr[tmp_arr_len - 1], tmp_msg_len + 1, tmp_msg);
  10364. OTL_STRCPY_S(tmp_sqlstate_arr[tmp_arr_len - 1], tmp_sqlstate_len + 1,
  10365. tmp_sqlstate);
  10366. tmp_code_arr[tmp_arr_len - 1] = tmp_code;
  10367. void *temp_ptr = &tmp_code;
  10368. rc = SQLGetDiagRec(
  10369. htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1),
  10370. OTL_RCAST(OTL_SQLCHAR_PTR, tmp_sqlstate),
  10371. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  10372. OTL_RCAST(OTL_SQLCHAR_PTR, tmp_msg), SQL_MAX_MESSAGE_LENGTH - 1,
  10373. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  10374. tmp_msg[msg_len] = 0;
  10375. if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) &&
  10376. tmp_arr_len == 1) {
  10377. int i;
  10378. for (i = 0; i < tmp_arr_len; ++i) {
  10379. delete[] tmp_msg_arr[i];
  10380. delete[] tmp_sqlstate_arr[i];
  10381. }
  10382. return;
  10383. }
  10384. } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR &&
  10385. tmp_arr_len < OTL_MAX_MSG_ARR);
  10386. exception_struct.arr_len = tmp_arr_len;
  10387. exception_struct.msg_arr = new char *[OTL_SCAST(size_t,tmp_arr_len)];
  10388. exception_struct.sqlstate_arr = new char *[OTL_SCAST(size_t,tmp_arr_len)];
  10389. exception_struct.code_arr = new int[OTL_SCAST(size_t,tmp_arr_len)];
  10390. memcpy(exception_struct.msg_arr, tmp_msg_arr,
  10391. OTL_SCAST(size_t, tmp_arr_len) * sizeof(char *));
  10392. memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr,
  10393. OTL_SCAST(size_t, tmp_arr_len) * sizeof(char *));
  10394. memcpy(exception_struct.code_arr, tmp_code_arr,
  10395. OTL_SCAST(size_t, tmp_arr_len) * sizeof(int));
  10396. #endif
  10397. }
  10398. #endif
  10399. #endif
  10400. const int OTL_DEFAULT_ODBC_CONNECT = 1;
  10401. const int OTL_TIMESTEN_ODBC_CONNECT = 2;
  10402. const int OTL_MSSQL_2005_ODBC_CONNECT = 3;
  10403. const int OTL_POSTGRESQL_ODBC_CONNECT = 4;
  10404. const int OTL_ENTERPRISE_DB_ODBC_CONNECT = 5;
  10405. const int OTL_MYODBC35_ODBC_CONNECT = 6;
  10406. const int OTL_MSSQL_2008_ODBC_CONNECT = 7;
  10407. class otl_cur;
  10408. class otl_connect;
  10409. class otl_sel;
  10410. #if defined(OTL_ENABLE_MSSQL_MARS)
  10411. #define OTL_SQL_COPT_SS_BASE 1200
  10412. #define OTL_SQL_COPT_SS_MARS_ENABLED (OTL_SQL_COPT_SS_BASE + 24)
  10413. #define OTL_SQL_MARS_ENABLED_YES 1L
  10414. #endif
  10415. class otl_conn {
  10416. protected:
  10417. friend class otl_connect;
  10418. friend class otl_cur;
  10419. friend class otl_sel;
  10420. OTL_HENV henv;
  10421. OTL_HDBC hdbc;
  10422. int timeout;
  10423. int cursor_type;
  10424. int status;
  10425. int long_max_size;
  10426. bool extern_lda;
  10427. #if defined(OTL_ODBC_zOS)
  10428. bool logoff_commit;
  10429. #endif
  10430. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  10431. bool throws_on_sql_success_with_info;
  10432. #endif
  10433. int connection_type;
  10434. public:
  10435. enum bigint_type {
  10436. #if defined(OTL_BIGINT) && !defined(OTL_STR_TO_BIGINT) && \
  10437. !defined(OTL_BIGINT_TO_STR)
  10438. var_bigint = otl_var_bigint,
  10439. bigint_size = sizeof(OTL_BIGINT)
  10440. #else
  10441. var_bigint = otl_var_char,
  10442. bigint_size = otl_bigint_str_size
  10443. #endif
  10444. };
  10445. enum ubigint_type {
  10446. #if defined(OTL_UBIGINT)
  10447. var_ubigint = otl_var_ubigint,
  10448. ubigint_size = sizeof(OTL_UBIGINT)
  10449. #else
  10450. var_ubigint = otl_var_char,
  10451. ubigint_size = otl_ubigint_str_size
  10452. #endif
  10453. };
  10454. void cleanup(void) {}
  10455. OTL_NODISCARD OTL_HENV &get_henv() { return henv; }
  10456. OTL_NODISCARD OTL_HDBC &get_hdbc() { return hdbc; }
  10457. OTL_NODISCARD int get_connection_type(void) { return connection_type; }
  10458. OTL_NODISCARD static int initialize(const int /* threaded_mode */ = 0) { return 1; }
  10459. otl_conn()
  10460. : henv(OTL_SQL_NULL_HANDLE_VAL), hdbc(OTL_SQL_NULL_HANDLE_VAL),
  10461. timeout(0), cursor_type(0), status(SQL_SUCCESS),
  10462. long_max_size(otl_short_int_max), extern_lda(false)
  10463. #if defined(OTL_ODBC_zOS)
  10464. ,
  10465. logoff_commit(true)
  10466. #endif
  10467. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  10468. ,
  10469. throws_on_sql_success_with_info(false)
  10470. #endif
  10471. ,
  10472. connection_type(OTL_DEFAULT_ODBC_CONNECT) {
  10473. }
  10474. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  10475. OTL_NODISCARD int rlogon(const SQLWCHAR *username, const SQLWCHAR *passwd,
  10476. const SQLWCHAR *tnsname, const int auto_commit) {
  10477. if (extern_lda) {
  10478. extern_lda = false;
  10479. henv = nullptr;
  10480. hdbc = nullptr;
  10481. }
  10482. OTL_TRACE_RLOGON_ODBC_W(0x1, L"otl_connect", L"rlogon",
  10483. OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, tnsname),
  10484. OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, username),
  10485. OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, passwd),
  10486. auto_commit);
  10487. if (henv == nullptr || hdbc == nullptr) {
  10488. status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv);
  10489. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10490. return 0;
  10491. status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
  10492. OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS);
  10493. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10494. return 0;
  10495. status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  10496. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10497. return 0;
  10498. }
  10499. if (auto_commit) {
  10500. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10501. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON),
  10502. SQL_IS_POINTER);
  10503. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10504. return 0;
  10505. } else {
  10506. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500)
  10507. #pragma clang diagnostic push
  10508. #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  10509. #endif
  10510. SQLPOINTER temp = SQL_AUTOCOMMIT_OFF;
  10511. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500)
  10512. #pragma clang diagnostic pop
  10513. #endif
  10514. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10515. OTL_RCAST(SQLPOINTER, temp), SQL_IS_POINTER);
  10516. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10517. return 0;
  10518. }
  10519. if (timeout > 0) {
  10520. status =
  10521. SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT,
  10522. OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0);
  10523. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10524. return 0;
  10525. }
  10526. #if defined(OTL_DB2_CLI)
  10527. status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT,
  10528. OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES),
  10529. SQL_IS_INTEGER);
  10530. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10531. return 0;
  10532. #endif
  10533. #if defined(OTL_ENABLE_MSSQL_MARS)
  10534. #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300)
  10535. status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED,
  10536. OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES),
  10537. SQL_IS_UINTEGER);
  10538. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10539. return 0;
  10540. #endif
  10541. #endif
  10542. status = SQLConnect(hdbc, OTL_CCAST(SQLWCHAR *, tnsname), SQL_NTS,
  10543. OTL_CCAST(SQLWCHAR *, username), SQL_NTS,
  10544. OTL_CCAST(SQLWCHAR *, passwd), SQL_NTS);
  10545. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10546. return 0;
  10547. else
  10548. return 1;
  10549. }
  10550. #endif
  10551. #if !defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) && \
  10552. ((defined(ODBCVER) && ODBCVER >= 0x0300) || defined(OTL_DB2_CLI))
  10553. #if defined(OTL_DB2_CLI)
  10554. #define OTL_RLOGON_SQLHANDLE_NULLPTR OTL_SCAST(SQLHANDLE,0)
  10555. #else
  10556. #define OTL_RLOGON_SQLHANDLE_NULLPTR nullptr
  10557. #endif
  10558. inline void otl_special_convert_char_to_SQLWCHAR
  10559. (SQLWCHAR *dst, const char *src){
  10560. while (*src)
  10561. *dst++ = OTL_SCAST(SQLWCHAR, *src++);
  10562. *dst = 0;
  10563. }
  10564. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500)
  10565. #pragma clang diagnostic push
  10566. #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  10567. #endif
  10568. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  10569. #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
  10570. #endif
  10571. OTL_NODISCARD int rlogon(const char*username, const char *passwd,
  10572. const char *dnsname, const int auto_commit){
  10573. if(extern_lda){
  10574. extern_lda=false;
  10575. henv=OTL_RLOGON_SQLHANDLE_NULLPTR;
  10576. hdbc=OTL_RLOGON_SQLHANDLE_NULLPTR;
  10577. }
  10578. OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", dnsname, username,
  10579. passwd, auto_commit)
  10580. if (henv == OTL_RLOGON_SQLHANDLE_NULLPTR || hdbc == OTL_RLOGON_SQLHANDLE_NULLPTR) {
  10581. status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv);
  10582. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10583. return 0;
  10584. status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
  10585. OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS);
  10586. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10587. return 0;
  10588. status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  10589. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10590. return 0;
  10591. }
  10592. if (auto_commit) {
  10593. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10594. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON),
  10595. SQL_IS_POINTER);
  10596. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10597. return 0;
  10598. } else {
  10599. SQLPOINTER temp = SQL_AUTOCOMMIT_OFF;
  10600. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10601. OTL_RCAST(SQLPOINTER, temp), SQL_IS_POINTER);
  10602. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10603. return 0;
  10604. }
  10605. if (timeout > 0) {
  10606. status =
  10607. SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT,
  10608. OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0);
  10609. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10610. return 0;
  10611. }
  10612. #if defined(OTL_DB2_CLI)
  10613. status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT,
  10614. OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES),
  10615. SQL_IS_INTEGER);
  10616. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10617. return 0;
  10618. #endif
  10619. #if defined(OTL_ENABLE_MSSQL_MARS)
  10620. #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300)
  10621. status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED,
  10622. OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES),
  10623. SQL_IS_UINTEGER);
  10624. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10625. return 0;
  10626. #endif
  10627. #endif
  10628. #if defined(_UNICODE) || defined(UNICODE)
  10629. {
  10630. SQLWCHAR *temp_dnsname = new SQLWCHAR[strlen(dnsname) + 1];
  10631. SQLWCHAR *temp_username = new SQLWCHAR[strlen(username) + 1];
  10632. SQLWCHAR *temp_passwd = new SQLWCHAR[strlen(passwd) + 1];
  10633. otl_special_convert_char_to_SQLWCHAR(temp_dnsname,dnsname);
  10634. otl_special_convert_char_to_SQLWCHAR(temp_username,username);
  10635. otl_special_convert_char_to_SQLWCHAR(temp_passwd,passwd);
  10636. status = SQLConnect(hdbc, temp_dnsname, SQL_NTS, temp_username, SQL_NTS,
  10637. temp_passwd, SQL_NTS);
  10638. delete[] temp_dnsname;
  10639. delete[] temp_username;
  10640. delete[] temp_passwd;
  10641. }
  10642. #else
  10643. status = SQLConnect(hdbc, OTL_RCAST(unsigned char*, OTL_CCAST(char*, dnsname)), SQL_NTS,
  10644. OTL_RCAST(unsigned char*, OTL_CCAST(char*, username)), SQL_NTS,
  10645. OTL_RCAST(unsigned char*, OTL_CCAST(char*, passwd)), SQL_NTS);
  10646. #endif
  10647. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10648. return 0;
  10649. else
  10650. return 1;
  10651. }
  10652. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500)
  10653. #pragma clang diagnostic pop
  10654. #endif
  10655. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  10656. #pragma GCC diagnostic pop
  10657. #endif
  10658. #else
  10659. OTL_NODISCARD int rlogon(const char* /*username*/, const char* /*passwd*/,
  10660. const char* /*dnsname*/, const int /*auto_commit*/){
  10661. return 0;
  10662. }
  10663. #endif
  10664. #if defined(OTL_DB2_CLI)
  10665. OTL_NODISCARD int set_prog_name(const char *prog_name) {
  10666. if (henv == OTL_SQL_NULL_HANDLE_VAL || hdbc == OTL_SQL_NULL_HANDLE_VAL) {
  10667. status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE, &henv);
  10668. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10669. return 0;
  10670. status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
  10671. OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS);
  10672. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10673. return 0;
  10674. status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  10675. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10676. return 0;
  10677. }
  10678. #if !defined(SQL_ATTR_INFO_PROGRAMNAME)
  10679. #define SQL_ATTR_INFO_PROGRAMNAME 2516
  10680. #endif
  10681. status = SQLSetConnectAttr(
  10682. hdbc, SQL_ATTR_INFO_PROGRAMNAME,
  10683. OTL_RCAST(SQLPOINTER, OTL_CCAST(char *, prog_name)), SQL_NTS);
  10684. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10685. return 0;
  10686. else
  10687. return 1;
  10688. }
  10689. #endif
  10690. OTL_NODISCARD int ext_logon(OTL_HENV ahenv, OTL_HDBC ahdbc, const int
  10691. #ifndef OTL_ODBC_MYSQL
  10692. auto_commit
  10693. #endif
  10694. ) {
  10695. if (!extern_lda) {
  10696. #if (ODBCVER >= 0x0300)
  10697. if (hdbc != OTL_SQL_NULL_HANDLE_VAL) {
  10698. status = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  10699. }
  10700. #else
  10701. if (hdbc != nullptr)
  10702. status = SQLFreeConnect(hdbc);
  10703. #endif
  10704. hdbc = OTL_SQL_NULL_HANDLE_VAL;
  10705. #if (ODBCVER >= 0x0300)
  10706. if (henv != OTL_SQL_NULL_HANDLE_VAL) {
  10707. status = SQLFreeHandle(SQL_HANDLE_ENV, henv);
  10708. }
  10709. #else
  10710. if (henv != nullptr)
  10711. status = SQLFreeEnv(henv);
  10712. #endif
  10713. henv = OTL_SQL_NULL_HANDLE_VAL;
  10714. }
  10715. extern_lda = true;
  10716. henv = ahenv;
  10717. hdbc = ahdbc;
  10718. #ifndef OTL_ODBC_MYSQL
  10719. #if (ODBCVER >= 0x0300)
  10720. if (auto_commit)
  10721. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10722. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON),
  10723. SQL_IS_POINTER);
  10724. else
  10725. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10726. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  10727. nullptr,
  10728. #else
  10729. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF),
  10730. #endif
  10731. SQL_IS_POINTER);
  10732. #else
  10733. if (auto_commit)
  10734. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1);
  10735. else
  10736. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0);
  10737. #endif
  10738. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10739. return 0;
  10740. #endif
  10741. #if defined(OTL_DB2_CLI)
  10742. status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT,
  10743. OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES),
  10744. SQL_IS_INTEGER);
  10745. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10746. return 0;
  10747. #endif
  10748. return 1;
  10749. }
  10750. virtual ~otl_conn() {
  10751. if (extern_lda) {
  10752. hdbc = OTL_SQL_NULL_HANDLE_VAL;
  10753. henv = OTL_SQL_NULL_HANDLE_VAL;
  10754. extern_lda = false;
  10755. } else {
  10756. #if (ODBCVER >= 0x0300)
  10757. if (hdbc != OTL_SQL_NULL_HANDLE_VAL) {
  10758. status = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  10759. }
  10760. #else
  10761. if (hdbc != nullptr)
  10762. status = SQLFreeConnect(hdbc);
  10763. #endif
  10764. hdbc = OTL_SQL_NULL_HANDLE_VAL;
  10765. #if (ODBCVER >= 0x0300)
  10766. if (henv != OTL_SQL_NULL_HANDLE_VAL) {
  10767. status = SQLFreeHandle(SQL_HANDLE_ENV, henv);
  10768. }
  10769. #else
  10770. if (henv != nullptr)
  10771. status = SQLFreeEnv(henv);
  10772. #endif
  10773. henv = OTL_SQL_NULL_HANDLE_VAL;
  10774. }
  10775. }
  10776. void set_timeout(const int atimeout = 0) { timeout = atimeout; }
  10777. void set_cursor_type(const int acursor_type = 0) {
  10778. cursor_type = acursor_type;
  10779. }
  10780. OTL_NODISCARD int rlogon(const char *connect_str, const int
  10781. #ifndef OTL_ODBC_MYSQL
  10782. auto_commit
  10783. #endif
  10784. ) {
  10785. char username[256];
  10786. char passwd[256];
  10787. char tnsname[1024];
  10788. char *tnsname_ptr = nullptr;
  10789. char *c = OTL_CCAST(char *, connect_str);
  10790. char *username_ptr = username;
  10791. char *passwd_ptr = passwd;
  10792. char temp_connect_str[512];
  10793. if (extern_lda) {
  10794. extern_lda = false;
  10795. henv = OTL_SQL_NULL_HANDLE_VAL;
  10796. hdbc = OTL_SQL_NULL_HANDLE_VAL;
  10797. }
  10798. memset(username, 0, sizeof(username));
  10799. memset(passwd, 0, sizeof(passwd));
  10800. memset(tnsname, 0, sizeof(tnsname));
  10801. char *c1 = OTL_CCAST(char *, connect_str);
  10802. int oracle_format = 0;
  10803. char prev_c = ' ';
  10804. while (*c1) {
  10805. if (*c1 == '@' && prev_c != '\\') {
  10806. oracle_format = 1;
  10807. break;
  10808. }
  10809. prev_c = *c1;
  10810. ++c1;
  10811. }
  10812. if (oracle_format) {
  10813. while (*c && *c != '/' && (OTL_SCAST(unsigned, username_ptr - username) <
  10814. sizeof(username) - 1)) {
  10815. *username_ptr = *c;
  10816. ++c;
  10817. ++username_ptr;
  10818. }
  10819. *username_ptr = 0;
  10820. if (*c == '/')
  10821. ++c;
  10822. prev_c = ' ';
  10823. while (*c && !(*c == '@' && prev_c != '\\') &&
  10824. (OTL_SCAST(unsigned, passwd_ptr - passwd) < sizeof(passwd) - 1)) {
  10825. if (prev_c == '\\')
  10826. --passwd_ptr;
  10827. *passwd_ptr = *c;
  10828. prev_c = *c;
  10829. ++c;
  10830. ++passwd_ptr;
  10831. }
  10832. *passwd_ptr = 0;
  10833. if (*c == '@') {
  10834. ++c;
  10835. tnsname_ptr = tnsname;
  10836. while (*c && (OTL_SCAST(unsigned, tnsname_ptr - tnsname) <
  10837. sizeof(tnsname) - 1)) {
  10838. *tnsname_ptr = *c;
  10839. ++c;
  10840. ++tnsname_ptr;
  10841. }
  10842. *tnsname_ptr = 0;
  10843. }
  10844. } else {
  10845. c1 = OTL_CCAST(char *, connect_str);
  10846. char *c2 = temp_connect_str;
  10847. while (*c1 && (OTL_SCAST(unsigned, c2 - temp_connect_str) <
  10848. sizeof(temp_connect_str) - 1)) {
  10849. *c2 = otl_to_upper(*c1);
  10850. ++c1;
  10851. ++c2;
  10852. }
  10853. *c2 = 0;
  10854. c1 = temp_connect_str;
  10855. char entry_name[256];
  10856. char entry_value[256];
  10857. while (*c1 && (OTL_SCAST(unsigned, c1 - temp_connect_str) <
  10858. sizeof(temp_connect_str) - 1)) {
  10859. c2 = entry_name;
  10860. while (*c1 && *c1 != '=' &&
  10861. (OTL_SCAST(unsigned, c1 - temp_connect_str) <
  10862. sizeof(temp_connect_str) - 1)) {
  10863. *c2 = *c1;
  10864. ++c1;
  10865. ++c2;
  10866. }
  10867. *c2 = 0;
  10868. #if defined(_MSC_VER) && (_MSC_VER == 1600)
  10869. entry_name[c2 - entry_name] = 0;
  10870. #endif
  10871. if (*c1)
  10872. ++c1;
  10873. c2 = entry_value;
  10874. prev_c = ' ';
  10875. while (*c1 && *c1 != ';' && (OTL_SCAST(unsigned, c2 - entry_value) <
  10876. sizeof(entry_value) - 1)) {
  10877. if (prev_c == '\\')
  10878. --c2;
  10879. *c2 = *c1;
  10880. prev_c = *c1;
  10881. ++c1;
  10882. ++c2;
  10883. }
  10884. *c2 = 0;
  10885. #if defined(_MSC_VER) && (_MSC_VER == 1600)
  10886. entry_value[c2 - entry_value] = 0;
  10887. #endif
  10888. if (*c1)
  10889. ++c1;
  10890. if (strcmp(entry_name, "DSN") == 0)
  10891. OTL_STRCPY_S(tnsname, sizeof(tnsname), entry_value);
  10892. if (strcmp(entry_name, "UID") == 0)
  10893. OTL_STRCPY_S(username, sizeof(username), entry_value);
  10894. if (strcmp(entry_name, "PWD") == 0)
  10895. OTL_STRCPY_S(passwd, sizeof(passwd), entry_value);
  10896. }
  10897. }
  10898. #ifndef OTL_ODBC_MYSQL
  10899. OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", tnsname, username,
  10900. passwd, auto_commit)
  10901. #else
  10902. OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", tnsname, username,
  10903. passwd, 0)
  10904. #endif
  10905. if (henv == OTL_SQL_NULL_HANDLE_VAL || hdbc == OTL_SQL_NULL_HANDLE_VAL) {
  10906. #if (ODBCVER >= 0x0300)
  10907. status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv);
  10908. #else
  10909. status = SQLAllocEnv(&henv);
  10910. #endif
  10911. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10912. return 0;
  10913. #if (ODBCVER >= 0x0300)
  10914. status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
  10915. OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS);
  10916. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10917. return 0;
  10918. #endif
  10919. #if (ODBCVER >= 0x0300)
  10920. status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  10921. #else
  10922. status = SQLAllocConnect(henv, &hdbc);
  10923. #endif
  10924. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10925. return 0;
  10926. } else
  10927. status = SQL_SUCCESS;
  10928. #ifndef OTL_ODBC_MYSQL
  10929. #if (ODBCVER >= 0x0300)
  10930. if (auto_commit)
  10931. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10932. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON),
  10933. SQL_IS_POINTER);
  10934. else
  10935. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  10936. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  10937. nullptr,
  10938. #else
  10939. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF),
  10940. #endif
  10941. SQL_IS_POINTER);
  10942. #else
  10943. if (auto_commit)
  10944. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1);
  10945. else
  10946. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0);
  10947. #endif
  10948. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10949. return 0;
  10950. #endif
  10951. #if (ODBCVER >= 0x0300)
  10952. if (timeout > 0)
  10953. status =
  10954. SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT,
  10955. OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0);
  10956. #else
  10957. if (timeout > 0)
  10958. status = SQLSetConnectOption(hdbc,
  10959. SQL_LOGIN_TIMEOUT,
  10960. OTL_SCAST(size_t,timeout));
  10961. #endif
  10962. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10963. return 0;
  10964. #if defined(OTL_DB2_CLI)
  10965. status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT,
  10966. OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES),
  10967. SQL_IS_INTEGER);
  10968. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  10969. return 0;
  10970. #endif
  10971. #if defined(OTL_ENABLE_MSSQL_MARS)
  10972. #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300)
  10973. status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED,
  10974. OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES),
  10975. SQL_IS_UINTEGER);
  10976. if (status != SQL_SUCCESS_WITH_INFO && status != SQL_SUCCESS)
  10977. return 0;
  10978. #endif
  10979. #endif
  10980. if (oracle_format) {
  10981. #if defined(OTL_ODBC_zOS)
  10982. if (tnsname[0] == 0 && username[0] == 0 && passwd[0] == 0) {
  10983. status = SQLConnect(hdbc, 0L, SQL_NTS, 0L, SQL_NTS, 0L, SQL_NTS);
  10984. logoff_commit = false;
  10985. } else
  10986. status = SQLConnect(hdbc, OTL_RCAST(unsigned char *, tnsname), SQL_NTS,
  10987. OTL_RCAST(unsigned char *, username), SQL_NTS,
  10988. OTL_RCAST(unsigned char *, passwd), SQL_NTS);
  10989. #else
  10990. #if defined(UNICODE) || defined(_UNICODE)
  10991. {
  10992. SQLWCHAR *temp_tnsname = new SQLWCHAR[strlen(tnsname) + 1];
  10993. SQLWCHAR *temp_username = new SQLWCHAR[strlen(username) + 1];
  10994. SQLWCHAR *temp_passwd = new SQLWCHAR[strlen(passwd) + 1];
  10995. otl_convert_char_to_SQLWCHAR_2(temp_tnsname,
  10996. OTL_RCAST(unsigned char *, tnsname));
  10997. otl_convert_char_to_SQLWCHAR_2(temp_username,
  10998. OTL_RCAST(unsigned char *, username));
  10999. otl_convert_char_to_SQLWCHAR_2(temp_passwd,
  11000. OTL_RCAST(unsigned char *, passwd));
  11001. status = SQLConnect(hdbc, temp_tnsname, SQL_NTS, temp_username, SQL_NTS,
  11002. temp_passwd, SQL_NTS);
  11003. delete[] temp_tnsname;
  11004. delete[] temp_username;
  11005. delete[] temp_passwd;
  11006. }
  11007. #else
  11008. status = SQLConnect(hdbc, OTL_RCAST(unsigned char *, tnsname), SQL_NTS,
  11009. OTL_RCAST(unsigned char *, username), SQL_NTS,
  11010. OTL_RCAST(unsigned char *, passwd), SQL_NTS);
  11011. #endif
  11012. #endif
  11013. } else {
  11014. char *tc2 = temp_connect_str;
  11015. const char *tc1 = connect_str;
  11016. prev_c = ' ';
  11017. while (*tc1 && (OTL_SCAST(unsigned, tc2 - temp_connect_str) <
  11018. sizeof(temp_connect_str) - 1)) {
  11019. if (*tc1 == '@' && prev_c == '\\')
  11020. --tc2;
  11021. *tc2 = *tc1;
  11022. prev_c = *tc1;
  11023. ++tc1;
  11024. ++tc2;
  11025. }
  11026. *tc2 = 0;
  11027. #if defined(_MSC_VER) && (_MSC_VER == 1600)
  11028. temp_connect_str[tc2 - temp_connect_str] = 0;
  11029. #endif
  11030. SQLSMALLINT out_len = 0;
  11031. #if (defined(UNICODE) || defined(_UNICODE))
  11032. {
  11033. size_t len = strlen(temp_connect_str);
  11034. SQLWCHAR *temp_connect_str2 = new SQLWCHAR[len + 1];
  11035. SQLWCHAR out_str[2048];
  11036. otl_convert_char_to_SQLWCHAR_2(
  11037. temp_connect_str2, OTL_RCAST(unsigned char *, temp_connect_str));
  11038. status = SQLDriverConnect(
  11039. hdbc, nullptr, temp_connect_str2, OTL_SCAST(short, len), out_str,
  11040. OTL_SCAST(OTL_SQLSMALLINT, sizeof(out_str) / sizeof(SQLWCHAR)),
  11041. &out_len, SQL_DRIVER_NOPROMPT);
  11042. delete[] temp_connect_str2;
  11043. }
  11044. #else
  11045. SQLCHAR out_str[2048];
  11046. status = SQLDriverConnect(
  11047. hdbc, nullptr,
  11048. OTL_RCAST(SQLCHAR *, OTL_CCAST(char *, temp_connect_str)),
  11049. OTL_SCAST(short, strlen(temp_connect_str)), out_str,
  11050. OTL_SCAST(SQLSMALLINT, sizeof(out_str)), &out_len,
  11051. SQL_DRIVER_NOPROMPT);
  11052. #endif
  11053. }
  11054. if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS)
  11055. return 1;
  11056. else
  11057. return 0;
  11058. }
  11059. OTL_NODISCARD int set_transaction_isolation_level(const long int
  11060. #ifndef OTL_ODBC_MYSQL
  11061. level
  11062. #endif
  11063. ) {
  11064. #ifndef OTL_ODBC_MYSQL
  11065. #if (ODBCVER >= 0x0300)
  11066. status = SQLSetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION,
  11067. OTL_RCAST(SQLPOINTER, OTL_SCAST(size_t, level)),
  11068. SQL_IS_POINTER);
  11069. #else
  11070. status = SQLSetConnectOption(hdbc,
  11071. SQL_TXN_ISOLATION,
  11072. OTL_SCAST(size_t,level));
  11073. #endif
  11074. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11075. return 0;
  11076. else
  11077. return 1;
  11078. #else
  11079. return 1;
  11080. #endif
  11081. }
  11082. OTL_NODISCARD int auto_commit_on(void) {
  11083. #if defined(OTL_ODBC_MYSQL)
  11084. return 1;
  11085. #else
  11086. #if (ODBCVER >= 0x0300)
  11087. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  11088. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON),
  11089. SQL_IS_POINTER);
  11090. #else
  11091. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1);
  11092. #endif
  11093. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11094. return 0;
  11095. else
  11096. return 1;
  11097. #endif
  11098. }
  11099. OTL_NODISCARD int auto_commit_off(void) {
  11100. #if defined(OTL_ODBC_MYSQL)
  11101. return 1;
  11102. #else
  11103. #if (ODBCVER >= 0x0300)
  11104. status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  11105. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  11106. nullptr,
  11107. #else
  11108. OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF),
  11109. #endif
  11110. SQL_IS_POINTER);
  11111. #else
  11112. status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0);
  11113. #endif
  11114. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11115. return 0;
  11116. else
  11117. return 1;
  11118. #endif
  11119. }
  11120. OTL_NODISCARD int logoff(void) {
  11121. if (extern_lda) {
  11122. extern_lda = false;
  11123. henv = OTL_SQL_NULL_HANDLE_VAL;
  11124. hdbc = OTL_SQL_NULL_HANDLE_VAL;
  11125. return 1;
  11126. } else {
  11127. #if defined(OTL_ODBC_zOS)
  11128. if (logoff_commit)
  11129. (void)commit();
  11130. #else
  11131. (void)commit();
  11132. #endif
  11133. status = SQLDisconnect(hdbc);
  11134. #if defined(OTL_ODBC_LOGOFF_FREES_HANDLES)
  11135. #if (ODBCVER >= 0x0300)
  11136. if (hdbc != nullptr) {
  11137. SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  11138. hdbc = nullptr;
  11139. }
  11140. if (henv != nullptr) {
  11141. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  11142. henv = nullptr;
  11143. }
  11144. #else
  11145. if (hdbc != nullptr) {
  11146. SQLFreeConnect(hdbc);
  11147. hdbc = nullptr;
  11148. }
  11149. if (henv != nullptr) {
  11150. SQLFreeEnv(henv);
  11151. henv = nullptr;
  11152. }
  11153. #endif
  11154. #endif
  11155. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11156. return 0;
  11157. else
  11158. return 1;
  11159. }
  11160. }
  11161. void error(otl_exc &exception_struct) {
  11162. OTL_SQLRETURN rc;
  11163. OTL_SQLSMALLINT msg_len = 0;
  11164. #if (ODBCVER >= 0x0300)
  11165. #if (defined(UNICODE) || defined(_UNICODE))
  11166. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  11167. #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
  11168. void* temp_ptr = &exception_struct.code;
  11169. rc = SQLGetDiagRec
  11170. #if defined(OTL_ODBC_zOS)
  11171. (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC,
  11172. hdbc == nullptr ? henv : hdbc,
  11173. #else
  11174. (SQL_HANDLE_DBC, hdbc,
  11175. #endif
  11176. 1, &exception_struct.sqlstate[0],
  11177. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  11178. &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1,
  11179. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11180. #else
  11181. rc = SQLGetDiagRec
  11182. #if defined(OTL_ODBC_zOS)
  11183. (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC,
  11184. hdbc == nullptr ? henv : hdbc,
  11185. #else
  11186. (SQL_HANDLE_DBC, hdbc,
  11187. #endif
  11188. 1, &exception_struct.sqlstate[0],
  11189. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code),
  11190. &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1,
  11191. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11192. #endif
  11193. exception_struct.msg[msg_len] = 0;
  11194. #else
  11195. {
  11196. SQLWCHAR temp_msg[SQL_MAX_MESSAGE_LENGTH];
  11197. SQLWCHAR temp_sqlstate[1000];
  11198. rc = SQLGetDiagRec
  11199. #if defined(OTL_ODBC_zOS)
  11200. (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC,
  11201. hdbc == nullptr ? henv : hdbc,
  11202. #else
  11203. (SQL_HANDLE_DBC, hdbc,
  11204. #endif
  11205. 1, temp_sqlstate,
  11206. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), temp_msg,
  11207. SQL_MAX_MESSAGE_LENGTH - 1,
  11208. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11209. temp_msg[msg_len] = 0;
  11210. otl_convert_SQLWCHAR_to_char_2(
  11211. OTL_RCAST(unsigned char *, &exception_struct.sqlstate[0]),
  11212. temp_sqlstate);
  11213. otl_convert_SQLWCHAR_to_char_2(
  11214. OTL_RCAST(unsigned char *, &exception_struct.msg[0]), temp_msg);
  11215. }
  11216. #endif
  11217. #else
  11218. void *temp_ptr = &exception_struct.code;
  11219. rc = SQLGetDiagRec
  11220. #if defined(OTL_ODBC_zOS)
  11221. (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC,
  11222. hdbc == nullptr ? henv : hdbc,
  11223. #else
  11224. (SQL_HANDLE_DBC, hdbc,
  11225. #endif
  11226. 1, OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  11227. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  11228. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  11229. SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11230. #endif
  11231. #else
  11232. #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
  11233. void* temp_ptr=&exception_struct.code;
  11234. rc = SQLError(henv, hdbc, 0, // hstmt
  11235. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  11236. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  11237. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  11238. SQL_MAX_MESSAGE_LENGTH - 1,
  11239. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11240. #else
  11241. rc = SQLError(henv, hdbc, 0, // hstmt
  11242. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  11243. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code),
  11244. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  11245. SQL_MAX_MESSAGE_LENGTH - 1,
  11246. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  11247. #endif
  11248. #endif
  11249. exception_struct.msg[msg_len] = 0;
  11250. if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR)
  11251. exception_struct.msg[0] = 0;
  11252. #if (ODBCVER >= 0x0300)
  11253. #if defined(OTL_EXTENDED_EXCEPTION)
  11254. else if (rc != SQL_NO_DATA)
  11255. #if defined(OTL_ODBC_zOS)
  11256. {
  11257. if (hdbc)
  11258. otl_fill_exception(exception_struct, hdbc, SQL_HANDLE_DBC);
  11259. else
  11260. otl_fill_exception(exception_struct, henv, SQL_HANDLE_ENV);
  11261. }
  11262. #else
  11263. otl_fill_exception(exception_struct, hdbc, SQL_HANDLE_DBC);
  11264. #endif
  11265. #endif
  11266. #endif
  11267. }
  11268. OTL_NODISCARD int commit(void) {
  11269. #ifndef OTL_ODBC_MYSQL
  11270. #if (ODBCVER >= 0x0300)
  11271. status = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
  11272. #else
  11273. status = SQLTransact(henv, hdbc, SQL_COMMIT);
  11274. #endif
  11275. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11276. return 0;
  11277. else
  11278. return 1;
  11279. #else
  11280. return 1;
  11281. #endif
  11282. }
  11283. OTL_NODISCARD int rollback(void) {
  11284. #ifndef OTL_ODBC_MYSQL
  11285. #if (ODBCVER >= 0x0300)
  11286. status = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK);
  11287. #else
  11288. status = SQLTransact(henv, hdbc, SQL_ROLLBACK);
  11289. #endif
  11290. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  11291. return 0;
  11292. else
  11293. return 1;
  11294. #else
  11295. return 1;
  11296. #endif
  11297. }
  11298. private:
  11299. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  11300. public:
  11301. otl_conn(const otl_conn &) = delete;
  11302. otl_conn &operator=(const otl_conn &) = delete;
  11303. private:
  11304. #else
  11305. otl_conn(const otl_conn &)
  11306. : henv(OTL_SQL_NULL_HANDLE_VAL), hdbc(OTL_SQL_NULL_HANDLE_VAL),
  11307. timeout(0), cursor_type(0), status(SQL_SUCCESS),
  11308. long_max_size(otl_short_int_max), extern_lda(false)
  11309. #if defined(OTL_ODBC_zOS)
  11310. ,
  11311. logoff_commit(true)
  11312. #endif
  11313. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  11314. ,
  11315. throws_on_sql_success_with_info(false)
  11316. #endif
  11317. ,
  11318. connection_type(OTL_DEFAULT_ODBC_CONNECT) {
  11319. }
  11320. otl_conn &operator=(const otl_conn &) { return *this; }
  11321. #endif
  11322. };
  11323. class otl_var;
  11324. class otl_cur;
  11325. class otl_sel;
  11326. class otl_cur0 {
  11327. protected:
  11328. friend class otl_sel;
  11329. friend class otl_var;
  11330. OTL_SQLHSTMT cda;
  11331. int last_param_data_token;
  11332. int last_sql_param_data_status;
  11333. int sql_param_data_count;
  11334. public:
  11335. otl_cur0()
  11336. : cda(OTL_SQL_NULL_HANDLE_VAL), last_param_data_token(0),
  11337. last_sql_param_data_status(0), sql_param_data_count(0) {}
  11338. virtual ~otl_cur0() {}
  11339. OTL_NODISCARD OTL_SQLHSTMT get_cda() { return cda; }
  11340. private:
  11341. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  11342. public:
  11343. otl_cur0(const otl_cur0 &) = delete;
  11344. otl_cur0 &operator=(const otl_cur0 &) = delete;
  11345. private:
  11346. #else
  11347. otl_cur0(const otl_cur0 &)
  11348. : cda(OTL_SQL_NULL_HANDLE_VAL), last_param_data_token(0),
  11349. last_sql_param_data_status(0), sql_param_data_count(0) {}
  11350. otl_cur0 &operator=(const otl_cur0 &) { return *this; }
  11351. #endif
  11352. };
  11353. class otl_cur;
  11354. class otl_var {
  11355. private:
  11356. friend class otl_cur;
  11357. unsigned char *p_v;
  11358. OTL_SQLLEN_PTR p_len;
  11359. int ftype;
  11360. int act_elem_size;
  11361. bool lob_stream_mode;
  11362. int lob_stream_flag;
  11363. int vparam_type;
  11364. int lob_len;
  11365. int lob_pos;
  11366. int lob_ftype;
  11367. otl_adapter_enum otl_adapter;
  11368. bool charz_flag;
  11369. public:
  11370. #if defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS)
  11371. void set_nls_flag(const bool) {}
  11372. #endif
  11373. void reset_lob_len() { lob_len = 0; }
  11374. OTL_NODISCARD otl_adapter_enum get_otl_adapter() const { return otl_adapter; }
  11375. void set_lob_stream_mode(const bool alob_stream_mode) {
  11376. lob_stream_mode = alob_stream_mode;
  11377. }
  11378. void set_vparam_type(const int avparam_type) { vparam_type = avparam_type; }
  11379. void set_charz_flag(const bool acharz_flag) { charz_flag = acharz_flag; }
  11380. otl_var()
  11381. : p_v(nullptr), p_len(nullptr), ftype(0), act_elem_size(0),
  11382. lob_stream_mode(false), lob_stream_flag(0), vparam_type(-1), lob_len(0),
  11383. lob_pos(0), lob_ftype(0),
  11384. otl_adapter(OTL_ADAPTER_ENUM otl_odbc_adapter), charz_flag(false) {}
  11385. virtual ~otl_var() {
  11386. delete[] p_v;
  11387. delete[] p_len;
  11388. }
  11389. OTL_NODISCARD int write_dt(void *trg, const void *src, const int sz) {
  11390. memcpy(trg, src, OTL_SCAST(unsigned int, sz));
  11391. return 1;
  11392. }
  11393. OTL_NODISCARD int read_dt(void *trg, const void *src, const int sz) {
  11394. memcpy(trg, src, OTL_SCAST(unsigned int, sz));
  11395. return 1;
  11396. }
  11397. void set_lob_stream_flag(const int flg = 1) { lob_stream_flag = flg; }
  11398. OTL_NODISCARD int get_pl_tab_len(void) { return 0; }
  11399. OTL_NODISCARD int get_max_pl_tab_len(void) { return 0; }
  11400. void set_pl_tab_len(const int /* pl_tab_len */) {}
  11401. OTL_NODISCARD int write_blob(const otl_long_string &s, const int /* alob_len */,
  11402. int &aoffset, otl_cur0 &cur) {
  11403. SQLRETURN rc = 0;
  11404. SQLINTEGER temp_len = 0;
  11405. SQLPOINTER pToken = nullptr;
  11406. int param_number = 0;
  11407. if (!lob_stream_flag && !lob_stream_mode)
  11408. return 1;
  11409. if (aoffset == 1) {
  11410. if (cur.sql_param_data_count == 0) {
  11411. rc = SQLParamData(cur.cda, &pToken);
  11412. param_number = OTL_SCAST(int, OTL_RCAST(size_t, pToken));
  11413. ++cur.sql_param_data_count;
  11414. cur.last_sql_param_data_status = rc;
  11415. cur.last_param_data_token = param_number;
  11416. if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO &&
  11417. rc != SQL_NEED_DATA)
  11418. return 0;
  11419. }
  11420. }
  11421. if (ftype == otl_var_raw_long)
  11422. temp_len = s.len();
  11423. else
  11424. temp_len = s.len() * OTL_SCAST(int, sizeof(OTL_CHAR));
  11425. rc = SQLPutData(cur.cda, s.v, temp_len);
  11426. if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
  11427. return 0;
  11428. else {
  11429. aoffset += s.len();
  11430. return 1;
  11431. }
  11432. }
  11433. OTL_NODISCARD int clob_blob(otl_cur0 &cur) {
  11434. SQLRETURN rc = 0;
  11435. SQLPOINTER pToken = nullptr;
  11436. int param_number = 0;
  11437. if (!(cur.last_param_data_token == 0 && cur.sql_param_data_count > 0)) {
  11438. rc = SQLParamData(cur.cda, &pToken);
  11439. param_number = OTL_SCAST(int, OTL_RCAST(size_t, pToken));
  11440. ++cur.sql_param_data_count;
  11441. cur.last_sql_param_data_status = rc;
  11442. cur.last_param_data_token = param_number;
  11443. if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO &&
  11444. #if (ODBCVER >= 0x0300)
  11445. rc != SQL_NO_DATA &&
  11446. #endif
  11447. rc != SQL_NEED_DATA)
  11448. return 0;
  11449. }
  11450. return 1;
  11451. }
  11452. OTL_NODISCARD int read_blob(otl_cur0 &cur, otl_long_string &s, const int andx, int &aoffset,
  11453. int &eof_flag) {
  11454. SQLRETURN rc = 0;
  11455. OTL_SQLLEN retLen = 0;
  11456. int chunkLen = 0;
  11457. if (!lob_stream_flag && !lob_stream_mode)
  11458. return 1;
  11459. int buf_size = s.get_buf_size() * OTL_SCAST(int, sizeof(OTL_CHAR));
  11460. if (ftype == otl_var_raw_long)
  11461. buf_size = s.get_buf_size();
  11462. rc = SQLGetData(cur.cda, OTL_SCAST(SQLUSMALLINT, lob_pos),
  11463. OTL_SCAST(SQLSMALLINT, lob_ftype), s.v, buf_size, &retLen);
  11464. if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) {
  11465. if (retLen == SQL_NULL_DATA) {
  11466. chunkLen = 0;
  11467. p_len[andx] = SQL_NULL_DATA;
  11468. } else if (retLen > buf_size || retLen == SQL_NO_TOTAL)
  11469. chunkLen = s.get_buf_size();
  11470. else {
  11471. if (ftype == otl_var_raw_long)
  11472. chunkLen = OTL_SCAST(int, retLen);
  11473. else
  11474. chunkLen = OTL_SCAST(int, retLen) / OTL_SCAST(int, sizeof(OTL_CHAR));
  11475. }
  11476. #if defined(OTL_UNICODE)
  11477. if (lob_ftype == SQL_C_WCHAR)
  11478. s.set_len(chunkLen - 1);
  11479. #else
  11480. if (lob_ftype == SQL_C_CHAR)
  11481. s.set_len(chunkLen - 1);
  11482. #endif
  11483. else
  11484. s.set_len(chunkLen);
  11485. if (lob_len == 0 && aoffset == 1 && retLen != SQL_NULL_DATA &&
  11486. retLen != SQL_NO_TOTAL)
  11487. lob_len = OTL_SCAST(int, retLen);
  11488. aoffset += chunkLen;
  11489. if (chunkLen < s.get_buf_size() || rc == SQL_SUCCESS) {
  11490. s.set_len(chunkLen);
  11491. eof_flag = 1;
  11492. } else
  11493. eof_flag = 0;
  11494. return 1;
  11495. }
  11496. #if (ODBCVER >= 0x0300)
  11497. else if (rc == SQL_NO_DATA)
  11498. #else
  11499. else if (rc == SQL_NO_DATA_FOUND)
  11500. #endif
  11501. return 1;
  11502. else
  11503. return 0;
  11504. }
  11505. OTL_NODISCARD int get_blob_len(const int /* ndx */, int &alen) {
  11506. alen = lob_len;
  11507. return 1;
  11508. }
  11509. OTL_NODISCARD int put_blob(void) { return 1; }
  11510. OTL_NODISCARD int get_blob(const int /* ndx */, unsigned char * /* abuf */,
  11511. const int /* buf_size */, int & /* len */) {
  11512. return 1;
  11513. }
  11514. OTL_NODISCARD int save_blob(const unsigned char * /* abuf */, const int /* len */,
  11515. const int /* extern_buffer_flag */) {
  11516. return 1;
  11517. }
  11518. OTL_NODISCARD int actual_elem_size(void) { return act_elem_size; }
  11519. void init(const bool, const int aftype, int &aelem_size,
  11520. const otl_stream_buffer_size_type aarray_size,
  11521. const void * /* connect_struct */ = nullptr,
  11522. const int /*apl_tab_size*/ = 0) {
  11523. int i;
  11524. size_t byte_size = 0;
  11525. ftype = aftype;
  11526. act_elem_size = aelem_size;
  11527. byte_size = OTL_SCAST(size_t, aelem_size) * OTL_SCAST(size_t, aarray_size);
  11528. #if defined(OTL_UNICODE)
  11529. if (aftype == otl_var_char || aftype == otl_var_varchar_long) {
  11530. byte_size *= sizeof(OTL_CHAR);
  11531. p_v = new unsigned char[byte_size];
  11532. } else
  11533. p_v = new unsigned char[byte_size];
  11534. #else
  11535. p_v = new unsigned char[byte_size];
  11536. #endif
  11537. p_len = new OTL_SQLLEN[OTL_SCAST(size_t,aarray_size)];
  11538. memset(p_v, 0, byte_size);
  11539. for (i = 0; i < aarray_size; ++i) {
  11540. if (ftype == otl_var_char)
  11541. p_len[i] = OTL_SCAST(OTL_SQLLEN, SQL_NTS);
  11542. else if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long)
  11543. p_len[i] = 0;
  11544. else
  11545. p_len[i] = OTL_SCAST(OTL_SQLLEN, aelem_size);
  11546. }
  11547. }
  11548. void set_null(int ndx) { p_len[ndx] = SQL_NULL_DATA; }
  11549. void set_not_null(int ndx, int pelem_size) { set_len(pelem_size, ndx); }
  11550. void set_len(int len, int ndx) {
  11551. switch (ftype) {
  11552. case otl_var_char:
  11553. p_len[ndx] = SQL_NTS;
  11554. break;
  11555. case otl_var_varchar_long:
  11556. if (lob_stream_mode &&
  11557. (vparam_type == otl_input_param || vparam_type == otl_inout_param))
  11558. p_len[ndx] = SQL_DATA_AT_EXEC;
  11559. else
  11560. #if defined(OTL_UNICODE)
  11561. p_len[ndx] =
  11562. OTL_SCAST(OTL_SQLLEN, len * OTL_SCAST(int, sizeof(OTL_CHAR)));
  11563. #else
  11564. p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len);
  11565. #endif
  11566. break;
  11567. case otl_var_raw_long:
  11568. if (lob_stream_mode &&
  11569. (vparam_type == otl_input_param || vparam_type == otl_inout_param))
  11570. p_len[ndx] = SQL_DATA_AT_EXEC;
  11571. else
  11572. p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len);
  11573. break;
  11574. default:
  11575. p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len);
  11576. break;
  11577. }
  11578. }
  11579. OTL_NODISCARD int get_len(int ndx) {
  11580. if (p_len[ndx] == SQL_NULL_DATA)
  11581. return 0;
  11582. else
  11583. #if defined(OTL_UNICODE)
  11584. if (ftype == otl_var_varchar_long || ftype == otl_var_char)
  11585. return OTL_SCAST(int, p_len[ndx]) / OTL_SCAST(int, sizeof(OTL_CHAR));
  11586. else
  11587. return OTL_SCAST(int, p_len[ndx]);
  11588. #else
  11589. return OTL_SCAST(int, p_len[ndx]);
  11590. #endif
  11591. }
  11592. OTL_NODISCARD int is_null(int ndx) { return p_len[ndx] == SQL_NULL_DATA; }
  11593. OTL_NODISCARD void *val(int ndx, int pelem_size) {
  11594. #if defined(OTL_UNICODE)
  11595. switch (ftype) {
  11596. case otl_var_char:
  11597. case otl_var_varchar_long:
  11598. return OTL_RCAST(void *,
  11599. &p_v[(OTL_SCAST(size_t, ndx)) *
  11600. OTL_SCAST(size_t, pelem_size) * sizeof(OTL_CHAR)]);
  11601. default:
  11602. return OTL_RCAST(
  11603. void *,
  11604. &p_v[(OTL_SCAST(size_t, ndx)) * OTL_SCAST(size_t, pelem_size)]);
  11605. }
  11606. #else
  11607. return OTL_RCAST(
  11608. void *, &p_v[(OTL_SCAST(size_t, ndx)) * OTL_SCAST(size_t, pelem_size)]);
  11609. #endif
  11610. }
  11611. #define OTL_SQL_UNICODE_CHAR (-95)
  11612. #define OTL_SQL_UNICODE_VARCHAR (-96)
  11613. #define OTL_SQL_UNICODE_LONGVARCHAR (-97)
  11614. #define OTL_SQL_SS_TIME2 (-154)
  11615. #define OTL_SQL_SS_TIMESTAMPOFFSET (-155)
  11616. OTL_NODISCARD static int int2ext(int int_type) {
  11617. switch (int_type) {
  11618. #if defined(OTL_UNICODE)
  11619. case SQL_VARCHAR:
  11620. return SQL_C_WCHAR;
  11621. case SQL_WVARCHAR:
  11622. return SQL_C_WCHAR;
  11623. case SQL_CHAR:
  11624. return SQL_C_WCHAR;
  11625. case SQL_WCHAR:
  11626. return SQL_C_WCHAR;
  11627. case SQL_LONGVARCHAR:
  11628. return SQL_WLONGVARCHAR;
  11629. case SQL_WLONGVARCHAR:
  11630. return SQL_WLONGVARCHAR;
  11631. case OTL_SQL_UNICODE_VARCHAR:
  11632. return SQL_C_WCHAR;
  11633. case OTL_SQL_UNICODE_CHAR:
  11634. return SQL_C_WCHAR;
  11635. case OTL_SQL_UNICODE_LONGVARCHAR:
  11636. return SQL_WLONGVARCHAR;
  11637. #else
  11638. case SQL_CHAR:
  11639. return SQL_C_CHAR;
  11640. case SQL_VARCHAR:
  11641. return SQL_C_CHAR;
  11642. #if defined(SQL_WCHAR)
  11643. case SQL_WCHAR:
  11644. return SQL_C_CHAR;
  11645. #else
  11646. case -8:
  11647. return SQL_C_CHAR;
  11648. #endif
  11649. #if defined(SQL_WVARCHAR)
  11650. case SQL_WVARCHAR:
  11651. return SQL_C_CHAR;
  11652. #else
  11653. case -9:
  11654. return SQL_C_CHAR;
  11655. #endif
  11656. case SQL_LONGVARCHAR:
  11657. return SQL_LONGVARCHAR;
  11658. #if defined(SQL_WLONGVARCHAR)
  11659. case SQL_WLONGVARCHAR:
  11660. return SQL_LONGVARCHAR;
  11661. #else
  11662. case -10:
  11663. return SQL_LONGVARCHAR;
  11664. #endif
  11665. case OTL_SQL_UNICODE_VARCHAR:
  11666. return SQL_C_CHAR;
  11667. case OTL_SQL_UNICODE_CHAR:
  11668. return SQL_C_CHAR;
  11669. case OTL_SQL_UNICODE_LONGVARCHAR:
  11670. return SQL_LONGVARCHAR;
  11671. #endif
  11672. #if (ODBCVER >= 0x0300)
  11673. case SQL_TYPE_DATE:
  11674. return OTL_SQL_C_TIMESTAMP;
  11675. case SQL_TYPE_TIMESTAMP:
  11676. return OTL_SQL_C_TIMESTAMP;
  11677. case SQL_TYPE_TIME:
  11678. return OTL_SQL_C_TIMESTAMP;
  11679. case OTL_SQL_SS_TIME2:
  11680. return OTL_SQL_C_TIMESTAMP;
  11681. #if defined(OTL_UNICODE)
  11682. case OTL_SQL_SS_TIMESTAMPOFFSET:
  11683. return SQL_C_WCHAR;
  11684. #else
  11685. case OTL_SQL_SS_TIMESTAMPOFFSET:
  11686. return SQL_C_CHAR;
  11687. #endif
  11688. #else
  11689. case OTL_SQL_DATE:
  11690. return OTL_SQL_C_TIMESTAMP;
  11691. case OTL_SQL_TIMESTAMP:
  11692. return OTL_SQL_C_TIMESTAMP;
  11693. case OTL_SQL_TIME:
  11694. return OTL_SQL_C_TIMESTAMP;
  11695. #endif
  11696. #if defined(OTL_BIGINT)
  11697. case SQL_BIGINT:
  11698. return SQL_C_SBIGINT;
  11699. #else
  11700. case SQL_BIGINT:
  11701. return SQL_C_DOUBLE;
  11702. #endif
  11703. #if defined(OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT) && !defined(OTL_BIGINT)
  11704. #error OTL_BIGINT needs to be defined for OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT \
  11705. to function
  11706. #elif defined(OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT) && defined(OTL_BIGINT)
  11707. case SQL_DECIMAL:
  11708. return SQL_C_SBIGINT;
  11709. #else
  11710. case SQL_DECIMAL:
  11711. return SQL_C_DOUBLE;
  11712. #endif
  11713. case SQL_DOUBLE:
  11714. return SQL_C_DOUBLE;
  11715. case SQL_FLOAT:
  11716. return SQL_C_DOUBLE;
  11717. case SQL_INTEGER:
  11718. return SQL_C_SLONG;
  11719. #if defined(OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT) && !defined(OTL_BIGINT)
  11720. #error OTL_BIGINT needs to be defined for OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT \
  11721. to function
  11722. #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT) && defined(OTL_BIGINT)
  11723. case SQL_NUMERIC:
  11724. return SQL_C_SBIGINT;
  11725. #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT) && !defined(OTL_UBIGINT)
  11726. #error OTL_UBIGINT needs to be defined for OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT \
  11727. to function
  11728. #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT) && defined(OTL_UBIGINT)
  11729. case SQL_NUMERIC:
  11730. return SQL_C_UBIGINT;
  11731. #else
  11732. case SQL_NUMERIC:
  11733. return SQL_C_DOUBLE;
  11734. #endif
  11735. case SQL_REAL:
  11736. return SQL_C_DOUBLE;
  11737. case SQL_SMALLINT:
  11738. return SQL_C_SSHORT;
  11739. case SQL_BIT:
  11740. return SQL_C_SSHORT;
  11741. case SQL_TINYINT:
  11742. return SQL_C_SSHORT;
  11743. case SQL_LONGVARBINARY:
  11744. return SQL_LONGVARBINARY;
  11745. #if defined(OTL_MAP_SQL_VARBINARY_TO_RAW_LONG)
  11746. case SQL_VARBINARY:
  11747. return SQL_LONGVARBINARY;
  11748. #else
  11749. case SQL_VARBINARY:
  11750. return SQL_C_BINARY;
  11751. #endif
  11752. #if (ODBCVER >= 0x0350)
  11753. #if defined(OTL_MAP_SQL_GUID_TO_CHAR)
  11754. #if defined(OTL_UNICODE)
  11755. case SQL_GUID:
  11756. return SQL_C_WCHAR;
  11757. #else
  11758. case SQL_GUID:
  11759. return SQL_C_CHAR;
  11760. #endif
  11761. #else
  11762. case SQL_GUID:
  11763. return SQL_C_BINARY;
  11764. #endif
  11765. #endif
  11766. #if defined(OTL_MAP_SQL_BINARY_TO_CHAR)
  11767. #if defined(OTL_UNICODE)
  11768. case SQL_BINARY: // MS SQL TIMESTAMP, BINARY
  11769. return SQL_C_WCHAR;
  11770. #else
  11771. case SQL_BINARY: // MS SQL TIMESTAMP, BINARY
  11772. return SQL_C_CHAR;
  11773. #endif
  11774. #else
  11775. case SQL_BINARY:
  11776. return SQL_C_BINARY;
  11777. #endif
  11778. #if (ODBCVER >= 0x0350)
  11779. case OTL_SQL_XML:
  11780. #if defined(OTL_UNICODE)
  11781. return SQL_C_WCHAR;
  11782. #else
  11783. return SQL_C_CHAR;
  11784. #endif
  11785. #endif
  11786. default:
  11787. return otl_unsupported_type;
  11788. }
  11789. }
  11790. OTL_NODISCARD static int datatype_size(int ftype, int maxsz, int int_type,
  11791. int max_long_size) {
  11792. switch (ftype) {
  11793. #if defined(OTL_UNICODE)
  11794. case SQL_C_WCHAR:
  11795. #endif
  11796. case SQL_C_CHAR:
  11797. switch (int_type) {
  11798. case SQL_BINARY: // MS SQL TIMESTAMP
  11799. return 17;
  11800. #if defined(OTL_UNICODE)
  11801. case SQL_WLONGVARCHAR:
  11802. #endif
  11803. case SQL_LONGVARCHAR:
  11804. return max_long_size * OTL_SCAST(int, sizeof(OTL_CHAR));
  11805. case SQL_LONGVARBINARY:
  11806. return max_long_size;
  11807. case OTL_SQL_DATE:
  11808. return 40;
  11809. #if (ODBCVER >= 0x0300)
  11810. case SQL_TYPE_TIMESTAMP:
  11811. #else
  11812. case OTL_SQL_TIMESTAMP:
  11813. #endif
  11814. return 40;
  11815. #if (ODBCVER >= 0x0300)
  11816. case SQL_TYPE_TIME:
  11817. #else
  11818. case OTL_SQL_TIME:
  11819. #endif
  11820. return 40;
  11821. #if (ODBCVER >= 0x0350)
  11822. #if defined(OTL_MAP_SQL_GUID_TO_SQL_VARBINARY)
  11823. case SQL_GUID:
  11824. return 16;
  11825. #else
  11826. case SQL_GUID:
  11827. return 40;
  11828. #endif
  11829. #endif
  11830. default:
  11831. return (maxsz + 1);
  11832. }
  11833. #if defined(OTL_BIGINT)
  11834. case SQL_C_SBIGINT:
  11835. return sizeof(OTL_BIGINT);
  11836. #endif
  11837. #if defined(OTL_UBIGINT)
  11838. case SQL_C_UBIGINT:
  11839. return sizeof(OTL_UBIGINT);
  11840. #endif
  11841. case SQL_C_DOUBLE:
  11842. return sizeof(double);
  11843. case SQL_C_SLONG:
  11844. return sizeof(int);
  11845. case SQL_C_SSHORT:
  11846. return sizeof(short int);
  11847. case OTL_SQL_C_TIMESTAMP:
  11848. return sizeof(OTL_SQL_TIMESTAMP_STRUCT);
  11849. case OTL_SQL_C_TIME:
  11850. return sizeof(OTL_SQL_TIME_STRUCT);
  11851. case OTL_SQL_C_DATE:
  11852. return sizeof(OTL_SQL_DATE_STRUCT);
  11853. #if defined(OTL_UNICODE)
  11854. case SQL_WLONGVARCHAR:
  11855. return max_long_size;
  11856. #endif
  11857. case SQL_LONGVARCHAR:
  11858. return max_long_size;
  11859. case SQL_LONGVARBINARY:
  11860. return max_long_size;
  11861. case SQL_C_BINARY:
  11862. return maxsz;
  11863. default:
  11864. return 0;
  11865. }
  11866. }
  11867. static void map_ftype(otl_column_desc &desc, const int max_long_size,
  11868. int &ftype, int &elem_size,
  11869. otl_select_struct_override &a_override,
  11870. const int column_ndx, const int
  11871. #if !defined(OTL_ODBC_TIMESTEN) && defined(OTL_ODBC_MULTI_MODE)
  11872. connection_type
  11873. #endif
  11874. ) {
  11875. int ndx = a_override.find(column_ndx);
  11876. if (ndx == -1) {
  11877. #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE)
  11878. if (desc.prec == 0 && desc.dbtype == SQL_VARBINARY)
  11879. ftype = SQL_LONGVARBINARY;
  11880. else
  11881. #elif defined(OTL_ODBC_MULTI_MODE)
  11882. if ((connection_type == OTL_MSSQL_2005_ODBC_CONNECT ||
  11883. connection_type == OTL_MSSQL_2008_ODBC_CONNECT) &&
  11884. desc.prec == 0 && desc.dbtype == SQL_VARBINARY)
  11885. ftype = SQL_LONGVARBINARY;
  11886. else
  11887. #endif
  11888. ftype = int2ext(desc.dbtype);
  11889. if (desc.dbsize == 0) {
  11890. #if !defined(OTL_UNICODE)
  11891. if (ftype == SQL_C_CHAR)
  11892. ftype = SQL_LONGVARCHAR;
  11893. #else
  11894. if (ftype == SQL_C_CHAR)
  11895. ftype = SQL_LONGVARCHAR;
  11896. else if (ftype == SQL_C_WCHAR)
  11897. ftype = SQL_WLONGVARCHAR;
  11898. #endif
  11899. elem_size = max_long_size * OTL_SCAST(int, sizeof(OTL_CHAR));
  11900. } else {
  11901. elem_size = datatype_size(ftype, OTL_SCAST(int, desc.dbsize),
  11902. desc.dbtype, max_long_size);
  11903. }
  11904. switch (ftype) {
  11905. #if defined(OTL_UNICODE)
  11906. case SQL_C_WCHAR:
  11907. ftype = otl_var_char;
  11908. break;
  11909. case SQL_WLONGVARCHAR:
  11910. ftype = otl_var_varchar_long;
  11911. break;
  11912. #else
  11913. case SQL_C_CHAR:
  11914. ftype = otl_var_char;
  11915. break;
  11916. case SQL_LONGVARCHAR:
  11917. ftype = otl_var_varchar_long;
  11918. break;
  11919. #endif
  11920. case SQL_C_DOUBLE:
  11921. if (a_override.get_all_mask() & otl_all_num2str) {
  11922. ftype = otl_var_char;
  11923. elem_size = otl_num_str_size;
  11924. } else
  11925. ftype = otl_var_double;
  11926. break;
  11927. #if defined(OTL_BIGINT)
  11928. case SQL_C_SBIGINT:
  11929. if (a_override.get_all_mask() & otl_all_num2str) {
  11930. ftype = otl_var_char;
  11931. elem_size = otl_num_str_size;
  11932. } else
  11933. ftype = otl_var_bigint;
  11934. break;
  11935. #endif
  11936. #if defined(OTL_UBIGINT)
  11937. case SQL_C_UBIGINT:
  11938. if (a_override.get_all_mask() & otl_all_num2str) {
  11939. ftype = otl_var_char;
  11940. elem_size = otl_num_str_size;
  11941. } else
  11942. ftype = otl_var_ubigint;
  11943. break;
  11944. #endif
  11945. case SQL_C_SLONG:
  11946. if (a_override.get_all_mask() & otl_all_num2str) {
  11947. ftype = otl_var_char;
  11948. elem_size = otl_num_str_size;
  11949. } else
  11950. ftype = otl_var_int;
  11951. break;
  11952. case SQL_C_SSHORT:
  11953. if (a_override.get_all_mask() & otl_all_num2str) {
  11954. ftype = otl_var_char;
  11955. elem_size = otl_num_str_size;
  11956. } else
  11957. ftype = otl_var_short;
  11958. break;
  11959. case SQL_LONGVARBINARY:
  11960. ftype = otl_var_raw_long;
  11961. break;
  11962. case OTL_SQL_C_DATE:
  11963. case OTL_SQL_C_TIME:
  11964. case OTL_SQL_C_TIMESTAMP:
  11965. if (a_override.get_all_mask() & otl_all_date2str) {
  11966. ftype = otl_var_char;
  11967. elem_size = otl_date_str_size;
  11968. } else
  11969. ftype = otl_var_timestamp;
  11970. break;
  11971. case SQL_C_BINARY:
  11972. ftype = otl_var_raw;
  11973. break;
  11974. default:
  11975. ftype = 0;
  11976. break;
  11977. }
  11978. } else {
  11979. ftype = a_override.get_col_type(ndx);
  11980. switch (ftype) {
  11981. case otl_var_char:
  11982. elem_size =
  11983. a_override.get_col_size(ndx) * OTL_SCAST(int, sizeof(OTL_CHAR));
  11984. break;
  11985. case otl_var_raw:
  11986. elem_size = a_override.get_col_size(ndx);
  11987. break;
  11988. case otl_var_double:
  11989. elem_size = sizeof(double);
  11990. break;
  11991. case otl_var_bdouble:
  11992. elem_size = sizeof(double);
  11993. break;
  11994. case otl_var_float:
  11995. elem_size = sizeof(float);
  11996. break;
  11997. case otl_var_bfloat:
  11998. elem_size = sizeof(float);
  11999. break;
  12000. case otl_var_int:
  12001. elem_size = sizeof(int);
  12002. break;
  12003. #if defined(OTL_BIGINT)
  12004. case otl_var_bigint:
  12005. elem_size = sizeof(OTL_BIGINT);
  12006. break;
  12007. #endif
  12008. #if defined(OTL_UBIGINT)
  12009. case otl_var_ubigint:
  12010. elem_size = sizeof(OTL_UBIGINT);
  12011. break;
  12012. #endif
  12013. case otl_var_unsigned_int:
  12014. elem_size = sizeof(unsigned);
  12015. break;
  12016. case otl_var_short:
  12017. elem_size = sizeof(short);
  12018. break;
  12019. case otl_var_long_int:
  12020. elem_size = sizeof(double);
  12021. break;
  12022. default:
  12023. elem_size = a_override.get_col_size(ndx);
  12024. break;
  12025. }
  12026. }
  12027. desc.otl_var_dbtype = ftype;
  12028. }
  12029. private:
  12030. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  12031. public:
  12032. otl_var(const otl_var &) = delete;
  12033. otl_var &operator=(const otl_var &) = delete;
  12034. private:
  12035. #else
  12036. otl_var(const otl_var &)
  12037. : p_v(nullptr), p_len(nullptr), ftype(0), act_elem_size(0),
  12038. lob_stream_mode(false), lob_stream_flag(0), vparam_type(-1), lob_len(0),
  12039. lob_pos(0), lob_ftype(0), otl_adapter(OTL_ADAPTER_ENUM otl_odbc_adapter),
  12040. charz_flag(false) {}
  12041. otl_var &operator=(const otl_var &) { return *this; }
  12042. #endif
  12043. };
  12044. #if defined(OTL_ODBC_zOS) || defined(OTL_ODBC_TIMESTEN) || \
  12045. (defined(SQL_TXN_READ_COMMITTED) && \
  12046. !defined(SQL_TRANSACTION_READ_COMMITTED))
  12047. const long otl_tran_read_uncommitted = SQL_TXN_READ_UNCOMMITTED;
  12048. const long otl_tran_read_committed = SQL_TXN_READ_COMMITTED;
  12049. const long otl_tran_repeatable_read = SQL_TXN_REPEATABLE_READ;
  12050. const long otl_tran_serializable = SQL_TXN_SERIALIZABLE;
  12051. #else
  12052. const long otl_tran_read_uncommitted = SQL_TRANSACTION_READ_UNCOMMITTED;
  12053. const long otl_tran_read_committed = SQL_TRANSACTION_READ_COMMITTED;
  12054. const long otl_tran_repeatable_read = SQL_TRANSACTION_REPEATABLE_READ;
  12055. const long otl_tran_serializable = SQL_TRANSACTION_SERIALIZABLE;
  12056. #endif
  12057. class otl_sel;
  12058. class otl_cur : public otl_cur0 {
  12059. private:
  12060. friend class otl_sel;
  12061. int status;
  12062. otl_conn *adb;
  12063. int direct_exec_flag;
  12064. long _rpc;
  12065. bool canceled;
  12066. int last_iters;
  12067. public:
  12068. void set_batch_error_mode(const bool) {}
  12069. OTL_NODISCARD int get_number_of_errors_in_batch(int &arc) {
  12070. arc = 1;
  12071. return 0;
  12072. }
  12073. void get_error(const int, int &, otl_exc &) {}
  12074. void set_canceled(const bool acanceled) { canceled = acanceled; }
  12075. void reset_last_param_data_token() { last_param_data_token = 0; }
  12076. void reset_last_sql_param_data_status() { last_sql_param_data_status = 0; }
  12077. void reset_sql_param_data_count() { sql_param_data_count = 0; }
  12078. otl_cur()
  12079. : otl_cur0(), status(0), adb(nullptr), direct_exec_flag(0), _rpc(0),
  12080. canceled(false), last_iters(0) {
  12081. cda = OTL_SQL_NULL_HANDLE_VAL;
  12082. last_param_data_token = 0;
  12083. last_sql_param_data_status = 0;
  12084. sql_param_data_count = 0;
  12085. }
  12086. virtual ~otl_cur() {}
  12087. OTL_NODISCARD int cancel(void) {
  12088. status = SQLCancel(cda);
  12089. canceled = true;
  12090. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12091. return 0;
  12092. else
  12093. return 1;
  12094. }
  12095. OTL_NODISCARD int open(otl_conn & /* connect */, otl_var * /* var */) { return 1; }
  12096. void set_direct_exec(const int flag) { direct_exec_flag = flag; }
  12097. void set_parse_only(const int /*flag*/) {}
  12098. OTL_NODISCARD int open(otl_conn &connect) {
  12099. last_iters = 0;
  12100. direct_exec_flag = 0;
  12101. adb = &connect;
  12102. #if (ODBCVER >= 0x0300)
  12103. status = SQLAllocHandle(SQL_HANDLE_STMT, connect.hdbc, &cda);
  12104. #else
  12105. status = SQLAllocStmt(connect.hdbc, &cda);
  12106. #endif
  12107. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12108. return 0;
  12109. if (connect.timeout > 0) {
  12110. #if (ODBCVER >= 0x0300)
  12111. status = SQLSetStmtAttr(
  12112. cda, SQL_ATTR_QUERY_TIMEOUT,
  12113. OTL_RCAST(void *, OTL_SCAST(size_t, connect.timeout)), SQL_NTS);
  12114. #else
  12115. status = SQLSetStmtOption(cda,
  12116. SQL_QUERY_TIMEOUT,
  12117. OTL_SCAST(size_t,connect.timeout));
  12118. #endif
  12119. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12120. return 0;
  12121. }
  12122. if (connect.cursor_type != 0) { // other than default
  12123. #if (ODBCVER >= 0x0300)
  12124. status = SQLSetStmtAttr(
  12125. cda, SQL_ATTR_CURSOR_TYPE,
  12126. OTL_RCAST(void *, OTL_SCAST(size_t, connect.cursor_type)), SQL_NTS);
  12127. #else
  12128. status = SQLSetStmtOption(cda, SQL_CURSOR_TYPE, OTL_SCAST(size_t,connect.cursor_type));
  12129. #endif
  12130. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12131. return 0;
  12132. }
  12133. return 1;
  12134. }
  12135. OTL_NODISCARD int close(const char = 'N') {
  12136. last_iters = 0;
  12137. #if (ODBCVER >= 0x0300)
  12138. status = SQLFreeHandle(SQL_HANDLE_STMT, cda);
  12139. #else
  12140. status = SQLFreeStmt(cda, SQL_DROP);
  12141. #endif
  12142. adb = nullptr;
  12143. cda = OTL_SQL_NULL_HANDLE_VAL;
  12144. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12145. return 0;
  12146. else
  12147. return 1;
  12148. }
  12149. OTL_NODISCARD SQLRETURN sql_row_count(OTL_SQLLEN *total_rpc) {
  12150. #if defined(OTL_ODBC_ALTERNATE_RPC)
  12151. OTL_SQLLEN rpc = 0;
  12152. SQLRETURN rc;
  12153. do {
  12154. rc = SQLRowCount(cda, &rpc);
  12155. if (rc != SQL_SUCCESS)
  12156. return rc;
  12157. *total_rpc += rpc;
  12158. rc = SQLMoreResults(cda);
  12159. } while (rc == SQL_SUCCESS);
  12160. return SQL_SUCCESS;
  12161. #else
  12162. return SQLRowCount(cda, total_rpc);
  12163. #endif
  12164. }
  12165. void convert(char*& c, short int& in_str, const char* stm_text){
  12166. while (*c) {
  12167. if (*c == '\'') {
  12168. if (!in_str)
  12169. in_str = 1;
  12170. else {
  12171. if (c[1] == '\'')
  12172. ++c;
  12173. else
  12174. in_str = 0;
  12175. }
  12176. }
  12177. if (*c == ':' && !in_str &&
  12178. ((c > stm_text && *(c - 1) != '\\') || c == stm_text)) {
  12179. *c = '?';
  12180. ++c;
  12181. while (isalnum(OTL_SCAST(unsigned char, *c)) || *c == '_') {
  12182. *c = ' ';
  12183. ++c;
  12184. }
  12185. } else if (*c == ':' && !in_str &&
  12186. ((c > stm_text && *(c - 1) == '\\') || c == stm_text)) {
  12187. char *c_1 = c - 1;
  12188. char *c_ = c;
  12189. while (*c_) {
  12190. *c_1 = *c_;
  12191. ++c_1;
  12192. ++c_;
  12193. }
  12194. if (c_1 > c - 1)
  12195. *c_1 = 0;
  12196. --c;
  12197. }
  12198. ++c;
  12199. }
  12200. }
  12201. OTL_NODISCARD int parse(char *stm_text, const int external_direct_exec_flag) {
  12202. #if !defined(OTL_ODBC_TIMESTEN)
  12203. short in_str = 0;
  12204. #endif
  12205. bool do_not_call_sql_row_count = false;
  12206. #if defined(OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT)
  12207. if (OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT(stm_text)) {
  12208. do_not_call_sql_row_count = true;
  12209. direct_exec_flag = 1;
  12210. }
  12211. #endif
  12212. char *c = stm_text;
  12213. if(external_direct_exec_flag){
  12214. direct_exec_flag=1;
  12215. #if !defined(OTL_ODBC_TIMESTEN)
  12216. // Converting : notation into ODBC's native notation ?
  12217. convert(c,in_str,stm_text);
  12218. #endif
  12219. }
  12220. if (*c == '$') {
  12221. ++c;
  12222. _rpc = 0;
  12223. direct_exec_flag = 1;
  12224. const int ctl_arr_size = 6;
  12225. struct {
  12226. OTL_SQLCHAR_PTR name_ptr;
  12227. OTL_SQLSMALLINT name_len;
  12228. OTL_SQLCHAR name[512];
  12229. } ctl_arr[ctl_arr_size];
  12230. #if (defined(UNICODE) || defined(_UNICODE))
  12231. struct {
  12232. SQLWCHAR name_ptr;
  12233. OTL_SQLSMALLINT name_len;
  12234. SQLWCHAR name[512];
  12235. } ctl_arr_W[ctl_arr_size];
  12236. #endif
  12237. int i = 0;
  12238. for (i = 0; i < ctl_arr_size; ++i) {
  12239. ctl_arr[i].name_ptr = nullptr;
  12240. ctl_arr[i].name_len = 0;
  12241. ctl_arr[i].name[0] = 0;
  12242. #if (defined(UNICODE) || defined(_UNICODE))
  12243. ctl_arr_W[i].name_ptr = 0;
  12244. ctl_arr_W[i].name_len = 0;
  12245. ctl_arr_W[i].name[0] = 0;
  12246. #endif
  12247. }
  12248. char func_name[256];
  12249. int par_num = 0;
  12250. char par_val[512];
  12251. size_t par_val_len = 0;
  12252. size_t fn_len = 0;
  12253. bool func_found = false;
  12254. while (*c && *c != ' ' && fn_len < sizeof(func_name)) {
  12255. ++fn_len;
  12256. func_name[fn_len - 1] = *c;
  12257. ++c;
  12258. }
  12259. if (fn_len < sizeof(func_name) - 1) {
  12260. ++fn_len;
  12261. func_name[fn_len - 1] = 0;
  12262. } else
  12263. func_name[sizeof(func_name) - 1] = 0;
  12264. while (*c == ' ')
  12265. ++c;
  12266. while (*c) {
  12267. if (*c == '$') {
  12268. ++c;
  12269. par_num = OTL_SCAST(int, *c - '0') - 1;
  12270. ++c;
  12271. while (*c && *c == ' ')
  12272. ++c;
  12273. if (*c == ':' &&
  12274. ((c > stm_text && *(c - 1) != '\\') || c == stm_text)) {
  12275. ++c;
  12276. while (*c && *c == ' ')
  12277. ++c;
  12278. if (*c == '\'') {
  12279. par_val_len = 0;
  12280. ++c;
  12281. while (*c && *c != '\'' && par_val_len < sizeof(par_val)) {
  12282. ++par_val_len;
  12283. par_val[par_val_len - 1] = *c;
  12284. ++c;
  12285. }
  12286. if (par_val_len < sizeof(par_val) - 1) {
  12287. ++par_val_len;
  12288. par_val[par_val_len - 1] = 0;
  12289. } else
  12290. par_val[sizeof(par_val) - 1] = 0;
  12291. if (par_num >= 0 && par_num < ctl_arr_size) {
  12292. ctl_arr[par_num].name_ptr = ctl_arr[par_num].name;
  12293. ctl_arr[par_num].name_len = SQL_NTS;
  12294. OTL_STRCPY_S(OTL_RCAST(char *, ctl_arr[par_num].name),
  12295. sizeof(ctl_arr[par_num].name),
  12296. OTL_RCAST(const char *, par_val));
  12297. }
  12298. }
  12299. ++c;
  12300. while (*c && *c == ' ')
  12301. ++c;
  12302. }
  12303. } else
  12304. ++c;
  12305. }
  12306. status = SQL_SUCCESS;
  12307. if (strcmp(func_name, "SQLTables") == 0) {
  12308. #if (defined(UNICODE) || defined(_UNICODE))
  12309. otl_convert_char_to_SQLWCHAR(
  12310. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12311. otl_convert_char_to_SQLWCHAR(
  12312. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12313. otl_convert_char_to_SQLWCHAR(
  12314. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12315. otl_convert_char_to_SQLWCHAR(
  12316. ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name));
  12317. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12318. status = SQLTables(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name,
  12319. SQL_NTS, ctl_arr_W[2].name, SQL_NTS,
  12320. ctl_arr_W[3].name, SQL_NTS);
  12321. #else
  12322. status = SQLTablesA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12323. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12324. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12325. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12326. #endif
  12327. #else
  12328. status = SQLTables(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12329. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12330. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12331. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12332. #endif
  12333. func_found = true;
  12334. } else if (strcmp(func_name, "SQLStatistics") == 0) {
  12335. #if (defined(UNICODE) || defined(_UNICODE))
  12336. otl_convert_char_to_SQLWCHAR(
  12337. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12338. otl_convert_char_to_SQLWCHAR(
  12339. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12340. otl_convert_char_to_SQLWCHAR(
  12341. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12342. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12343. status = SQLStatistics(cda, ctl_arr_W[0].name, SQL_NTS,
  12344. ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name,
  12345. SQL_NTS, SQL_INDEX_ALL, SQL_QUICK);
  12346. #else
  12347. status = SQLStatisticsA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12348. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12349. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12350. SQL_INDEX_ALL, SQL_QUICK);
  12351. #endif
  12352. #else
  12353. status = SQLStatistics(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12354. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12355. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12356. SQL_INDEX_ALL, SQL_QUICK);
  12357. #endif
  12358. func_found = true;
  12359. } else if (strcmp(func_name, "SQLGetTypeInfo") == 0) {
  12360. status = SQLGetTypeInfo(cda, SQL_ALL_TYPES);
  12361. func_found = true;
  12362. } else if (strcmp(func_name, "SQLColumns") == 0) {
  12363. #if (defined(UNICODE) || defined(_UNICODE))
  12364. otl_convert_char_to_SQLWCHAR(
  12365. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12366. otl_convert_char_to_SQLWCHAR(
  12367. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12368. otl_convert_char_to_SQLWCHAR(
  12369. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12370. otl_convert_char_to_SQLWCHAR(
  12371. ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name));
  12372. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12373. status = SQLColumns(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name,
  12374. SQL_NTS, ctl_arr_W[2].name, SQL_NTS,
  12375. ctl_arr_W[3].name, SQL_NTS);
  12376. #else
  12377. status = SQLColumnsA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12378. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12379. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12380. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12381. #endif
  12382. #else
  12383. status = SQLColumns(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12384. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12385. ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12386. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12387. #endif
  12388. func_found = true;
  12389. } else if (strcmp(func_name, "SQLProcedures") == 0) {
  12390. #if (defined(UNICODE) || defined(_UNICODE))
  12391. otl_convert_char_to_SQLWCHAR(
  12392. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12393. otl_convert_char_to_SQLWCHAR(
  12394. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12395. otl_convert_char_to_SQLWCHAR(
  12396. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12397. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12398. status =
  12399. SQLProcedures(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name,
  12400. SQL_NTS, ctl_arr_W[2].name, SQL_NTS);
  12401. #else
  12402. status = SQLProceduresA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12403. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12404. ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12405. #endif
  12406. #else
  12407. status = SQLProcedures(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12408. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12409. ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12410. #endif
  12411. func_found = true;
  12412. } else if (strcmp(func_name, "SQLColumnPrivileges") == 0) {
  12413. #if (defined(UNICODE) || defined(_UNICODE))
  12414. otl_convert_char_to_SQLWCHAR(
  12415. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12416. otl_convert_char_to_SQLWCHAR(
  12417. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12418. otl_convert_char_to_SQLWCHAR(
  12419. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12420. otl_convert_char_to_SQLWCHAR(
  12421. ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name));
  12422. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12423. status = SQLColumnPrivileges(
  12424. cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS,
  12425. ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS);
  12426. #else
  12427. status = SQLColumnPrivilegesA(
  12428. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12429. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12430. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12431. #endif
  12432. #else
  12433. status = SQLColumnPrivileges(
  12434. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12435. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12436. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12437. #endif
  12438. func_found = true;
  12439. } else if (strcmp(func_name, "SQLTablePrivileges") == 0) {
  12440. #if (defined(UNICODE) || defined(_UNICODE))
  12441. otl_convert_char_to_SQLWCHAR(
  12442. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12443. otl_convert_char_to_SQLWCHAR(
  12444. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12445. otl_convert_char_to_SQLWCHAR(
  12446. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12447. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12448. status = SQLTablePrivileges(cda, ctl_arr_W[0].name, SQL_NTS,
  12449. ctl_arr_W[1].name, SQL_NTS,
  12450. ctl_arr_W[2].name, SQL_NTS);
  12451. #else
  12452. status = SQLTablePrivilegesA(
  12453. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12454. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12455. #endif
  12456. #else
  12457. status = SQLTablePrivileges(
  12458. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12459. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12460. #endif
  12461. func_found = true;
  12462. } else if (strcmp(func_name, "SQLPrimaryKeys") == 0) {
  12463. #if (defined(UNICODE) || defined(_UNICODE))
  12464. otl_convert_char_to_SQLWCHAR(
  12465. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12466. otl_convert_char_to_SQLWCHAR(
  12467. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12468. otl_convert_char_to_SQLWCHAR(
  12469. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12470. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12471. status =
  12472. SQLPrimaryKeys(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name,
  12473. SQL_NTS, ctl_arr_W[2].name, SQL_NTS);
  12474. #else
  12475. status = SQLPrimaryKeysA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12476. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12477. ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12478. #endif
  12479. #else
  12480. status = SQLPrimaryKeys(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len,
  12481. ctl_arr[1].name_ptr, ctl_arr[1].name_len,
  12482. ctl_arr[2].name_ptr, ctl_arr[2].name_len);
  12483. #endif
  12484. func_found = true;
  12485. } else if (strcmp(func_name, "SQLProcedureColumns") == 0) {
  12486. #if (defined(UNICODE) || defined(_UNICODE))
  12487. otl_convert_char_to_SQLWCHAR(
  12488. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12489. otl_convert_char_to_SQLWCHAR(
  12490. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12491. otl_convert_char_to_SQLWCHAR(
  12492. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12493. otl_convert_char_to_SQLWCHAR(
  12494. ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name));
  12495. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12496. status = SQLProcedureColumns(
  12497. cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS,
  12498. ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS);
  12499. #else
  12500. status = SQLProcedureColumnsA(
  12501. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12502. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12503. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12504. #endif
  12505. #else
  12506. status = SQLProcedureColumns(
  12507. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12508. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12509. ctl_arr[3].name_ptr, ctl_arr[3].name_len);
  12510. #endif
  12511. func_found = true;
  12512. } else if (strcmp(func_name, "SQLForeignKeys") == 0) {
  12513. #if (defined(UNICODE) || defined(_UNICODE))
  12514. otl_convert_char_to_SQLWCHAR(
  12515. ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name));
  12516. otl_convert_char_to_SQLWCHAR(
  12517. ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name));
  12518. otl_convert_char_to_SQLWCHAR(
  12519. ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name));
  12520. otl_convert_char_to_SQLWCHAR(
  12521. ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name));
  12522. otl_convert_char_to_SQLWCHAR(
  12523. ctl_arr_W[4].name, OTL_RCAST(unsigned char *, ctl_arr[4].name));
  12524. otl_convert_char_to_SQLWCHAR(
  12525. ctl_arr_W[5].name, OTL_RCAST(unsigned char *, ctl_arr[5].name));
  12526. #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT)
  12527. status = SQLForeignKeys(
  12528. cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS,
  12529. ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS,
  12530. ctl_arr_W[4].name, SQL_NTS, ctl_arr_W[5].name, SQL_NTS);
  12531. #else
  12532. status = SQLForeignKeysA(
  12533. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12534. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12535. ctl_arr[3].name_ptr, ctl_arr[3].name_len, ctl_arr[4].name_ptr,
  12536. ctl_arr[4].name_len, ctl_arr[5].name_ptr, ctl_arr[5].name_len);
  12537. #endif
  12538. #else
  12539. status = SQLForeignKeys(
  12540. cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr,
  12541. ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len,
  12542. ctl_arr[3].name_ptr, ctl_arr[3].name_len, ctl_arr[4].name_ptr,
  12543. ctl_arr[4].name_len, ctl_arr[5].name_ptr, ctl_arr[5].name_len);
  12544. #endif
  12545. func_found = true;
  12546. }
  12547. if (!func_found)
  12548. return 2;
  12549. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12550. return 0;
  12551. else
  12552. return 1;
  12553. }
  12554. if (direct_exec_flag) {
  12555. _rpc = 0;
  12556. #if (defined(UNICODE) || defined(_UNICODE))
  12557. {
  12558. SQLWCHAR *temp_stm_text = new SQLWCHAR[strlen(stm_text) + 1];
  12559. otl_convert_char_to_SQLWCHAR(temp_stm_text,
  12560. OTL_RCAST(unsigned char *, stm_text));
  12561. status = SQLExecDirect(cda, temp_stm_text, SQL_NTS);
  12562. delete[] temp_stm_text;
  12563. }
  12564. #else
  12565. status =
  12566. SQLExecDirect(cda, OTL_RCAST(OTL_SQLCHAR_PTR, stm_text), SQL_NTS);
  12567. #endif
  12568. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  12569. if (adb && adb->throws_on_sql_success_with_info &&
  12570. status == SQL_SUCCESS_WITH_INFO)
  12571. return 0;
  12572. #endif
  12573. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO &&
  12574. #if (ODBCVER >= 0x0300)
  12575. status != SQL_NO_DATA
  12576. #else
  12577. status != SQL_NO_DATA_FOUND
  12578. #endif
  12579. )
  12580. return 0;
  12581. else {
  12582. _rpc = 0;
  12583. if (!do_not_call_sql_row_count) {
  12584. OTL_SQLLEN tmp_rpc = 0;
  12585. SQLRETURN diag_status = sql_row_count(&tmp_rpc);
  12586. if (diag_status == SQL_SUCCESS ||
  12587. diag_status == SQL_SUCCESS_WITH_INFO)
  12588. _rpc = OTL_SCAST(long, tmp_rpc);
  12589. }
  12590. return 1;
  12591. }
  12592. }
  12593. #if !defined(OTL_ODBC_TIMESTEN)
  12594. // Converting : notation into ODBC's native notation ?
  12595. convert(c,in_str,stm_text);
  12596. #endif
  12597. #if defined(OTL_DB2_CLI)
  12598. OTL_SQLINTEGER temp_isolation_level = 0;
  12599. status = SQLGetStmtAttr(cda, SQL_ATTR_TXN_ISOLATION,
  12600. OTL_RCAST(SQLPOINTER, &temp_isolation_level),
  12601. SQL_IS_POINTER, nullptr);
  12602. if (OTL_SCAST(long, temp_isolation_level) == otl_tran_read_committed ||
  12603. OTL_SCAST(long, temp_isolation_level) == otl_tran_read_uncommitted) {
  12604. status = SQLSetStmtAttr(cda, SQL_ATTR_CLOSE_BEHAVIOR,
  12605. OTL_RCAST(void *, SQL_CC_RELEASE), SQL_NTS);
  12606. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12607. return 0;
  12608. }
  12609. #endif
  12610. #if (defined(UNICODE) || defined(_UNICODE))
  12611. {
  12612. SQLWCHAR *temp_stm_text = new SQLWCHAR[strlen(stm_text) + 1];
  12613. otl_convert_char_to_SQLWCHAR(temp_stm_text,
  12614. OTL_RCAST(unsigned char *, stm_text));
  12615. status = SQLPrepare(cda, temp_stm_text, SQL_NTS);
  12616. delete[] temp_stm_text;
  12617. }
  12618. #else
  12619. status = SQLPrepare(cda, OTL_RCAST(OTL_SQLCHAR_PTR, stm_text), SQL_NTS);
  12620. #endif
  12621. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12622. return 0;
  12623. else
  12624. return 1;
  12625. }
  12626. OTL_NODISCARD int exec(const int iters, const int /*rowoff*/,
  12627. #if defined(OTL_ODBC_ALTERNATE_RPC)
  12628. const otl_sql_exec_from_enum otl_sql_exec_from_class)
  12629. #else
  12630. const otl_sql_exec_from_enum /*otl_sql_exec_from_class*/)
  12631. #endif
  12632. {
  12633. #if (ODBCVER >= 0x0300)
  12634. #else
  12635. #if defined(OTL_ODBC_TIMESTEN_WIN) && defined(_WIN64)
  12636. OTL_SQLULEN irows;
  12637. #else
  12638. #if defined(OTL_ODBC_UNIX)
  12639. #if !defined(BUILD_LEGACY_64_BIT_MODE) && defined(SIZEOF_LONG_INT) && \
  12640. (SIZEOF_LONG_INT == 8)
  12641. OTL_SQLULEN irows;
  12642. #else
  12643. OTL_SQLUINTEGER irows;
  12644. #endif
  12645. #else
  12646. OTL_SQLUINTEGER irows;
  12647. #endif
  12648. #endif
  12649. #endif
  12650. if (direct_exec_flag) {
  12651. return 1;
  12652. } else {
  12653. #if !defined(OTL_ODBC_MYSQL) && !defined(OTL_ODBC_XTG_IBASE6)
  12654. #if (ODBCVER >= 0x0300)
  12655. if (last_iters > 1 || iters > 1 || _rpc > 1) {
  12656. last_iters = iters;
  12657. size_t temp_iters = OTL_SCAST(size_t, iters);
  12658. status = SQLSetStmtAttr(cda, SQL_ATTR_PARAMSET_SIZE,
  12659. OTL_RCAST(void *, temp_iters), SQL_NTS);
  12660. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12661. return 0;
  12662. }
  12663. #else
  12664. if (last_iters > 1 || iters > 1 || _rpc > 1) {
  12665. last_iters = iters;
  12666. status = SQLParamOptions(cda,
  12667. #if defined(OTL_ODBC_UNIX)
  12668. #if !defined(BUILD_LEGACY_64_BIT_MODE) && defined(SIZEOF_LONG_INT) && \
  12669. (SIZEOF_LONG_INT == 8)
  12670. OTL_SCAST(OTL_SQLULEN, iters),
  12671. #else
  12672. OTL_SCAST(OTL_SQLUINTEGER, iters),
  12673. #endif
  12674. #else
  12675. OTL_SCAST(OTL_SQLUINTEGER, iters),
  12676. #endif
  12677. &irows);
  12678. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  12679. return 0;
  12680. }
  12681. #endif
  12682. #endif
  12683. _rpc = 0;
  12684. last_param_data_token = 0;
  12685. last_sql_param_data_status = 0;
  12686. sql_param_data_count = 0;
  12687. status = SQLExecute(cda);
  12688. if (canceled)
  12689. return 0;
  12690. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  12691. if (adb && adb->throws_on_sql_success_with_info &&
  12692. status == SQL_SUCCESS_WITH_INFO)
  12693. return 0;
  12694. #endif
  12695. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO &&
  12696. #if (ODBCVER >= 0x0300)
  12697. status != SQL_NO_DATA &&
  12698. #else
  12699. status != SQL_NO_DATA_FOUND &&
  12700. #endif
  12701. status != SQL_NEED_DATA)
  12702. return 0;
  12703. if (status == SQL_NEED_DATA) {
  12704. _rpc = iters;
  12705. return 1;
  12706. }
  12707. OTL_SQLLEN tmp_rpc = 0;
  12708. SQLRETURN diag_status = 0;
  12709. #if defined(OTL_ODBC_ALTERNATE_RPC)
  12710. if (otl_sql_exec_from_class == otl_sql_exec_from_cursor_class) {
  12711. diag_status = sql_row_count(&tmp_rpc);
  12712. if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO)
  12713. _rpc = OTL_SCAST(long, tmp_rpc);
  12714. return 1;
  12715. } else {
  12716. _rpc = 0;
  12717. return 1;
  12718. }
  12719. #else
  12720. diag_status = sql_row_count(&tmp_rpc);
  12721. if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO)
  12722. _rpc = OTL_SCAST(long, tmp_rpc);
  12723. return 1;
  12724. #endif
  12725. }
  12726. }
  12727. OTL_NODISCARD long get_rpc() OTL_NO_THROW { return _rpc; }
  12728. OTL_NODISCARD int tmpl_ftype2odbc_ftype(const int ftype) {
  12729. switch (ftype) {
  12730. #if defined(OTL_UNICODE)
  12731. case otl_var_char:
  12732. return SQL_C_WCHAR;
  12733. case otl_var_varchar_long:
  12734. return SQL_WLONGVARCHAR;
  12735. #else
  12736. case otl_var_char:
  12737. return SQL_C_CHAR;
  12738. case otl_var_varchar_long:
  12739. return SQL_LONGVARCHAR;
  12740. #endif
  12741. case otl_var_double:
  12742. return SQL_C_DOUBLE;
  12743. #if defined(OTL_BIGINT)
  12744. case otl_var_bigint:
  12745. return SQL_C_SBIGINT;
  12746. #endif
  12747. #if defined(OTL_UBIGINT)
  12748. case otl_var_ubigint:
  12749. return SQL_C_UBIGINT;
  12750. #endif
  12751. case otl_var_float:
  12752. return SQL_C_FLOAT;
  12753. case otl_var_int:
  12754. return SQL_C_SLONG;
  12755. case otl_var_long_int:
  12756. #if defined(OTL_MAP_LONG_TO_SQL_C_SBIGINT) && \
  12757. ((ODBCVER >= 0x0300) || defined(OTL_ODBC_TIMESTEN))
  12758. {
  12759. static bool long_is_8_bytes = sizeof(long) == 8;
  12760. if (long_is_8_bytes)
  12761. return SQL_C_SBIGINT;
  12762. else
  12763. return SQL_C_SLONG;
  12764. }
  12765. #else
  12766. return SQL_C_SLONG;
  12767. #endif
  12768. case otl_var_unsigned_int:
  12769. return SQL_C_ULONG;
  12770. case otl_var_short:
  12771. return SQL_C_SSHORT;
  12772. case otl_var_timestamp:
  12773. case otl_var_db2time:
  12774. case otl_var_db2date:
  12775. return OTL_SQL_C_TIMESTAMP;
  12776. case otl_var_raw_long:
  12777. return SQL_LONGVARBINARY;
  12778. case otl_var_raw:
  12779. return SQL_C_BINARY;
  12780. default:
  12781. return 0;
  12782. }
  12783. }
  12784. OTL_NODISCARD int otl_map_ext2int(int ftype) {
  12785. switch (ftype) {
  12786. #if defined(OTL_UNICODE)
  12787. case SQL_WLONGVARCHAR:
  12788. return SQL_WLONGVARCHAR;
  12789. case SQL_C_WCHAR:
  12790. return SQL_WVARCHAR;
  12791. #else
  12792. case SQL_LONGVARCHAR:
  12793. return SQL_LONGVARCHAR;
  12794. case SQL_C_CHAR:
  12795. return SQL_VARCHAR;
  12796. #endif
  12797. case SQL_LONGVARBINARY:
  12798. return SQL_LONGVARBINARY;
  12799. case OTL_SQL_C_DATE:
  12800. return OTL_SQL_DATE;
  12801. #if (ODBCVER >= 0x0300)
  12802. case OTL_SQL_C_TIME:
  12803. return SQL_TYPE_TIME;
  12804. case OTL_SQL_C_TIMESTAMP:
  12805. return SQL_TYPE_TIMESTAMP;
  12806. #else
  12807. case OTL_SQL_C_TIME:
  12808. return OTL_SQL_TIME;
  12809. case OTL_SQL_C_TIMESTAMP:
  12810. return OTL_SQL_TIMESTAMP;
  12811. #endif
  12812. case SQL_C_DOUBLE:
  12813. return SQL_DOUBLE;
  12814. #if defined(OTL_BIGINT)
  12815. case SQL_C_SBIGINT:
  12816. return SQL_BIGINT;
  12817. #endif
  12818. #if defined(OTL_UBIGINT)
  12819. case SQL_C_UBIGINT:
  12820. return SQL_BIGINT;
  12821. #endif
  12822. #if defined(OTL_MAPS_SQL_C_FLOAT_TO_SQL_REAL)
  12823. case SQL_C_FLOAT:
  12824. return SQL_REAL;
  12825. #else
  12826. case SQL_C_FLOAT:
  12827. return SQL_FLOAT;
  12828. #endif
  12829. case SQL_C_SLONG:
  12830. return SQL_INTEGER;
  12831. case SQL_C_SSHORT:
  12832. return SQL_SMALLINT;
  12833. case SQL_C_ULONG:
  12834. return SQL_DOUBLE;
  12835. case SQL_C_BINARY:
  12836. return SQL_VARBINARY;
  12837. default:
  12838. return -1;
  12839. }
  12840. }
  12841. OTL_NODISCARD int bind(const char * /* name */, otl_var &v, const int aelem_size,
  12842. const int aftype, const int aparam_type, const int name_pos,
  12843. const int
  12844. #if !defined(OTL_ODBC_TIMESTEN) && defined(OTL_ODBC_MULTI_MODE)
  12845. connection_type
  12846. #endif
  12847. ,
  12848. const int /* apl_tab_size */) {
  12849. OTL_SQLSMALLINT ftype =
  12850. OTL_SCAST(OTL_SQLSMALLINT, tmpl_ftype2odbc_ftype(aftype));
  12851. OTL_SQLSMALLINT ftype_save = ftype;
  12852. int param_type;
  12853. int parm_pos = name_pos;
  12854. v.vparam_type = aparam_type;
  12855. switch (aparam_type) {
  12856. case otl_input_param:
  12857. param_type = SQL_PARAM_INPUT;
  12858. break;
  12859. case otl_output_param:
  12860. param_type = SQL_PARAM_OUTPUT;
  12861. break;
  12862. case otl_inout_param:
  12863. param_type = SQL_PARAM_INPUT_OUTPUT;
  12864. break;
  12865. default:
  12866. param_type = SQL_PARAM_INPUT;
  12867. break;
  12868. }
  12869. #if defined(OTL_UNICODE)
  12870. if (ftype == SQL_WLONGVARCHAR) {
  12871. ftype = SQL_C_WCHAR;
  12872. #else
  12873. if (ftype == SQL_LONGVARCHAR) {
  12874. ftype = SQL_C_CHAR;
  12875. #endif
  12876. } else if (ftype == SQL_LONGVARBINARY) {
  12877. ftype = SQL_C_BINARY;
  12878. }
  12879. int sqltype = otl_map_ext2int(ftype_save);
  12880. int mapped_sqltype = sqltype;
  12881. if (aftype == otl_var_db2date)
  12882. #if (ODBCVER >= 0x0300)
  12883. mapped_sqltype = SQL_TYPE_DATE;
  12884. #else
  12885. mapped_sqltype = OTL_SQL_DATE;
  12886. #endif
  12887. else if (aftype == otl_var_db2time)
  12888. #if (ODBCVER >= 0x0300)
  12889. mapped_sqltype = SQL_TYPE_TIME;
  12890. #else
  12891. mapped_sqltype = SQL_TIME;
  12892. #endif
  12893. if (v.lob_stream_mode && (ftype_save == SQL_LONGVARBINARY ||
  12894. #if defined(OTL_UNICODE)
  12895. ftype_save == SQL_WLONGVARCHAR)) {
  12896. #else
  12897. ftype_save == SQL_LONGVARCHAR)) {
  12898. #endif
  12899. // in case of "stream mode" the variable
  12900. // gets bound in a special way
  12901. #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE)
  12902. switch (ftype_save) {
  12903. case SQL_LONGVARBINARY:
  12904. mapped_sqltype = SQL_VARBINARY;
  12905. break;
  12906. #if defined(OTL_UNICODE)
  12907. case SQL_WLONGVARCHAR:
  12908. mapped_sqltype = SQL_WVARCHAR;
  12909. break;
  12910. #else
  12911. case SQL_LONGVARCHAR:
  12912. mapped_sqltype = SQL_VARCHAR;
  12913. break;
  12914. #endif
  12915. }
  12916. #elif defined(OTL_ODBC_MULTI_MODE)
  12917. if (connection_type == OTL_MSSQL_2005_ODBC_CONNECT ||
  12918. connection_type == OTL_MSSQL_2008_ODBC_CONNECT) {
  12919. switch (ftype_save) {
  12920. case SQL_LONGVARBINARY:
  12921. mapped_sqltype = SQL_VARBINARY;
  12922. break;
  12923. #if defined(OTL_UNICODE)
  12924. case SQL_WLONGVARCHAR:
  12925. mapped_sqltype = SQL_WVARCHAR;
  12926. break;
  12927. #else
  12928. case SQL_LONGVARCHAR:
  12929. mapped_sqltype = SQL_VARCHAR;
  12930. break;
  12931. #endif
  12932. }
  12933. }
  12934. #endif
  12935. int temp_int_val =
  12936. #if (ODBCVER >= 0x0300)
  12937. sqltype == SQL_TYPE_TIMESTAMP ?
  12938. #if defined(OTL_ODBC_MULTI_MODE)
  12939. ((connection_type == OTL_MSSQL_2008_ODBC_CONNECT)
  12940. ? 7
  12941. : (connection_type == OTL_MSSQL_2005_ODBC_CONNECT)
  12942. ? 3
  12943. : otl_odbc_date_scale)
  12944. : 0;
  12945. #else
  12946. otl_odbc_date_scale
  12947. : 0;
  12948. #endif
  12949. #else
  12950. sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_scale : 0;
  12951. #endif
  12952. short int temp_val = OTL_SCAST(OTL_SQLSMALLINT, temp_int_val);
  12953. status = SQLBindParameter(
  12954. cda, OTL_SCAST(OTL_SQLUSMALLINT, parm_pos),
  12955. OTL_SCAST(OTL_SQLSMALLINT, param_type), ftype,
  12956. OTL_SCAST(OTL_SQLSMALLINT, mapped_sqltype),
  12957. #if (ODBCVER >= 0x0300)
  12958. #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE)
  12959. 0,
  12960. #elif defined(OTL_ODBC_MULTI_MODE)
  12961. (connection_type == OTL_MSSQL_2005_ODBC_CONNECT ||
  12962. connection_type == OTL_MSSQL_2008_ODBC_CONNECT)
  12963. ? 0
  12964. : (sqltype == SQL_TYPE_TIMESTAMP ? otl_odbc_date_prec
  12965. : OTL_SCAST(size_t,aelem_size)),
  12966. #else
  12967. sqltype == SQL_TYPE_TIMESTAMP ? otl_odbc_date_prec
  12968. : OTL_SCAST(OTL_SQLULEN, OTL_SCAST(size_t,aelem_size)),
  12969. #endif
  12970. #else
  12971. sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_prec : OTL_SCAST(size_t,aelem_size),
  12972. #endif
  12973. temp_val, OTL_RCAST(OTL_SQLPOINTER, OTL_SCAST(size_t, parm_pos)), 0,
  12974. v.p_len);
  12975. } else {
  12976. int temp_column_size = 0;
  12977. #if (ODBCVER >= 0x0300)
  12978. if (sqltype == SQL_TYPE_TIMESTAMP)
  12979. temp_column_size = otl_odbc_date_prec;
  12980. #if defined(OTL_UNICODE)
  12981. else if (ftype == SQL_C_WCHAR)
  12982. temp_column_size = (aelem_size - 1);
  12983. #else
  12984. else if (ftype == SQL_C_CHAR)
  12985. temp_column_size = aelem_size - 1;
  12986. #endif
  12987. else
  12988. temp_column_size = aelem_size;
  12989. #else
  12990. if (sqltype == OTL_SQL_TIMESTAMP)
  12991. temp_column_size = otl_odbc_date_prec;
  12992. else if (ftype == SQL_C_CHAR)
  12993. temp_column_size = aelem_size - 1;
  12994. else
  12995. temp_column_size = aelem_size;
  12996. #endif
  12997. OTL_SQLINTEGER buflen = 0;
  12998. #if defined(OTL_UNICODE)
  12999. if (ftype == SQL_C_WCHAR)
  13000. buflen = aelem_size * OTL_SCAST(int, sizeof(OTL_CHAR));
  13001. else
  13002. #endif
  13003. buflen = aelem_size;
  13004. int temp_int_val2 =
  13005. #if (ODBCVER >= 0x0300)
  13006. sqltype == SQL_TYPE_TIMESTAMP ?
  13007. #if defined(OTL_ODBC_MULTI_MODE)
  13008. ((connection_type == OTL_MSSQL_2008_ODBC_CONNECT)
  13009. ? 7
  13010. : (connection_type == OTL_MSSQL_2005_ODBC_CONNECT)
  13011. ? 3
  13012. : otl_odbc_date_scale)
  13013. : 0;
  13014. #else
  13015. otl_odbc_date_scale
  13016. : 0;
  13017. #endif
  13018. #else
  13019. sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_scale : 0;
  13020. #endif
  13021. short int temp_val2 = OTL_SCAST(OTL_SQLSMALLINT, temp_int_val2);
  13022. status =
  13023. SQLBindParameter(cda, OTL_SCAST(OTL_SQLUSMALLINT, parm_pos),
  13024. OTL_SCAST(OTL_SQLSMALLINT, param_type), ftype,
  13025. OTL_SCAST(OTL_SQLSMALLINT, mapped_sqltype),
  13026. OTL_SCAST(OTL_SQLULEN, temp_column_size), temp_val2,
  13027. OTL_RCAST(OTL_SQLPOINTER, v.p_v), buflen, v.p_len);
  13028. }
  13029. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13030. return 0;
  13031. else
  13032. return 1;
  13033. }
  13034. OTL_NODISCARD int bind(const int column_num, otl_var &v, const int elem_size,
  13035. const int aftype, const int param_type) {
  13036. SWORD ftype = OTL_SCAST(SWORD, tmpl_ftype2odbc_ftype(aftype));
  13037. v.vparam_type = param_type;
  13038. SWORD ftype_save = ftype;
  13039. #if defined(OTL_UNICODE)
  13040. if (ftype == SQL_WLONGVARCHAR) {
  13041. ftype = SQL_C_WCHAR;
  13042. #else
  13043. if (ftype == SQL_LONGVARCHAR) {
  13044. ftype = SQL_C_CHAR;
  13045. #endif
  13046. } else if (ftype == SQL_LONGVARBINARY) {
  13047. ftype = SQL_C_BINARY;
  13048. }
  13049. if (v.lob_stream_mode && (ftype_save == SQL_LONGVARBINARY ||
  13050. #if defined(OTL_UNICODE)
  13051. ftype_save == SQL_WLONGVARCHAR)) {
  13052. #else
  13053. ftype_save == SQL_LONGVARCHAR)) {
  13054. #endif
  13055. // in case of "stream mode" the variable
  13056. // remains unbound
  13057. v.lob_ftype = ftype;
  13058. v.lob_pos = column_num;
  13059. return 1;
  13060. } else {
  13061. SQLINTEGER buflen = elem_size;
  13062. #if defined(OTL_UNICODE)
  13063. if (ftype == SQL_C_WCHAR || ftype == SQL_WLONGVARCHAR)
  13064. buflen = elem_size * OTL_SCAST(SQLINTEGER, sizeof(OTL_CHAR));
  13065. #endif
  13066. status = SQLBindCol(cda, OTL_SCAST(unsigned short, column_num), ftype,
  13067. OTL_RCAST(PTR, v.p_v), buflen, &v.p_len[0]);
  13068. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13069. return 0;
  13070. else
  13071. return 1;
  13072. }
  13073. }
  13074. OTL_NODISCARD int describe_column(otl_column_desc &col, const int column_num,
  13075. int &eof_desc) {
  13076. OTL_SQLCHAR name[256];
  13077. OTL_SQLSMALLINT nlen;
  13078. OTL_SQLSMALLINT dbtype;
  13079. OTL_SQLLEN dbsize;
  13080. OTL_SQLSMALLINT scale;
  13081. OTL_SQLULEN prec;
  13082. OTL_SQLSMALLINT nullok;
  13083. OTL_SQLSMALLINT icols;
  13084. eof_desc = 0;
  13085. status = SQLNumResultCols(cda, &icols);
  13086. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13087. return 0;
  13088. if (column_num > icols) {
  13089. eof_desc = 1;
  13090. return 0;
  13091. }
  13092. #if (defined(UNICODE) || defined(_UNICODE))
  13093. {
  13094. SQLWCHAR temp_name[256];
  13095. status = SQLDescribeCol(
  13096. cda, OTL_SCAST(unsigned short, column_num), temp_name,
  13097. OTL_SCAST(OTL_SQLSMALLINT, sizeof(temp_name) / sizeof(SQLWCHAR)),
  13098. &nlen, &dbtype, &prec, &scale, &nullok);
  13099. otl_convert_SQLWCHAR_to_char(OTL_RCAST(unsigned char *, name), temp_name);
  13100. }
  13101. #else
  13102. status = SQLDescribeCol(cda, OTL_SCAST(unsigned short, column_num), name,
  13103. OTL_SCAST(SQLSMALLINT, sizeof(name)), &nlen,
  13104. &dbtype, &prec, &scale, &nullok);
  13105. #endif
  13106. if (!(status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO))
  13107. return 0;
  13108. dbsize = OTL_SCAST(OTL_SQLLEN, prec);
  13109. col.set_name(OTL_RCAST(char *, name));
  13110. #if defined(OTL_DB2_CLI) && defined(OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR)
  13111. #if defined(OTL_UNICODE)
  13112. #error OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR is not supported when \
  13113. OTL_UNICODE is defined
  13114. #else
  13115. if (dbtype == SQL_LONGVARCHAR &&
  13116. dbsize <= OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR) {
  13117. dbtype = SQL_VARCHAR;
  13118. }
  13119. #endif
  13120. #endif
  13121. col.dbtype = dbtype;
  13122. col.dbsize = OTL_SCAST(int, dbsize);
  13123. col.scale = scale;
  13124. col.prec = OTL_SCAST(int, prec);
  13125. col.nullok = nullok;
  13126. return 1;
  13127. }
  13128. void error(otl_exc &exception_struct) {
  13129. OTL_SQLRETURN rc;
  13130. OTL_SQLSMALLINT msg_len = 0;
  13131. #if (ODBCVER >= 0x0300)
  13132. #if (defined(UNICODE) || defined(_UNICODE))
  13133. {
  13134. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  13135. #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
  13136. void* temp_ptr = &exception_struct.code;
  13137. rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, &exception_struct.sqlstate[0],
  13138. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  13139. &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1,
  13140. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13141. #else
  13142. rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, &exception_struct.sqlstate[0],
  13143. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code),
  13144. &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1,
  13145. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13146. #endif
  13147. exception_struct.msg[msg_len] = 0;
  13148. #else
  13149. SQLWCHAR temp_sqlstate[1000];
  13150. SQLWCHAR temp_msg[SQL_MAX_MESSAGE_LENGTH];
  13151. rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, temp_sqlstate,
  13152. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code),
  13153. temp_msg, SQL_MAX_MESSAGE_LENGTH - 1,
  13154. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13155. temp_msg[msg_len] = 0;
  13156. otl_convert_SQLWCHAR_to_char_2(
  13157. OTL_RCAST(unsigned char *, &exception_struct.sqlstate[0]),
  13158. temp_sqlstate);
  13159. otl_convert_SQLWCHAR_to_char_2(
  13160. OTL_RCAST(unsigned char *, &exception_struct.msg[0]), temp_msg);
  13161. #endif
  13162. }
  13163. #else
  13164. void *temp_ptr = &exception_struct.code;
  13165. rc = SQLGetDiagRec(
  13166. SQL_HANDLE_STMT, cda, 1,
  13167. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  13168. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  13169. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  13170. SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13171. #endif
  13172. #else
  13173. #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
  13174. void* temp_ptr = &exception_struct.code;
  13175. rc = SQLError(adb->henv, adb->hdbc, cda,
  13176. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  13177. OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr),
  13178. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  13179. SQL_MAX_MESSAGE_LENGTH - 1,
  13180. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13181. #else
  13182. rc = SQLError(adb->henv, adb->hdbc, cda,
  13183. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]),
  13184. OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code),
  13185. OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]),
  13186. SQL_MAX_MESSAGE_LENGTH - 1,
  13187. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  13188. #endif
  13189. #endif
  13190. exception_struct.msg[msg_len] = 0;
  13191. if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR)
  13192. exception_struct.msg[0] = 0;
  13193. #if (ODBCVER >= 0x0300)
  13194. #if defined(OTL_EXTENDED_EXCEPTION)
  13195. else if (rc != SQL_NO_DATA)
  13196. otl_fill_exception(exception_struct, cda, SQL_HANDLE_STMT);
  13197. #endif
  13198. #endif
  13199. }
  13200. private:
  13201. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  13202. public:
  13203. otl_cur(const otl_cur &) = delete;
  13204. otl_cur &operator=(const otl_cur &) = delete;
  13205. private:
  13206. #else
  13207. otl_cur(const otl_cur &)
  13208. : otl_cur0(), status(0), adb(nullptr), direct_exec_flag(0), _rpc(0),
  13209. canceled(false), last_iters(0) {}
  13210. otl_cur &operator=(const otl_cur &) { return *this; }
  13211. #endif
  13212. };
  13213. class otl_sel {
  13214. public:
  13215. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  13216. void set_fetch_scroll_flag() { use_fetch_scroll_ = true; }
  13217. #endif
  13218. private:
  13219. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13220. bool use_fetch_scroll_;
  13221. #endif
  13222. int implicit_cursor;
  13223. int status;
  13224. int prefetch_array_size;
  13225. #if defined(OTL_ODBC_UNIX)
  13226. #if defined(SIZEOF_LONG)
  13227. #if (SIZEOF_LONG == 8)
  13228. #if !defined(BUILD_REAL_64_BIT_MODE)
  13229. OTL_SQLULEN crow;
  13230. #else
  13231. OTL_SQLUINTEGER crow;
  13232. #endif
  13233. #else // (SIZEOF_LONG==8)
  13234. OTL_SQLULEN crow;
  13235. #endif
  13236. #else // defined(SIZEOF_LONG)
  13237. OTL_SQLULEN crow;
  13238. #endif
  13239. #else // defined(OTL_ODBC_UNIX)
  13240. OTL_SQLULEN crow;
  13241. #endif
  13242. int in_sequence;
  13243. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300)
  13244. OTL_SQLUSMALLINT *row_status;
  13245. int row_status_arr_size;
  13246. #endif
  13247. public:
  13248. OTL_NODISCARD int get_implicit_cursor() const {
  13249. return implicit_cursor;
  13250. }
  13251. void set_arr_size(const int input_arr_size, int &out_array_size,
  13252. int &out_prefetch_array_size) {
  13253. #if defined(OTL_ODBC_TIMESTEN)
  13254. out_array_size = 1;
  13255. out_prefetch_array_size = input_arr_size;
  13256. #else
  13257. out_array_size = input_arr_size;
  13258. out_prefetch_array_size = 0;
  13259. #endif
  13260. }
  13261. OTL_NODISCARD int close_select(otl_cur &cur) {
  13262. if (!in_sequence)
  13263. return 1;
  13264. #if defined(OTL_DB2_CLI)
  13265. status = SQLCloseCursor(cur.cda);
  13266. #else
  13267. status = SQLFreeStmt(cur.cda, SQL_CLOSE);
  13268. #endif
  13269. in_sequence = 0;
  13270. if (status == SQL_ERROR)
  13271. return 0;
  13272. else
  13273. return 1;
  13274. }
  13275. otl_sel()
  13276. :
  13277. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13278. use_fetch_scroll_(false),
  13279. #endif
  13280. implicit_cursor(0), status(0), prefetch_array_size(0), crow(0),
  13281. in_sequence(0)
  13282. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300)
  13283. ,
  13284. row_status(nullptr), row_status_arr_size(0)
  13285. #endif
  13286. {
  13287. }
  13288. virtual ~otl_sel() {
  13289. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300)
  13290. if (row_status != 0) {
  13291. delete[] row_status;
  13292. row_status = nullptr;
  13293. row_status_arr_size = 0;
  13294. }
  13295. #endif
  13296. }
  13297. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300)
  13298. void alloc_row_status(const int array_size) {
  13299. if (row_status == nullptr) {
  13300. row_status = new OTL_SQLUSMALLINT[OTL_SCAST(size_t,array_size)];
  13301. row_status_arr_size = array_size;
  13302. memset(row_status, 0, sizeof(OTL_SQLUSMALLINT) * OTL_SCAST(size_t,array_size));
  13303. } else if (row_status != nullptr && array_size != row_status_arr_size) {
  13304. delete[] row_status;
  13305. row_status = new OTL_SQLUSMALLINT[OTL_SCAST(size_t,array_size)];
  13306. row_status_arr_size = array_size;
  13307. memset(row_status, 0, sizeof(OTL_SQLUSMALLINT) * OTL_SCAST(size_t,array_size));
  13308. }
  13309. }
  13310. #endif
  13311. void set_select_type(const int atype) {
  13312. implicit_cursor = atype;
  13313. }
  13314. void init(const int /* array_size */) {}
  13315. void set_prefetch_size(const int aprefetch_array_size) {
  13316. prefetch_array_size = aprefetch_array_size;
  13317. }
  13318. OTL_NODISCARD int first(otl_cur &cur, int &cur_row, int &cur_size, int &row_count,
  13319. int &eof_data, const int
  13320. #if !defined(OTL_ODBC_XTG_IBASE6)
  13321. array_size
  13322. #endif
  13323. ) {
  13324. #if defined(OTL_ODBC_XTG_IBASE6)
  13325. cur_row = -1;
  13326. eof_data = 0;
  13327. if (implicit_cursor == otl_explicit_select) {
  13328. status = SQLExecute(cur.cda);
  13329. if (cur.canceled)
  13330. return 0;
  13331. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  13332. if (cur.adb && cur.adb->throws_on_sql_success_with_info &&
  13333. status == SQL_SUCCESS_WITH_INFO)
  13334. return 0;
  13335. #endif
  13336. #if (ODBCVER >= 0x0300) && defined(OTL_DB2_CLI)
  13337. if (status == SQL_NO_DATA) {
  13338. status = SQL_SUCCESS;
  13339. cur.status = SQL_SUCCESS;
  13340. }
  13341. #endif
  13342. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13343. return 0;
  13344. }
  13345. crow = 0;
  13346. status = SQLFetch(cur.cda);
  13347. if (cur.canceled)
  13348. return 0;
  13349. if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) {
  13350. crow = 1;
  13351. in_sequence = 1;
  13352. }
  13353. #else
  13354. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13355. alloc_row_status(array_size);
  13356. #endif
  13357. cur_row = -1;
  13358. eof_data = 0;
  13359. #if (ODBCVER >= 0x0300)
  13360. status = SQLSetStmtAttr(cur.cda, SQL_ATTR_ROW_ARRAY_SIZE,
  13361. OTL_RCAST(void *, OTL_SCAST(size_t, array_size)),
  13362. SQL_NTS);
  13363. #else
  13364. #if defined(OTL_ODBC_TIMESTEN)
  13365. status = SQLSetStmtOption(cur.cda, TT_PREFETCH_COUNT, prefetch_array_size);
  13366. #else
  13367. status = SQLSetStmtOption(cur.cda, SQL_ROWSET_SIZE, OTL_SCAST(size_t,array_size));
  13368. #endif
  13369. #endif
  13370. if (cur.canceled)
  13371. return 0;
  13372. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13373. return 0;
  13374. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13375. #if (ODBCVER >= 0x0300)
  13376. if (use_fetch_scroll_) {
  13377. status =
  13378. SQLSetStmtAttr(cur.cda, SQL_ATTR_ROWS_FETCHED_PTR, &crow, SQL_NTS);
  13379. if (cur.canceled)
  13380. return 0;
  13381. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13382. return 0;
  13383. }
  13384. #endif
  13385. #else
  13386. #if (ODBCVER >= 0x0300)
  13387. status = SQLSetStmtAttr(cur.cda, SQL_ATTR_ROWS_FETCHED_PTR, &crow, SQL_NTS);
  13388. if (cur.canceled)
  13389. return 0;
  13390. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13391. return 0;
  13392. #else
  13393. #endif
  13394. #endif
  13395. if (implicit_cursor == otl_explicit_select) {
  13396. status = SQLExecute(cur.cda);
  13397. if (cur.canceled)
  13398. return 0;
  13399. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  13400. if (cur.adb && cur.adb->throws_on_sql_success_with_info &&
  13401. status == SQL_SUCCESS_WITH_INFO)
  13402. return 0;
  13403. #endif
  13404. #if (ODBCVER >= 0x0300) && defined(OTL_DB2_CLI)
  13405. if (status == SQL_NO_DATA) {
  13406. status = SQL_SUCCESS;
  13407. cur.status = SQL_SUCCESS;
  13408. }
  13409. #endif
  13410. if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  13411. return 0;
  13412. }
  13413. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13414. if (array_size == 1) {
  13415. crow = 0;
  13416. status = SQLFetch(cur.cda);
  13417. if (cur.canceled)
  13418. return 0;
  13419. if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) {
  13420. crow = 1;
  13421. in_sequence = 1;
  13422. }
  13423. } else {
  13424. if (use_fetch_scroll_) {
  13425. #if (ODBCVER >= 0x0300)
  13426. status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1);
  13427. #endif
  13428. } else {
  13429. status =
  13430. SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status);
  13431. }
  13432. }
  13433. #else
  13434. #if (ODBCVER >= 0x0300)
  13435. status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1);
  13436. #else
  13437. {
  13438. alloc_row_status(array_size);
  13439. status = SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status);
  13440. }
  13441. #endif
  13442. #endif
  13443. #endif
  13444. in_sequence = 1;
  13445. if (cur.canceled)
  13446. return 0;
  13447. if (status == SQL_ERROR || status == SQL_INVALID_HANDLE)
  13448. return 0;
  13449. if (status == SQL_NO_DATA_FOUND) {
  13450. eof_data = 1;
  13451. cur_row = -1;
  13452. crow = 0;
  13453. row_count = 0;
  13454. cur_size = 0;
  13455. #if defined(OTL_DB2_CLI)
  13456. status = SQLCloseCursor(cur.cda);
  13457. #else
  13458. status = SQLFreeStmt(cur.cda, SQL_CLOSE);
  13459. #endif
  13460. in_sequence = 0;
  13461. if (status == SQL_ERROR)
  13462. return 0;
  13463. return 1;
  13464. }
  13465. row_count = OTL_SCAST(int, crow);
  13466. cur_size = row_count;
  13467. if (cur_size != 0)
  13468. cur_row = 0;
  13469. return 1;
  13470. }
  13471. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13472. int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count,
  13473. int &eof_data, const int array_size) {
  13474. alloc_row_status(array_size);
  13475. #else
  13476. OTL_NODISCARD int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count,
  13477. int &eof_data,
  13478. #if (ODBCVER >= 0x0300)
  13479. const int /* array_size */)
  13480. #else
  13481. const int array_size)
  13482. #endif
  13483. {
  13484. #endif
  13485. if (cur_row < cur_size - 1) {
  13486. ++cur_row;
  13487. return 1;
  13488. } else {
  13489. if (eof_data) {
  13490. cur_row = -1;
  13491. cur_size = 0;
  13492. in_sequence = 0;
  13493. #if defined(OTL_DB2_CLI)
  13494. status = SQLCloseCursor(cur.cda);
  13495. #else
  13496. status = SQLFreeStmt(cur.cda, SQL_CLOSE);
  13497. #endif
  13498. if (status == SQL_ERROR)
  13499. return 0;
  13500. return 1;
  13501. }
  13502. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13503. if (array_size == 1) {
  13504. crow = 0;
  13505. status = SQLFetch(cur.cda);
  13506. if (cur.canceled)
  13507. return 0;
  13508. if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) {
  13509. crow = 1;
  13510. in_sequence = 1;
  13511. }
  13512. } else {
  13513. if (use_fetch_scroll_) {
  13514. #if (ODBCVER >= 0x0300)
  13515. status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1);
  13516. #endif
  13517. } else {
  13518. status =
  13519. SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status);
  13520. }
  13521. }
  13522. #else
  13523. #if (ODBCVER >= 0x0300)
  13524. status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1);
  13525. #else
  13526. {
  13527. alloc_row_status(array_size);
  13528. status =
  13529. SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status);
  13530. }
  13531. #endif
  13532. #endif
  13533. in_sequence = 1;
  13534. if (cur.canceled)
  13535. return 0;
  13536. if (status == SQL_ERROR ||
  13537. // status==SQL_SUCCESS_WITH_INFO||
  13538. status == SQL_INVALID_HANDLE)
  13539. return 0;
  13540. if (status == SQL_NO_DATA_FOUND) {
  13541. eof_data = 1;
  13542. cur_row = -1;
  13543. cur_size = 0;
  13544. in_sequence = 0;
  13545. #if defined(OTL_DB2_CLI)
  13546. status = SQLCloseCursor(cur.cda);
  13547. #else
  13548. status = SQLFreeStmt(cur.cda, SQL_CLOSE);
  13549. #endif
  13550. if (status == SQL_ERROR)
  13551. return 0;
  13552. return 1;
  13553. }
  13554. cur_size = OTL_SCAST(int, crow);
  13555. row_count += OTL_SCAST(int, crow);
  13556. if (cur_size != 0)
  13557. cur_row = 0;
  13558. return 1;
  13559. }
  13560. }
  13561. private:
  13562. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  13563. public:
  13564. otl_sel(const otl_sel &) = delete;
  13565. otl_sel &operator=(const otl_sel &) = delete;
  13566. private:
  13567. #else
  13568. otl_sel(const otl_sel &)
  13569. :
  13570. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)
  13571. use_fetch_scroll_(false),
  13572. #endif
  13573. implicit_cursor(0), status(0), prefetch_array_size(0), crow(0),
  13574. in_sequence(0)
  13575. #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300)
  13576. ,
  13577. row_status(nullptr), row_status_arr_size(0)
  13578. #endif
  13579. {
  13580. }
  13581. otl_sel &operator=(const otl_sel &) { return *this; }
  13582. #endif
  13583. };
  13584. typedef otl_tmpl_connect<otl_exc, otl_conn, otl_cur> otl_odbc_connect;
  13585. typedef otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> otl_cursor;
  13586. typedef otl_tmpl_exception<otl_exc, otl_conn, otl_cur> otl_exception;
  13587. typedef otl_tmpl_select_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_sel,
  13588. otl_time> otl_select_stream;
  13589. typedef otl_tmpl_inout_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_time>
  13590. otl_inout_stream;
  13591. class otl_stream;
  13592. class otl_connect : public otl_odbc_connect {
  13593. public:
  13594. void set_connection_mode(const int connection_mode) {
  13595. connect_struct.connection_type = connection_mode;
  13596. }
  13597. #if defined(OTL_DB2_CLI)
  13598. void set_prog_name(const char *prog_name) {
  13599. retcode = connect_struct.set_prog_name(prog_name);
  13600. if (!retcode) {
  13601. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  13602. OTL_THROW((otl_exception(connect_struct)));
  13603. }
  13604. }
  13605. #endif
  13606. int get_connection_mode(void) { return connect_struct.connection_type; }
  13607. protected:
  13608. friend class otl_stream;
  13609. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13610. defined(OTL_UNICODE_STRING_TYPE)) && \
  13611. defined(OTL_STREAM_POOLING_ON)
  13612. otl_stream_pool sc;
  13613. bool pool_enabled_;
  13614. #endif
  13615. public:
  13616. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13617. defined(OTL_UNICODE_STRING_TYPE)) && \
  13618. defined(OTL_STREAM_POOLING_ON)
  13619. void set_stream_pool_size(const int max_size = otl_max_default_pool_size) {
  13620. sc.init(max_size);
  13621. }
  13622. void stream_pool_enable() { pool_enabled_ = true; }
  13623. void stream_pool_disable() { pool_enabled_ = false; }
  13624. bool get_stream_pool_enabled_flag() const { return pool_enabled_; }
  13625. #endif
  13626. void commit(void) {
  13627. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13628. if (!auto_commit_) {
  13629. (*this) << "commit tran";
  13630. otl_odbc_connect::commit();
  13631. (*this) << "begin tran";
  13632. }
  13633. #else
  13634. otl_odbc_connect::commit();
  13635. #endif
  13636. }
  13637. void rollback(void) {
  13638. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13639. if (!auto_commit_) {
  13640. (*this) << "rollback tran";
  13641. otl_odbc_connect::rollback();
  13642. (*this) << "begin tran";
  13643. }
  13644. #else
  13645. otl_odbc_connect::rollback();
  13646. #endif
  13647. }
  13648. long direct_exec(const char *sqlstm,
  13649. const int exception_enabled = 1) OTL_THROWS_OTL_EXCEPTION {
  13650. return otl_cursor::direct_exec(*this, sqlstm, exception_enabled);
  13651. }
  13652. void syntax_check(const char *sqlstm) OTL_THROWS_OTL_EXCEPTION {
  13653. otl_cursor::syntax_check(*this, sqlstm);
  13654. }
  13655. otl_connect() OTL_NO_THROW : otl_odbc_connect(),
  13656. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13657. defined(OTL_UNICODE_STRING_TYPE)) && \
  13658. defined(OTL_STREAM_POOLING_ON)
  13659. sc(),
  13660. pool_enabled_(true),
  13661. #endif
  13662. cmd_(nullptr)
  13663. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13664. ,
  13665. auto_commit_(false)
  13666. #endif
  13667. {
  13668. }
  13669. otl_connect(const char *connect_str, const int aauto_commit = 0)
  13670. OTL_THROWS_OTL_EXCEPTION:
  13671. otl_odbc_connect(connect_str, aauto_commit),
  13672. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13673. defined(OTL_UNICODE_STRING_TYPE)) && \
  13674. defined(OTL_STREAM_POOLING_ON)
  13675. sc(), pool_enabled_(true),
  13676. #endif
  13677. cmd_(nullptr)
  13678. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13679. ,
  13680. auto_commit_(false)
  13681. #endif
  13682. {
  13683. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13684. if (aauto_commit)
  13685. auto_commit_ = true;
  13686. else
  13687. auto_commit_ = false;
  13688. #endif
  13689. }
  13690. otl_connect(OTL_HENV ahenv, OTL_HDBC ahdbc, const int auto_commit = 0)
  13691. OTL_THROWS_OTL_EXCEPTION:
  13692. otl_odbc_connect(),
  13693. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13694. defined(OTL_UNICODE_STRING_TYPE)) && \
  13695. defined(OTL_STREAM_POOLING_ON)
  13696. sc(), pool_enabled_(true),
  13697. #endif
  13698. cmd_(nullptr)
  13699. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13700. ,
  13701. auto_commit_(false)
  13702. #endif
  13703. {
  13704. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13705. if (auto_commit)
  13706. auto_commit_ = true;
  13707. else
  13708. auto_commit_ = false;
  13709. #endif
  13710. rlogon(ahenv, ahdbc, auto_commit);
  13711. }
  13712. OTL_NODISCARD const char *getCmd(void) const { return cmd_; }
  13713. otl_connect &operator<<(const char *cmd) {
  13714. if (!connected) {
  13715. this->rlogon(cmd);
  13716. } else {
  13717. otl_cursor::direct_exec(*this, cmd);
  13718. }
  13719. return *this;
  13720. }
  13721. otl_connect &operator<<=(const char *cmd) {
  13722. if (cmd_) {
  13723. delete[] cmd_;
  13724. cmd_ = nullptr;
  13725. }
  13726. size_t cmd_len = strlen(cmd);
  13727. cmd_ = new char[cmd_len + 1];
  13728. OTL_STRCPY_S(cmd_, cmd_len + 1, cmd);
  13729. return *this;
  13730. }
  13731. #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO)
  13732. void set_throw_on_sql_success_with_info(const bool throw_flag = false) {
  13733. this->get_connect_struct().throws_on_sql_success_with_info = throw_flag;
  13734. }
  13735. #endif
  13736. void rlogon(OTL_HENV ahenv, OTL_HDBC ahdbc,
  13737. const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION {
  13738. if (this->connected) {
  13739. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  13740. }
  13741. if (cmd_) {
  13742. delete[] cmd_;
  13743. cmd_ = nullptr;
  13744. }
  13745. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13746. if (auto_commit)
  13747. auto_commit_ = true;
  13748. else
  13749. auto_commit_ = false;
  13750. #endif
  13751. retcode = connect_struct.ext_logon(ahenv, ahdbc, auto_commit);
  13752. if (retcode)
  13753. connected = 1;
  13754. else {
  13755. connected = 0;
  13756. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  13757. OTL_THROW((otl_exception(connect_struct)));
  13758. }
  13759. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13760. if (!auto_commit_) {
  13761. (*this) << "begin tran";
  13762. }
  13763. #endif
  13764. }
  13765. #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON)
  13766. void rlogon(const OTL_UNICODE_CHAR_TYPE *username,
  13767. const OTL_UNICODE_CHAR_TYPE *passwd,
  13768. const OTL_UNICODE_CHAR_TYPE *dns,
  13769. const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION {
  13770. if (this->connected) {
  13771. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  13772. }
  13773. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13774. if (auto_commit)
  13775. auto_commit_ = true;
  13776. else
  13777. auto_commit_ = false;
  13778. #endif
  13779. retcode =
  13780. connect_struct.rlogon(OTL_RCAST(const SQLWCHAR *, username),
  13781. OTL_RCAST(const SQLWCHAR *, passwd),
  13782. OTL_RCAST(const SQLWCHAR *, dns), auto_commit);
  13783. if (retcode)
  13784. connected = 1;
  13785. else {
  13786. connected = 0;
  13787. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  13788. OTL_THROW((otl_exception(connect_struct)));
  13789. }
  13790. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13791. if (!auto_commit_) {
  13792. (*this) << "begin tran";
  13793. }
  13794. #endif
  13795. }
  13796. #endif
  13797. void rlogon(const char *username,
  13798. const char *passwd,
  13799. const char *dns,
  13800. const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION {
  13801. if (this->connected) {
  13802. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  13803. }
  13804. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13805. if (auto_commit)
  13806. auto_commit_ = true;
  13807. else
  13808. auto_commit_ = false;
  13809. #endif
  13810. retcode = connect_struct.rlogon(username, passwd, dns, auto_commit);
  13811. if (retcode)
  13812. connected = 1;
  13813. else {
  13814. connected = 0;
  13815. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  13816. OTL_THROW((otl_exception(connect_struct)));
  13817. }
  13818. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13819. if (!auto_commit_) {
  13820. (*this) << "begin tran";
  13821. }
  13822. #endif
  13823. }
  13824. virtual ~otl_connect()
  13825. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  13826. OTL_THROWS_OTL_EXCEPTION
  13827. #else
  13828. OTL_NO_THROW
  13829. #endif
  13830. {
  13831. if (cmd_) {
  13832. delete[] cmd_;
  13833. cmd_ = nullptr;
  13834. }
  13835. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  13836. try {
  13837. #endif
  13838. logoff();
  13839. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  13840. }
  13841. catch (OTL_CONST_EXCEPTION otl_exception &) {
  13842. }
  13843. #endif
  13844. }
  13845. void rlogon(const char *connect_str,
  13846. const int aauto_commit = 0) OTL_THROWS_OTL_EXCEPTION {
  13847. if (this->connected) {
  13848. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  13849. }
  13850. if (cmd_) {
  13851. delete[] cmd_;
  13852. cmd_ = nullptr;
  13853. }
  13854. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13855. if (aauto_commit)
  13856. auto_commit_ = true;
  13857. else
  13858. auto_commit_ = false;
  13859. #endif
  13860. otl_odbc_connect::rlogon(connect_str, aauto_commit);
  13861. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13862. if (!auto_commit_) {
  13863. (*this) << "begin tran";
  13864. }
  13865. #endif
  13866. }
  13867. void logoff(void) OTL_THROWS_OTL_EXCEPTION {
  13868. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  13869. defined(OTL_STREAM_POOLING_ON)
  13870. if (connected)
  13871. sc.init(sc.get_max_size());
  13872. #endif
  13873. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13874. if (!auto_commit_)
  13875. rollback();
  13876. #endif
  13877. #if defined(OTL_ROLLS_BACK_BEFORE_LOGOFF)
  13878. otl_odbc_connect::rollback();
  13879. #endif
  13880. otl_odbc_connect::logoff();
  13881. }
  13882. void set_transaction_isolation_level(const long int level)
  13883. OTL_THROWS_OTL_EXCEPTION {
  13884. retcode = connect_struct.set_transaction_isolation_level(level);
  13885. if (!retcode) {
  13886. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  13887. OTL_THROW((otl_exception(connect_struct)));
  13888. }
  13889. }
  13890. private:
  13891. char *cmd_;
  13892. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13893. bool auto_commit_;
  13894. #endif
  13895. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  13896. public:
  13897. otl_connect(const otl_connect &) = delete;
  13898. otl_connect &operator=(const otl_connect &) = delete;
  13899. private:
  13900. #else
  13901. otl_connect(const otl_connect &) OTL_NO_THROW : otl_odbc_connect(),
  13902. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13903. defined(OTL_UNICODE_STRING_TYPE)) && \
  13904. defined(OTL_STREAM_POOLING_ON)
  13905. sc(),
  13906. pool_enabled_(true),
  13907. #endif
  13908. cmd_(nullptr)
  13909. #if defined(OTL_FREETDS_ODBC_WORKAROUNDS)
  13910. ,
  13911. auto_commit_(false)
  13912. #endif
  13913. {
  13914. }
  13915. otl_connect &operator=(const otl_connect &) { return *this; }
  13916. #endif
  13917. };
  13918. const int otl_odbc_no_stream = 0;
  13919. const int otl_odbc_io_stream = 1;
  13920. const int otl_odbc_select_stream = 2;
  13921. class otl_stream_shell : public otl_stream_shell_generic {
  13922. public:
  13923. otl_select_stream *ss;
  13924. otl_inout_stream *io;
  13925. otl_connect *adb;
  13926. int auto_commit_flag;
  13927. otl_var_desc *iov;
  13928. int iov_len;
  13929. int next_iov_ndx;
  13930. otl_var_desc *ov;
  13931. int ov_len;
  13932. int next_ov_ndx;
  13933. bool flush_flag;
  13934. int stream_type;
  13935. bool lob_stream_flag;
  13936. otl_select_struct_override override_;
  13937. #if (defined(OTL_STL) || defined(OTL_ACE)) && defined(OTL_STREAM_POOLING_ON)
  13938. OTL_STRING_CONTAINER orig_sql_stm;
  13939. #endif
  13940. #if defined(OTL_UNICODE_STRING_TYPE) && defined(OTL_STREAM_POOLING_ON)
  13941. std::string orig_sql_stm;
  13942. #endif
  13943. otl_stream_shell()
  13944. : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr),
  13945. auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0),
  13946. ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false),
  13947. stream_type(otl_odbc_no_stream), lob_stream_flag(0), override_()
  13948. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13949. defined(OTL_UNICODE_STRING_TYPE)) && \
  13950. defined(OTL_STREAM_POOLING_ON)
  13951. ,
  13952. orig_sql_stm()
  13953. #endif
  13954. {
  13955. should_delete = 0;
  13956. }
  13957. otl_stream_shell(const int ashould_delete)
  13958. : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr),
  13959. auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0),
  13960. ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(true),
  13961. stream_type(otl_odbc_no_stream), lob_stream_flag(false), override_()
  13962. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  13963. defined(OTL_UNICODE_STRING_TYPE)) && \
  13964. defined(OTL_STREAM_POOLING_ON)
  13965. ,
  13966. orig_sql_stm()
  13967. #endif
  13968. {
  13969. should_delete = ashould_delete;
  13970. }
  13971. virtual ~otl_stream_shell() OTL_THROWS_OTL_EXCEPTION {
  13972. if (should_delete) {
  13973. delete[] iov;
  13974. delete[] ov;
  13975. iov = nullptr;
  13976. iov_len = 0;
  13977. ov = nullptr;
  13978. ov_len = 0;
  13979. next_iov_ndx = 0;
  13980. next_ov_ndx = 0;
  13981. override_.setLen(0);
  13982. flush_flag = true;
  13983. delete ss;
  13984. delete io;
  13985. ss = nullptr;
  13986. io = nullptr;
  13987. adb = nullptr;
  13988. }
  13989. }
  13990. private:
  13991. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  13992. public:
  13993. otl_stream_shell(const otl_stream_shell &) = delete;
  13994. otl_stream_shell &operator=(const otl_stream_shell &) = delete;
  13995. private:
  13996. #else
  13997. otl_stream_shell(const otl_stream_shell &)
  13998. : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr),
  13999. auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0),
  14000. ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false),
  14001. stream_type(otl_odbc_no_stream), lob_stream_flag(0), override_()
  14002. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  14003. defined(OTL_UNICODE_STRING_TYPE)) && \
  14004. defined(OTL_STREAM_POOLING_ON)
  14005. ,
  14006. orig_sql_stm()
  14007. #endif
  14008. {
  14009. should_delete = 0;
  14010. }
  14011. otl_stream_shell &operator=(const otl_stream_shell &) { return *this; }
  14012. #endif
  14013. };
  14014. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  14015. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
  14016. class otl_tmpl_lob_stream : public otl_lob_stream_generic {
  14017. public:
  14018. typedef otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
  14019. otl_exception;
  14020. typedef otl_tmpl_variable<TVariableStruct> *p_bind_var;
  14021. typedef otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct> *
  14022. p_connect;
  14023. typedef otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct,
  14024. TVariableStruct> *p_cursor;
  14025. private:
  14026. p_bind_var bind_var;
  14027. p_connect connect;
  14028. p_cursor cursor;
  14029. otl_long_string *temp_buf;
  14030. char *temp_char_buf;
  14031. bool written_to_flag;
  14032. bool closed_flag;
  14033. int last_read_lob_len;
  14034. public:
  14035. void reset_last_read_lob_len() { last_read_lob_len = 0; }
  14036. void init(void *avar, void *aconnect, void *acursor, int andx, int amode,
  14037. const int alob_is_null = 0) OTL_THROWS_OTL_EXCEPTION {
  14038. closed_flag = false;
  14039. if (written_to_flag) {
  14040. retcode =
  14041. bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct());
  14042. written_to_flag = false;
  14043. if (!retcode) {
  14044. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  14045. OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(),
  14046. cursor->get_stm_label()
  14047. ? cursor->get_stm_label()
  14048. : cursor->get_stm_text())));
  14049. }
  14050. }
  14051. connect = OTL_RCAST(p_connect, aconnect);
  14052. bind_var = OTL_RCAST(p_bind_var, avar);
  14053. cursor = OTL_RCAST(p_cursor, acursor);
  14054. mode = amode;
  14055. retcode = 0;
  14056. lob_is_null = alob_is_null;
  14057. ndx = andx;
  14058. offset = 0;
  14059. lob_len = 0;
  14060. eof_flag = 0;
  14061. in_destructor = 0;
  14062. if (bind_var) {
  14063. bind_var->get_var_struct().set_lob_stream_flag();
  14064. bind_var->get_var_struct().reset_lob_len();
  14065. }
  14066. }
  14067. void set_len(void) OTL_NO_THROW {}
  14068. void set_len(const int /*new_len*/) OTL_NO_THROW {}
  14069. otl_tmpl_lob_stream() OTL_THROWS_OTL_EXCEPTION : otl_lob_stream_generic(false),
  14070. bind_var(nullptr),
  14071. connect(nullptr),
  14072. cursor(nullptr),
  14073. temp_buf(nullptr),
  14074. temp_char_buf(nullptr),
  14075. written_to_flag(false),
  14076. closed_flag(false),
  14077. last_read_lob_len(0) {
  14078. init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode));
  14079. }
  14080. ~otl_tmpl_lob_stream()
  14081. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  14082. OTL_THROWS_OTL_EXCEPTION
  14083. #else
  14084. OTL_NO_THROW
  14085. #endif
  14086. {
  14087. in_destructor = 1;
  14088. if (temp_buf) {
  14089. delete temp_buf;
  14090. temp_buf = nullptr;
  14091. }
  14092. if (temp_char_buf) {
  14093. delete[] temp_char_buf;
  14094. temp_char_buf = nullptr;
  14095. }
  14096. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  14097. try {
  14098. if (!closed_flag)
  14099. close();
  14100. }
  14101. catch (OTL_CONST_EXCEPTION otl_exception &) {
  14102. }
  14103. #else
  14104. if (!closed_flag)
  14105. close();
  14106. #endif
  14107. }
  14108. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  14109. otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s)
  14110. OTL_THROWS_OTL_EXCEPTION {
  14111. otl_long_string temp_s(s.data(), OTL_SCAST(int, s.length()),
  14112. OTL_SCAST(int, s.length()));
  14113. (*this) << temp_s;
  14114. return *this;
  14115. }
  14116. #endif
  14117. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  14118. defined(OTL_USER_DEFINED_STRING_CLASS_ON)) && \
  14119. !defined(OTL_UNICODE)
  14120. otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s)
  14121. OTL_THROWS_OTL_EXCEPTION {
  14122. otl_long_string temp_s(s.c_str(), OTL_SCAST(int, s.length()),
  14123. OTL_SCAST(int, s.length()));
  14124. (*this) << temp_s;
  14125. return *this;
  14126. }
  14127. void setStringBuffer(const int chunk_size) {
  14128. delete[] temp_char_buf;
  14129. temp_char_buf = nullptr;
  14130. delete temp_buf;
  14131. temp_buf = nullptr;
  14132. temp_char_buf = new char[OTL_SCAST(size_t,chunk_size + 1)];
  14133. temp_buf = new otl_long_string(temp_char_buf, chunk_size);
  14134. }
  14135. otl_lob_stream_generic &
  14136. operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION {
  14137. const int TEMP_BUF_SIZE = 4096;
  14138. if (!temp_char_buf)
  14139. temp_char_buf = new char[TEMP_BUF_SIZE];
  14140. if (!temp_buf)
  14141. temp_buf = new otl_long_string(temp_char_buf, TEMP_BUF_SIZE - 1);
  14142. int iters = 0;
  14143. while (!this->eof()) {
  14144. ++iters;
  14145. (*this) >> (*temp_buf);
  14146. temp_char_buf[temp_buf->len()] = 0;
  14147. if (iters > 1)
  14148. s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()));
  14149. else
  14150. #if (defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL)) && \
  14151. !defined(OTL_ACE)
  14152. s.assign(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()));
  14153. #elif defined(OTL_ACE)
  14154. s.set(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()), 1);
  14155. #endif
  14156. }
  14157. return *this;
  14158. }
  14159. #endif
  14160. otl_lob_stream_generic &operator<<(const otl_long_string &s)
  14161. OTL_THROWS_OTL_EXCEPTION {
  14162. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  14163. if (bind_var && bind_var->get_ftype() == otl_var_raw_long)
  14164. in_unicode_mode = false;
  14165. if (s.get_unicode_flag() != in_unicode_mode) {
  14166. OTL_THROW((OTL_TMPL_EXCEPTION(
  14167. otl_error_msg_37, otl_error_code_37,
  14168. "otl_lob_stream_generic::operator<<(const otl_long_string&)")));
  14169. }
  14170. if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) {
  14171. const char *stm = nullptr;
  14172. char var_info[256];
  14173. var_info[0] = 0;
  14174. if (cursor != nullptr) {
  14175. if (cursor->get_stm_label())
  14176. stm = cursor->get_stm_label();
  14177. else
  14178. stm = cursor->get_stm_text();
  14179. }
  14180. if (bind_var != nullptr) {
  14181. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  14182. otl_var_long_string, var_info, sizeof(var_info));
  14183. }
  14184. char *vinfo = nullptr;
  14185. if (var_info[0] != 0)
  14186. vinfo = &var_info[0];
  14187. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  14188. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>(
  14189. otl_error_msg_9, otl_error_code_9, stm, vinfo)));
  14190. }
  14191. if (offset == 0)
  14192. offset = 1;
  14193. if (bind_var != nullptr)
  14194. retcode = bind_var->get_var_struct().write_blob(
  14195. s, lob_len, offset, cursor->get_cursor_struct());
  14196. written_to_flag = true;
  14197. if (retcode)
  14198. return *this;
  14199. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  14200. OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(),
  14201. cursor->get_stm_label() ? cursor->get_stm_label()
  14202. : cursor->get_stm_text())));
  14203. }
  14204. otl_lob_stream_generic &
  14205. operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION {
  14206. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  14207. if (bind_var && bind_var->get_ftype() == otl_var_raw_long)
  14208. in_unicode_mode = false;
  14209. if (s.get_unicode_flag() != in_unicode_mode) {
  14210. OTL_THROW((OTL_TMPL_EXCEPTION(
  14211. otl_error_msg_37, otl_error_code_37,
  14212. "otl_lob_stream_generic::operator>>(otl_long_string&)")));
  14213. }
  14214. if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  14215. const char *stm = nullptr;
  14216. char var_info[256];
  14217. var_info[0] = 0;
  14218. if (cursor != nullptr) {
  14219. if (cursor->get_stm_label())
  14220. stm = cursor->get_stm_label();
  14221. else
  14222. stm = cursor->get_stm_text();
  14223. }
  14224. if (bind_var != nullptr) {
  14225. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  14226. otl_var_long_string, var_info, sizeof(var_info));
  14227. }
  14228. char *vinfo = nullptr;
  14229. if (var_info[0] != 0)
  14230. vinfo = &var_info[0];
  14231. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  14232. OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_10, otl_error_code_10, stm, vinfo)));
  14233. }
  14234. if (offset == 0)
  14235. offset = 1;
  14236. if (bind_var != nullptr)
  14237. retcode = bind_var->get_var_struct().read_blob(
  14238. cursor->get_cursor_struct(), s, ndx, offset, eof_flag);
  14239. if (retcode)
  14240. (void)len();
  14241. if (retcode) {
  14242. if (eof())
  14243. close();
  14244. return *this;
  14245. }
  14246. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  14247. OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(),
  14248. cursor->get_stm_label() ? cursor->get_stm_label()
  14249. : cursor->get_stm_text())));
  14250. }
  14251. OTL_NODISCARD int eof(void) OTL_NO_THROW {
  14252. if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode))
  14253. return 1;
  14254. if (lob_is_null)
  14255. return 1;
  14256. return eof_flag;
  14257. }
  14258. OTL_NODISCARD int len(void) OTL_THROWS_OTL_EXCEPTION {
  14259. if (last_read_lob_len > 0)
  14260. return last_read_lob_len;
  14261. if (cursor == nullptr || connect == nullptr || bind_var == nullptr ||
  14262. lob_is_null)
  14263. return 0;
  14264. int alen;
  14265. retcode = bind_var->get_var_struct().get_blob_len(ndx, alen);
  14266. if (retcode) {
  14267. last_read_lob_len = alen;
  14268. return alen;
  14269. }
  14270. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  14271. OTL_THROW((OTL_TMPL_EXCEPTION(connect->get_connect_struct(),
  14272. cursor->get_stm_label() ? cursor->get_stm_label()
  14273. : cursor->get_stm_text())));
  14274. }
  14275. OTL_NODISCARD bool is_initialized(void) OTL_THROWS_OTL_EXCEPTION {
  14276. if (cursor == nullptr || connect == nullptr || bind_var == nullptr ||
  14277. lob_is_null)
  14278. return false;
  14279. else
  14280. return true;
  14281. }
  14282. void close(bool = false) OTL_THROWS_OTL_EXCEPTION {
  14283. if (in_destructor) {
  14284. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  14285. bind_var->get_var_struct().set_lob_stream_flag(0);
  14286. bind_var->set_not_null(0);
  14287. }
  14288. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) {
  14289. retcode =
  14290. bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct());
  14291. closed_flag = true;
  14292. written_to_flag = false;
  14293. if (!retcode) {
  14294. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  14295. OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(),
  14296. cursor->get_stm_label()
  14297. ? cursor->get_stm_label()
  14298. : cursor->get_stm_text())));
  14299. }
  14300. }
  14301. return;
  14302. }
  14303. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode))
  14304. return;
  14305. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  14306. bind_var->get_var_struct().set_lob_stream_flag(0);
  14307. bind_var->set_not_null(0);
  14308. init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode));
  14309. } else {
  14310. // write mode
  14311. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) {
  14312. retcode =
  14313. bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct());
  14314. written_to_flag = false;
  14315. closed_flag = true;
  14316. if (!retcode) {
  14317. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  14318. OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(),
  14319. cursor->get_stm_label()
  14320. ? cursor->get_stm_label()
  14321. : cursor->get_stm_text())));
  14322. }
  14323. }
  14324. bind_var->get_var_struct().set_lob_stream_flag(0);
  14325. bind_var->set_not_null(0);
  14326. }
  14327. }
  14328. private:
  14329. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  14330. public:
  14331. otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) = delete;
  14332. otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) = delete;
  14333. private:
  14334. #else
  14335. otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) OTL_NO_THROW
  14336. : otl_lob_stream_generic(false),
  14337. bind_var(nullptr),
  14338. connect(nullptr),
  14339. cursor(nullptr),
  14340. temp_buf(nullptr),
  14341. temp_char_buf(nullptr),
  14342. written_to_flag(false),
  14343. closed_flag(false),
  14344. last_read_lob_len(0) {}
  14345. otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) { return *this; }
  14346. #endif
  14347. };
  14348. typedef otl_tmpl_lob_stream<otl_exc, otl_conn, otl_cur, otl_var> otl_lob_stream;
  14349. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  14350. class otl_stream;
  14351. class otl_for_range_loop_odbc_stream_adapter{
  14352. public:
  14353. otl_for_range_loop_odbc_stream_adapter(): str_(nullptr){}
  14354. otl_for_range_loop_odbc_stream_adapter(otl_stream& str): str_(&str){}
  14355. otl_stream& operator*(){
  14356. return *str_;
  14357. }
  14358. otl_for_range_loop_odbc_stream_adapter& operator++(){
  14359. return *this;
  14360. }
  14361. otl_stream* str_;
  14362. };
  14363. #endif
  14364. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  14365. #include <array>
  14366. #endif
  14367. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  14368. #include <array>
  14369. #endif
  14370. #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL)
  14371. #include <optional>
  14372. #endif
  14373. class otl_stream {
  14374. private:
  14375. otl_stream_shell *shell;
  14376. otl_ptr<otl_stream_shell> shell_pt;
  14377. int connected;
  14378. otl_select_stream **ss;
  14379. otl_inout_stream **io;
  14380. otl_connect **adb;
  14381. int *auto_commit_flag;
  14382. otl_var_desc **iov;
  14383. int *iov_len;
  14384. int *next_iov_ndx;
  14385. otl_var_desc **ov;
  14386. int *ov_len;
  14387. int *next_ov_ndx;
  14388. otl_select_struct_override *override_;
  14389. int end_marker;
  14390. int oper_int_called;
  14391. int last_eof_rc;
  14392. bool last_oper_was_read_op;
  14393. #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED)
  14394. public:
  14395. template<typename...T>
  14396. otl_stream& operator<<(const std::tuple<T...>& t){
  14397. otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::write(*this,t);
  14398. return (*this);
  14399. }
  14400. template<typename...T>
  14401. otl_stream& operator>>(std::tuple<T...>& t){
  14402. otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::read(*this,t);
  14403. return (*this);
  14404. }
  14405. #endif
  14406. #if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON)
  14407. public:
  14408. template<typename...T>
  14409. otl_stream& operator<<(const std::variant<T...>& v){
  14410. bool value_written=false;
  14411. otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
  14412. ::write(*this,v,value_written);
  14413. return (*this);
  14414. }
  14415. template<typename...T>
  14416. otl_stream& operator>>(std::variant<T...>& v){
  14417. bool value_read=false;
  14418. otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
  14419. ::read(*this,v,value_read);
  14420. return (*this);
  14421. }
  14422. #endif
  14423. public:
  14424. #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_CPP_14_ON)
  14425. #if defined(OTL_COMPILER_HAS_STD_OPTIONAL)
  14426. template<OTL_TYPE_NAME TData>
  14427. otl_stream& operator<<(const std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  14428. if(var)
  14429. (*this)<<(*var);
  14430. else
  14431. (*this)<<otl_null();
  14432. return *this;
  14433. }
  14434. template<OTL_TYPE_NAME TData>
  14435. otl_stream& operator>>(std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  14436. if(var){
  14437. (*this)>>(*var);
  14438. if(this->is_null())var=std::optional<TData>();
  14439. }else{
  14440. TData temp_var;
  14441. (*this)>>temp_var;
  14442. if(!this->is_null())var.emplace(std::move(temp_var));
  14443. }
  14444. return *this;
  14445. }
  14446. #else
  14447. template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
  14448. otl_stream& operator<<(const Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  14449. if(var)
  14450. (*this)<<(*var);
  14451. else
  14452. (*this)<<otl_null();
  14453. return *this;
  14454. }
  14455. template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
  14456. otl_stream& operator>>(Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  14457. if(var){
  14458. (*this)>>(*var);
  14459. if(this->is_null())var=Optional<TData>();
  14460. }else{
  14461. TData temp_var;
  14462. (*this)>>temp_var;
  14463. if(!this->is_null())var.emplace(std::move(temp_var));
  14464. }
  14465. return *this;
  14466. }
  14467. #endif
  14468. #endif
  14469. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  14470. OTL_NODISCARD otl_for_range_loop_odbc_stream_adapter begin(){
  14471. if(!eof())
  14472. return otl_for_range_loop_odbc_stream_adapter(*this);
  14473. else
  14474. return otl_for_range_loop_odbc_stream_adapter();
  14475. }
  14476. otl_for_range_loop_odbc_stream_adapter end(){
  14477. return otl_for_range_loop_odbc_stream_adapter();
  14478. }
  14479. OTL_NODISCARD int get_auto_commit_flag() const {
  14480. if (!auto_commit_flag)
  14481. return 0;
  14482. else
  14483. return *auto_commit_flag;
  14484. }
  14485. #endif
  14486. #if defined(OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT)
  14487. OTL_NODISCARD OTL_SQLHSTMT get_stm_handle() { return (*io)->get_cursor_struct().get_cda(); }
  14488. #if defined(_UNICODE) || defined(UNICODE)
  14489. typedef SQLWCHAR sqlchar_type;
  14490. #else
  14491. typedef SQLCHAR sqlchar_type;
  14492. #endif
  14493. OTL_NODISCARD bool get_next_diag_rec(short int &rec_ndx, sqlchar_type *sqlstate_buf,
  14494. sqlchar_type *msg_buf, short int msg_buf_size,
  14495. int &native_err) {
  14496. OTL_SQLINTEGER rc;
  14497. SQLSMALLINT msg_len;
  14498. rc = SQLGetDiagRec(SQL_HANDLE_STMT, get_stm_handle(),
  14499. OTL_SCAST(OTL_SQLSMALLINT, rec_ndx),
  14500. OTL_RCAST(sqlchar_type *, sqlstate_buf),
  14501. OTL_RCAST(OTL_SQLINTEGER_PTR, &native_err),
  14502. OTL_RCAST(sqlchar_type *, msg_buf), msg_buf_size,
  14503. OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len));
  14504. bool result = rc == SQL_NO_DATA || rc < 0;
  14505. msg_buf[msg_len] = 0;
  14506. ++rec_ndx;
  14507. return result;
  14508. }
  14509. #endif
  14510. protected:
  14511. int buf_size_;
  14512. void reset_end_marker(void) {
  14513. last_eof_rc = 0;
  14514. end_marker = -1;
  14515. oper_int_called = 0;
  14516. }
  14517. OTL_NORETURN void throw_end_of_row()
  14518. #if defined(__GNUC__) && (__GNUC__ >= 4)
  14519. __attribute__((noreturn))
  14520. #endif
  14521. {
  14522. OTL_THROW((otl_exception(otl_error_msg_34, otl_error_code_34,
  14523. this->get_stm_text())));
  14524. }
  14525. void inc_next_ov(void) {
  14526. if ((*ov_len) == 0)
  14527. return;
  14528. if ((*next_ov_ndx) < (*ov_len) - 1)
  14529. ++(*next_ov_ndx);
  14530. else
  14531. (*next_ov_ndx) = 0;
  14532. }
  14533. void inc_next_iov(void) {
  14534. if ((*iov_len) == 0)
  14535. return;
  14536. if ((*next_iov_ndx) < (*iov_len) - 1)
  14537. ++(*next_iov_ndx);
  14538. else
  14539. (*next_iov_ndx) = 0;
  14540. }
  14541. public:
  14542. OTL_NODISCARD int get_prefetched_row_count() const {
  14543. if (*ss) {
  14544. return (*ss)->get_prefetched_row_count();
  14545. }
  14546. return 0;
  14547. }
  14548. OTL_NODISCARD bool get_lob_stream_flag() const {
  14549. if (!shell)
  14550. return false;
  14551. else
  14552. return shell->lob_stream_flag;
  14553. }
  14554. OTL_NODISCARD int get_adb_max_long_size() const {
  14555. return this->shell->adb->get_max_long_size();
  14556. }
  14557. void check_end_of_row() {
  14558. if (next_ov_ndx == nullptr || (*next_ov_ndx) != 0)
  14559. throw_end_of_row();
  14560. if (next_iov_ndx == nullptr || (*next_iov_ndx) != 0)
  14561. throw_end_of_row();
  14562. }
  14563. OTL_NODISCARD otl_stream_shell *get_shell() { return shell; }
  14564. OTL_NODISCARD int get_connected() const { return connected; }
  14565. OTL_NODISCARD int get_dirty_buf_len() const {
  14566. switch (shell->stream_type) {
  14567. case otl_odbc_no_stream:
  14568. return 0;
  14569. case otl_odbc_io_stream:
  14570. return (*io)->get_dirty_buf_len();
  14571. case otl_odbc_select_stream:
  14572. return (*ss)->get_select_row_count();
  14573. default:
  14574. return 0;
  14575. }
  14576. }
  14577. OTL_NODISCARD const char *get_stm_text(void) {
  14578. const char *no_stm_text = OTL_NO_STM_TEXT;
  14579. switch (shell->stream_type) {
  14580. case otl_odbc_no_stream:
  14581. return no_stm_text;
  14582. case otl_odbc_io_stream:
  14583. return (*io)->get_stm_label() ? (*io)->get_stm_label()
  14584. : (*io)->get_stm_text();
  14585. case otl_odbc_select_stream:
  14586. return (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  14587. : (*ss)->get_stm_text();
  14588. default:
  14589. return no_stm_text;
  14590. }
  14591. }
  14592. void setBufSize(int buf_size) { buf_size_ = buf_size; }
  14593. OTL_NODISCARD int getBufSize(void) const { return buf_size_; }
  14594. OTL_NODISCARD long get_rpc() OTL_NO_THROW {
  14595. if ((*io)) {
  14596. return (*io)->get_rpc();
  14597. } else if ((*ss)) {
  14598. return (*ss)->get_rfc();
  14599. } else
  14600. return 0;
  14601. }
  14602. void skip_to_end_of_row() {
  14603. if (next_ov_ndx == nullptr)
  14604. return;
  14605. if ((*ov_len) == 0)
  14606. return;
  14607. last_oper_was_read_op = true;
  14608. switch (shell->stream_type) {
  14609. case otl_odbc_no_stream:
  14610. break;
  14611. case otl_odbc_io_stream:
  14612. last_eof_rc = (*io)->eof();
  14613. (*io)->skip_to_end_of_row();
  14614. break;
  14615. case otl_odbc_select_stream:
  14616. last_eof_rc = (*ss)->eof();
  14617. (*ss)->skip_to_end_of_row();
  14618. break;
  14619. }
  14620. *next_ov_ndx = 0;
  14621. }
  14622. void skip_to_next_var() {
  14623. if(next_ov_ndx==nullptr)return;
  14624. if((*ov_len)==0)return;
  14625. last_oper_was_read_op = true;
  14626. switch (shell->stream_type) {
  14627. case otl_odbc_no_stream:
  14628. break;
  14629. case otl_odbc_io_stream:
  14630. last_eof_rc = (*io)->eof();
  14631. (*io)->skip_to_next_var();
  14632. break;
  14633. case otl_odbc_select_stream:
  14634. last_eof_rc = (*ss)->eof();
  14635. (*ss)->skip_to_next_var();
  14636. break;
  14637. }
  14638. if((*next_ov_ndx)<(*ov_len)-1)
  14639. ++(*next_ov_ndx);
  14640. }
  14641. operator int(void) OTL_THROWS_OTL_EXCEPTION {
  14642. if (shell && shell->lob_stream_flag) {
  14643. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  14644. const char *stm_label = nullptr;
  14645. const char *stm_text = nullptr;
  14646. if ((*io)) {
  14647. stm_label = (*io)->get_stm_label();
  14648. stm_text = (*io)->get_stm_text();
  14649. } else if ((*ss)) {
  14650. stm_label = (*ss)->get_stm_label();
  14651. stm_text = (*ss)->get_stm_text();
  14652. }
  14653. OTL_THROW((otl_exception(otl_error_msg_24, otl_error_code_24,
  14654. stm_label ? stm_label : stm_text)));
  14655. }
  14656. if (!last_oper_was_read_op) {
  14657. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  14658. const char *stm_label = nullptr;
  14659. const char *stm_text = nullptr;
  14660. if ((*io)) {
  14661. stm_label = (*io)->get_stm_label();
  14662. stm_text = (*io)->get_stm_text();
  14663. } else if ((*ss)) {
  14664. stm_label = (*ss)->get_stm_label();
  14665. stm_text = (*ss)->get_stm_text();
  14666. }
  14667. OTL_THROW((otl_exception(otl_error_msg_18, otl_error_code_18,
  14668. stm_label ? stm_label : stm_text)));
  14669. }
  14670. if (end_marker == 1)
  14671. return 0;
  14672. int rc = 0;
  14673. int temp_eof = eof();
  14674. if (temp_eof && end_marker == -1 && oper_int_called == 0) {
  14675. end_marker = 1;
  14676. if (last_eof_rc == 1)
  14677. rc = 0;
  14678. else
  14679. rc = 1;
  14680. } else if (!temp_eof && end_marker == -1)
  14681. rc = 1;
  14682. else if (temp_eof && end_marker == -1) {
  14683. end_marker = 0;
  14684. rc = 1;
  14685. } else if (temp_eof && end_marker == 0) {
  14686. end_marker = 1;
  14687. rc = 0;
  14688. }
  14689. if (!oper_int_called)
  14690. oper_int_called = 1;
  14691. return rc;
  14692. }
  14693. void cancel(void) OTL_THROWS_OTL_EXCEPTION {
  14694. if ((*ss)) {
  14695. int status = (*ss)->get_cursor_struct().cancel();
  14696. if (status == 0)
  14697. OTL_THROW((otl_exception((*ss)->get_cursor_struct())));
  14698. } else if ((*io)) {
  14699. int status = (*io)->get_cursor_struct().cancel();
  14700. if (status == 0)
  14701. OTL_THROW((otl_exception((*io)->get_cursor_struct())));
  14702. }
  14703. }
  14704. void create_var_desc(void) {
  14705. int i;
  14706. delete[](*iov);
  14707. delete[](*ov);
  14708. (*iov) = nullptr;
  14709. (*iov_len) = 0;
  14710. (*ov) = nullptr;
  14711. (*ov_len) = 0;
  14712. if ((*ss)) {
  14713. if ((*ss)->get_vl_len() > 0) {
  14714. (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_vl_len())];
  14715. (*iov_len) = (*ss)->get_vl_len();
  14716. for (i = 0; i < (*ss)->get_vl_len(); ++i)
  14717. (*ss)->get_vl()[i]->copy_var_desc((*iov)[i]);
  14718. }
  14719. if ((*ss)->get_sl_len() > 0) {
  14720. (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_sl_len())];
  14721. (*ov_len) = (*ss)->get_sl_len();
  14722. for (i = 0; i < (*ss)->get_sl_len(); ++i) {
  14723. (*ss)->get_sl()[i].copy_var_desc((*ov)[i]);
  14724. if ((*ss)->get_sl_desc() != nullptr){
  14725. (*ov)[i].copy_name((*ss)->get_sl_desc()[i].name);
  14726. (*ov)[i].set_param_type(1);
  14727. }
  14728. }
  14729. }
  14730. } else if ((*io)) {
  14731. int temp_vl_len = (*io)->get_vl_len();
  14732. int temp_iv_len = (*io)->get_iv_len();
  14733. if (temp_vl_len > 0) {
  14734. (*iov) = new otl_var_desc[OTL_SCAST(size_t,temp_vl_len)];
  14735. (*iov_len) = temp_vl_len;
  14736. for (i = 0; i < temp_vl_len; ++i)
  14737. (*io)->get_vl()[i]->copy_var_desc((*iov)[i]);
  14738. }
  14739. if (temp_iv_len > 0) {
  14740. (*ov) = new otl_var_desc[OTL_SCAST(size_t,temp_iv_len)];
  14741. (*ov_len) = temp_iv_len;
  14742. for (i = 0; i < temp_iv_len; ++i)
  14743. (*io)->get_in_vl()[i]->copy_var_desc((*ov)[i]);
  14744. }
  14745. }
  14746. }
  14747. void set_column_type(const int column_ndx, const int col_type,
  14748. const int col_size = 0) OTL_NO_THROW {
  14749. if (shell == nullptr) {
  14750. init_stream();
  14751. shell->flush_flag = true;
  14752. }
  14753. override_->add_override(column_ndx, col_type, col_size);
  14754. }
  14755. void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW {
  14756. if (shell == nullptr) {
  14757. init_stream();
  14758. shell->flush_flag = true;
  14759. }
  14760. override_->set_all_column_types(mask);
  14761. }
  14762. void set_flush(const bool flush_flag = true) OTL_NO_THROW {
  14763. if (shell == nullptr)
  14764. init_stream();
  14765. shell->flush_flag = flush_flag;
  14766. }
  14767. void set_lob_stream_mode(const bool lob_stream_flag = false) OTL_NO_THROW {
  14768. if (shell == nullptr)
  14769. return;
  14770. shell->lob_stream_flag = lob_stream_flag;
  14771. }
  14772. OTL_NODISCARD otl_var_desc *describe_in_vars(int &desc_len) OTL_NO_THROW {
  14773. desc_len = 0;
  14774. if (shell == nullptr)
  14775. return nullptr;
  14776. if (shell->iov == nullptr)
  14777. return nullptr;
  14778. desc_len = shell->iov_len;
  14779. return shell->iov;
  14780. }
  14781. OTL_NODISCARD otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW {
  14782. desc_len = 0;
  14783. if (shell == nullptr)
  14784. return nullptr;
  14785. if (shell->ov == nullptr)
  14786. return nullptr;
  14787. desc_len = shell->ov_len;
  14788. return shell->ov;
  14789. }
  14790. OTL_NODISCARD otl_var_desc *describe_next_in_var(void) OTL_NO_THROW {
  14791. if (shell == nullptr)
  14792. return nullptr;
  14793. if (shell->iov == nullptr)
  14794. return nullptr;
  14795. return &(shell->iov[shell->next_iov_ndx]);
  14796. }
  14797. OTL_NODISCARD otl_var_desc *describe_next_out_var(void) OTL_NO_THROW {
  14798. if (shell == nullptr)
  14799. return nullptr;
  14800. if (shell->ov == nullptr)
  14801. return nullptr;
  14802. return &(shell->ov[shell->next_ov_ndx]);
  14803. }
  14804. void init_stream(void) {
  14805. buf_size_ = 1;
  14806. last_oper_was_read_op = false;
  14807. shell = nullptr;
  14808. shell = new otl_stream_shell(0);
  14809. shell_pt.assign(&shell);
  14810. connected = 0;
  14811. ss = &(shell->ss);
  14812. io = &(shell->io);
  14813. adb = &(shell->adb);
  14814. auto_commit_flag = &(shell->auto_commit_flag);
  14815. iov = &(shell->iov);
  14816. iov_len = &(shell->iov_len);
  14817. next_iov_ndx = &(shell->next_iov_ndx);
  14818. ov = &(shell->ov);
  14819. ov_len = &(shell->ov_len);
  14820. next_ov_ndx = &(shell->next_ov_ndx);
  14821. override_ = &(shell->override_);
  14822. (*io) = nullptr;
  14823. (*ss) = nullptr;
  14824. (*adb) = nullptr;
  14825. (*ov) = nullptr;
  14826. (*ov_len) = 0;
  14827. (*next_iov_ndx) = 0;
  14828. (*next_ov_ndx) = 0;
  14829. (*auto_commit_flag) = 1;
  14830. (*iov) = nullptr;
  14831. (*iov_len) = 0;
  14832. }
  14833. otl_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm,
  14834. otl_connect &db, const int implicit_select = otl_explicit_select,
  14835. const char *sqlstm_label = nullptr)
  14836. OTL_THROWS_OTL_EXCEPTION:
  14837. shell(nullptr), shell_pt(), connected(0), ss(nullptr), io(nullptr),
  14838. adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr),
  14839. next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr),
  14840. override_(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0),
  14841. last_oper_was_read_op(false), buf_size_(0) {
  14842. init_stream();
  14843. (*io) = nullptr;
  14844. (*ss) = nullptr;
  14845. (*iov) = nullptr;
  14846. (*iov_len) = 0;
  14847. (*ov) = nullptr;
  14848. (*ov_len) = 0;
  14849. (*auto_commit_flag) = 1;
  14850. (*next_iov_ndx) = 0;
  14851. (*next_ov_ndx) = 0;
  14852. (*adb) = &db;
  14853. shell->flush_flag = true;
  14854. open(arr_size, sqlstm, db, implicit_select, sqlstm_label);
  14855. }
  14856. otl_stream() OTL_NO_THROW : shell(nullptr),
  14857. shell_pt(),
  14858. connected(0),
  14859. ss(nullptr),
  14860. io(nullptr),
  14861. adb(nullptr),
  14862. auto_commit_flag(nullptr),
  14863. iov(nullptr),
  14864. iov_len(nullptr),
  14865. next_iov_ndx(nullptr),
  14866. ov(nullptr),
  14867. ov_len(nullptr),
  14868. next_ov_ndx(nullptr),
  14869. override_(nullptr),
  14870. end_marker(0),
  14871. oper_int_called(0),
  14872. last_eof_rc(0),
  14873. last_oper_was_read_op(false),
  14874. buf_size_(0) {
  14875. init_stream();
  14876. shell->flush_flag = true;
  14877. }
  14878. virtual ~otl_stream()
  14879. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  14880. OTL_THROWS_OTL_EXCEPTION
  14881. #else
  14882. OTL_NO_THROW
  14883. #endif
  14884. {
  14885. if (!connected)
  14886. return;
  14887. try {
  14888. if ((*io) != nullptr && shell->flush_flag == false)
  14889. (*io)->set_flush_flag2(false);
  14890. close();
  14891. if (shell != nullptr) {
  14892. if ((*io) != nullptr)
  14893. (*io)->set_flush_flag2(true);
  14894. }
  14895. }
  14896. catch (OTL_CONST_EXCEPTION otl_exception &) {
  14897. if (shell != nullptr) {
  14898. if ((*io) != nullptr)
  14899. (*io)->set_flush_flag2(true);
  14900. }
  14901. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  14902. defined(OTL_STREAM_POOLING_ON)
  14903. clean(1);
  14904. if (shell != nullptr)
  14905. shell->set_should_delete(1);
  14906. shell_pt.destroy();
  14907. #else
  14908. shell_pt.destroy();
  14909. #endif
  14910. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  14911. throw;
  14912. #endif
  14913. }
  14914. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  14915. defined(OTL_STREAM_POOLING_ON)
  14916. if(otl_uncaught_exception()){}
  14917. #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  14918. if (otl_uncaught_exception()){}
  14919. #else
  14920. shell_pt.destroy();
  14921. #endif
  14922. }
  14923. OTL_NODISCARD int eof(void)OTL_THROWS_OTL_EXCEPTION {
  14924. if ((*io)) {
  14925. return (*io)->eof();
  14926. } else if ((*ss)) {
  14927. return (*ss)->eof();
  14928. } else
  14929. return 1;
  14930. }
  14931. void reset_to_last_valid_row() {
  14932. if ((*io)) {
  14933. (*io)->reset_to_last_valid_row();
  14934. }
  14935. }
  14936. void flush(void) OTL_THROWS_OTL_EXCEPTION {
  14937. if ((*io)) {
  14938. (*io)->flush();
  14939. }
  14940. }
  14941. OTL_NODISCARD bool get_error_state(void) const {
  14942. if(otl_uncaught_exception())
  14943. return true;
  14944. else if ((*io))
  14945. return (*io)->get_error_state();
  14946. else
  14947. return false;
  14948. }
  14949. void clean(const int clean_up_error_flag = 0) OTL_THROWS_OTL_EXCEPTION {
  14950. if(next_ov_ndx!=nullptr)(*next_ov_ndx)=0;
  14951. if(next_iov_ndx!=nullptr)(*next_iov_ndx)=0;
  14952. if ((*io) && shell != nullptr) {
  14953. (*io)->clean(clean_up_error_flag);
  14954. } else if ((*ss) && shell != nullptr) {
  14955. (*ss)->clean();
  14956. }
  14957. }
  14958. void rewind(void) OTL_THROWS_OTL_EXCEPTION {
  14959. if ((*io)) {
  14960. (*io)->rewind();
  14961. } else if ((*ss)) {
  14962. (*ss)->rewind();
  14963. }
  14964. }
  14965. OTL_NODISCARD int is_null(void) OTL_NO_THROW {
  14966. if ((*io))
  14967. return (*io)->is_null();
  14968. else if ((*ss))
  14969. return (*ss)->is_null();
  14970. else
  14971. return 0;
  14972. }
  14973. void set_commit(int auto_commit = 0) OTL_NO_THROW {
  14974. (*auto_commit_flag) = auto_commit;
  14975. if ((*io)) {
  14976. (*io)->set_commit(auto_commit);
  14977. }
  14978. }
  14979. OTL_NODISCARD const char *assign_stream_type(const char *stm_text, const char *stm_label) {
  14980. const char *temp_stm_text = nullptr;
  14981. temp_stm_text = stm_label ? stm_label : stm_text;
  14982. return temp_stm_text;
  14983. }
  14984. void open(const otl_stream_buffer_size_type arr_size, const char *sqlstm,
  14985. otl_connect &db, const int implicit_select = otl_explicit_select,
  14986. const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION {
  14987. if (arr_size <= 0) {
  14988. OTL_THROW((otl_exception(otl_error_msg_40, otl_error_code_40, sqlstm)));
  14989. }
  14990. #if defined(OTL_STREAM_THROWS_NOT_CONNECTED_TO_DATABASE_EXCEPTION)
  14991. if (!db.connected) {
  14992. OTL_THROW((otl_exception(otl_error_msg_35, otl_error_code_35, sqlstm)));
  14993. }
  14994. #endif
  14995. reset_end_marker();
  14996. otl_stream_buffer_size_type temp_arr_size = arr_size;
  14997. if (this->good()) {
  14998. const char *temp_stm_text = assign_stream_type(sqlstm, sqlstm_label);
  14999. OTL_THROW((otl_exception(otl_error_msg_29, otl_error_code_29, temp_stm_text)));
  15000. }
  15001. if (shell == nullptr)
  15002. init_stream();
  15003. buf_size_ = arr_size;
  15004. OTL_TRACE_STREAM_OPEN
  15005. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  15006. defined(OTL_STREAM_POOLING_ON)
  15007. if (*adb == nullptr)
  15008. *adb = &db;
  15009. if ((*adb) && (**adb).get_stream_pool_enabled_flag()) {
  15010. char temp_buf[128];
  15011. otl_itoa(arr_size, temp_buf);
  15012. const char delimiter = ';';
  15013. #if defined(OTL_STREAM_POOL_USES_STREAM_LABEL_AS_KEY)
  15014. const char *temp_label = sqlstm_label ? sqlstm_label : sqlstm;
  15015. #if defined(OTL_UNICODE_STRING_TYPE)
  15016. std::string sql_stm(temp_label);
  15017. #else
  15018. OTL_STRING_CONTAINER sql_stm(temp_label);
  15019. #endif
  15020. sql_stm += delimiter;
  15021. #if defined(OTL_UNICODE_STRING_TYPE)
  15022. sql_stm += std::string(temp_buf);
  15023. #else
  15024. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  15025. #endif
  15026. #else
  15027. #if defined(OTL_UNICODE_STRING_TYPE)
  15028. std::string sql_stm(sqlstm);
  15029. #else
  15030. OTL_STRING_CONTAINER sql_stm(sqlstm);
  15031. #endif
  15032. sql_stm += delimiter;
  15033. #if defined(OTL_UNICODE_STRING_TYPE)
  15034. sql_stm += std::string(temp_buf);
  15035. #else
  15036. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  15037. #endif
  15038. #endif
  15039. if (shell != nullptr) {
  15040. otl_select_struct_override &temp_override = shell->override_;
  15041. for (int i = 0; i < temp_override.getLen(); ++i) {
  15042. otl_itoa(OTL_SCAST(int, temp_override.get_col_type(i)), temp_buf);
  15043. sql_stm += delimiter;
  15044. #if defined(OTL_UNICODE_STRING_TYPE)
  15045. sql_stm += std::string(temp_buf);
  15046. #else
  15047. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  15048. #endif
  15049. }
  15050. }
  15051. otl_stream_shell *temp_shell =
  15052. OTL_RCAST(otl_stream_shell *, db.sc.find(sql_stm));
  15053. if (temp_shell) {
  15054. if (shell != nullptr)
  15055. shell_pt.destroy();
  15056. shell = temp_shell;
  15057. ss = &(shell->ss);
  15058. io = &(shell->io);
  15059. if ((*io) != nullptr)
  15060. (*io)->set_flush_flag2(true);
  15061. adb = &(shell->adb);
  15062. if (*adb == nullptr)
  15063. *adb = &db;
  15064. auto_commit_flag = &(shell->auto_commit_flag);
  15065. iov = &(shell->iov);
  15066. iov_len = &(shell->iov_len);
  15067. next_iov_ndx = &(shell->next_iov_ndx);
  15068. ov = &(shell->ov);
  15069. ov_len = &(shell->ov_len);
  15070. next_ov_ndx = &(shell->next_ov_ndx);
  15071. override_ = &(shell->override_);
  15072. try {
  15073. if ((*iov_len) == 0)
  15074. this->rewind();
  15075. }
  15076. catch (OTL_CONST_EXCEPTION otl_exception &) {
  15077. if ((*adb))
  15078. (*adb)->sc.remove(shell, shell->orig_sql_stm);
  15079. intern_cleanup();
  15080. shell_pt.destroy();
  15081. connected = 0;
  15082. throw;
  15083. }
  15084. connected = 1;
  15085. return;
  15086. }
  15087. shell->orig_sql_stm = sql_stm;
  15088. }
  15089. #endif
  15090. delete[](*iov);
  15091. delete[](*ov);
  15092. (*iov) = nullptr;
  15093. (*iov_len) = 0;
  15094. (*ov) = nullptr;
  15095. (*ov_len) = 0;
  15096. (*next_iov_ndx) = 0;
  15097. (*next_ov_ndx) = 0;
  15098. char tmp[7];
  15099. char *c = OTL_CCAST(char *, sqlstm);
  15100. override_->set_lob_stream_mode(shell->lob_stream_flag);
  15101. while (otl_isspace(*c) || (*c) == '(')
  15102. ++c;
  15103. OTL_STRNCPY_S(tmp, sizeof(tmp), c, 6);
  15104. tmp[6] = 0;
  15105. c = tmp;
  15106. while (*c) {
  15107. *c = OTL_SCAST(char, otl_to_upper(*c));
  15108. ++c;
  15109. }
  15110. if (adb == nullptr)
  15111. adb = &(shell->adb);
  15112. (*adb) = &db;
  15113. try {
  15114. #if (defined(OTL_ODBC_POSTGRESQL) && !defined(OTL_ODBC_ALTERNATE_RPC) || \
  15115. defined(OTL_ODBC_SELECT_STM_EXECUTE_BEFORE_DESCRIBE)) && \
  15116. !defined(OTL_ODBC_MULTI_MODE)
  15117. if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0)) {
  15118. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15119. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db,
  15120. otl_implicit_select, sqlstm_label);
  15121. shell->stream_type = otl_odbc_select_stream;
  15122. }
  15123. #elif defined(OTL_ODBC_MULTI_MODE)
  15124. #if defined(OTL_ODBC_ALTERNATE_RPC)
  15125. bool alternate_rpc = true;
  15126. #else
  15127. bool alternate_rpc = false;
  15128. #endif
  15129. int connect_type = (*adb)->get_connect_struct().get_connection_type();
  15130. if (((connect_type == OTL_POSTGRESQL_ODBC_CONNECT && !alternate_rpc) ||
  15131. connect_type == OTL_ENTERPRISE_DB_ODBC_CONNECT ||
  15132. connect_type == OTL_MYODBC35_ODBC_CONNECT) &&
  15133. (strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0)) {
  15134. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15135. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db,
  15136. otl_implicit_select, sqlstm_label);
  15137. shell->stream_type = otl_odbc_select_stream;
  15138. } else if ((strncmp(tmp, "SELECT", 6) == 0 ||
  15139. strncmp(tmp, "WITH", 4) == 0) &&
  15140. implicit_select == otl_explicit_select) {
  15141. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db,
  15142. otl_explicit_select, sqlstm_label);
  15143. shell->stream_type = otl_odbc_select_stream;
  15144. }
  15145. #else
  15146. if ((strncmp(tmp, "SELECT", 6) == 0 ||
  15147. strncmp(tmp, "WITH", 4) == 0) &&
  15148. implicit_select == otl_explicit_select) {
  15149. #if defined(OTL_ODBC_TIMESTEN)
  15150. if (temp_arr_size > 128 || temp_arr_size < 0) {
  15151. const char *temp_stm_text =
  15152. assign_stream_type(sqlstm, sqlstm_label);
  15153. OTL_THROW((otl_exception(otl_error_msg_31, otl_error_code_31,
  15154. temp_stm_text)));
  15155. }
  15156. #endif
  15157. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15158. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db,
  15159. otl_explicit_select, sqlstm_label);
  15160. shell->stream_type = otl_odbc_select_stream;
  15161. }
  15162. #endif
  15163. else if (tmp[0] == '$') {
  15164. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15165. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 1,
  15166. sqlstm_label);
  15167. shell->stream_type = otl_odbc_select_stream;
  15168. } else {
  15169. if (implicit_select == otl_implicit_select) {
  15170. #if defined(OTL_ODBC_TIMESTEN)
  15171. if (temp_arr_size > 128 || temp_arr_size < 0) {
  15172. const char *temp_stm_text =
  15173. assign_stream_type(sqlstm, sqlstm_label);
  15174. OTL_THROW((otl_exception(otl_error_msg_31, otl_error_code_31,
  15175. temp_stm_text)));
  15176. }
  15177. #endif
  15178. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15179. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 1,
  15180. sqlstm_label);
  15181. shell->stream_type = otl_odbc_select_stream;
  15182. } else if(implicit_select == otl_direct_exec_select){
  15183. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  15184. (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 2,
  15185. sqlstm_label);
  15186. shell->stream_type = otl_odbc_select_stream;
  15187. }else {
  15188. (*io) = new otl_inout_stream(arr_size, sqlstm, db,
  15189. OTL_RCAST(void *, this),
  15190. shell->lob_stream_flag, sqlstm_label);
  15191. (*io)->set_flush_flag(shell->flush_flag);
  15192. shell->stream_type = otl_odbc_io_stream;
  15193. }
  15194. }
  15195. }
  15196. catch (OTL_CONST_EXCEPTION otl_exception &) {
  15197. shell_pt.destroy();
  15198. throw;
  15199. }
  15200. if ((*io))
  15201. (*io)->set_commit((*auto_commit_flag));
  15202. create_var_desc();
  15203. connected = 1;
  15204. #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT)
  15205. if ((*ss) && db.get_fetch_scroll_mode()) {
  15206. (*ss)->get_select_cursor_struct().set_fetch_scroll_flag();
  15207. }
  15208. #endif
  15209. }
  15210. void intern_cleanup(void) {
  15211. delete[](*iov);
  15212. delete[](*ov);
  15213. (*iov) = nullptr;
  15214. (*iov_len) = 0;
  15215. (*ov) = nullptr;
  15216. (*ov_len) = 0;
  15217. (*next_iov_ndx) = 0;
  15218. (*next_ov_ndx) = 0;
  15219. override_->setLen(0);
  15220. override_->set_lob_stream_mode(false);
  15221. switch (shell->stream_type) {
  15222. case otl_odbc_no_stream:
  15223. break;
  15224. case otl_odbc_io_stream:
  15225. try {
  15226. if ((*io) != nullptr) {
  15227. (*io)->flush();
  15228. (*io)->close();
  15229. }
  15230. }
  15231. catch (OTL_CONST_EXCEPTION otl_exception &) {
  15232. clean(1);
  15233. (*io)->close();
  15234. delete (*io);
  15235. (*io) = nullptr;
  15236. shell->stream_type = otl_odbc_no_stream;
  15237. throw;
  15238. }
  15239. delete (*io);
  15240. (*io) = nullptr;
  15241. shell->stream_type = otl_odbc_no_stream;
  15242. break;
  15243. case otl_odbc_select_stream:
  15244. try {
  15245. if ((*ss) != nullptr)
  15246. (*ss)->close();
  15247. }
  15248. catch (OTL_CONST_EXCEPTION otl_exception &) {
  15249. delete (*ss);
  15250. (*ss) = nullptr;
  15251. shell->stream_type = otl_odbc_no_stream;
  15252. throw;
  15253. }
  15254. delete (*ss);
  15255. (*ss) = nullptr;
  15256. shell->stream_type = otl_odbc_no_stream;
  15257. break;
  15258. }
  15259. (*ss) = nullptr;
  15260. (*io) = nullptr;
  15261. if (adb != nullptr)
  15262. (*adb) = nullptr;
  15263. adb = nullptr;
  15264. }
  15265. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  15266. defined(OTL_UNICODE_STRING_TYPE)) && \
  15267. defined(OTL_STREAM_POOLING_ON)
  15268. void close(const bool save_in_stream_pool = true) OTL_THROWS_OTL_EXCEPTION
  15269. #else
  15270. void close(void) OTL_THROWS_OTL_EXCEPTION
  15271. #endif
  15272. {
  15273. if (shell == nullptr)
  15274. return;
  15275. OTL_TRACE_FUNC(0x4, "otl_stream", "close", "")
  15276. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  15277. defined(OTL_UNICODE_STRING_TYPE)) && \
  15278. defined(OTL_STREAM_POOLING_ON)
  15279. if (save_in_stream_pool && (*adb) &&
  15280. (**adb).get_stream_pool_enabled_flag() &&
  15281. !(otl_uncaught_exception())) {
  15282. try {
  15283. this->flush();
  15284. this->clean(1);
  15285. }
  15286. catch (OTL_CONST_EXCEPTION otl_exception &) {
  15287. this->clean(1);
  15288. throw;
  15289. }
  15290. if (otl_uncaught_exception()) {
  15291. (*adb)->sc.remove(shell, shell->orig_sql_stm);
  15292. intern_cleanup();
  15293. shell_pt.destroy();
  15294. connected = 0;
  15295. return;
  15296. }
  15297. #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  15298. if (otl_uncaught_exception()) {
  15299. if ((*adb))
  15300. (*adb)->sc.remove(shell, shell->orig_sql_stm);
  15301. intern_cleanup();
  15302. shell_pt.destroy();
  15303. connected = 0;
  15304. return;
  15305. }
  15306. #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  15307. if (otl_uncaught_exception()) {
  15308. if ((*adb))
  15309. (*adb)->sc.remove(shell, shell->orig_sql_stm);
  15310. intern_cleanup();
  15311. shell_pt.destroy();
  15312. connected = 0;
  15313. return;
  15314. }
  15315. #endif
  15316. if(shell->io!=nullptr)
  15317. shell->io->set_commit(1);
  15318. (*adb)->sc.add(shell, shell->orig_sql_stm.c_str());
  15319. shell_pt.disconnect();
  15320. connected = 0;
  15321. } else {
  15322. if ((*adb))
  15323. (*adb)->sc.remove(shell, shell->orig_sql_stm);
  15324. intern_cleanup();
  15325. shell_pt.destroy();
  15326. connected = 0;
  15327. }
  15328. #else
  15329. intern_cleanup();
  15330. connected = 0;
  15331. #endif
  15332. }
  15333. OTL_NODISCARD otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW {
  15334. desc_len = 0;
  15335. if ((*ss)) {
  15336. desc_len = (*ss)->get_sl_len();
  15337. return (*ss)->get_sl_desc();
  15338. }
  15339. return nullptr;
  15340. }
  15341. OTL_NODISCARD int good(void) OTL_NO_THROW {
  15342. if (!connected)
  15343. return 0;
  15344. if ((*io) || (*ss)) {
  15345. return 1;
  15346. } else
  15347. return 0;
  15348. }
  15349. otl_stream &operator<<(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION {
  15350. last_oper_was_read_op = false;
  15351. reset_end_marker();
  15352. if ((*io)) {
  15353. (*io)->operator<<(s);
  15354. inc_next_iov();
  15355. } else if (*ss) {
  15356. OTL_THROW((otl_exception(otl_error_msg_41, otl_error_code_41,
  15357. (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  15358. : (*ss)->get_stm_text())));
  15359. }
  15360. return *this;
  15361. }
  15362. otl_stream &operator>>(otl_stream &(*pf)(otl_stream &)) {
  15363. (*pf)(*this);
  15364. return *this;
  15365. }
  15366. otl_stream &operator<<(otl_stream &(*pf)(otl_stream &)) {
  15367. (*pf)(*this);
  15368. return *this;
  15369. }
  15370. #if defined(OTL_PARANOID_EOF)
  15371. void throw_if_eof_was_already_reached(const int eof_flag,
  15372. const char *operator_type = nullptr) {
  15373. if (eof_flag) {
  15374. char out_buf[256];
  15375. OTL_SPRINTF_S(out_buf, sizeof(out_buf), otl_error_msg_42,
  15376. operator_type == nullptr ? "" : operator_type);
  15377. OTL_THROW((otl_exception(out_buf, otl_error_code_42, this->get_stm_text(),
  15378. this->describe_next_out_var()->name)));
  15379. }
  15380. }
  15381. #endif
  15382. otl_stream &operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION {
  15383. last_oper_was_read_op = true;
  15384. switch (shell->stream_type) {
  15385. case otl_odbc_no_stream:
  15386. break;
  15387. case otl_odbc_io_stream:
  15388. last_eof_rc = (*io)->eof();
  15389. #if defined(OTL_PARANOID_EOF)
  15390. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  15391. #endif
  15392. #if defined(OTL_PARANOID_EOF)
  15393. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  15394. #endif
  15395. (*io)->operator>>(s);
  15396. break;
  15397. case otl_odbc_select_stream:
  15398. s.reset_last_read_lob_len();
  15399. last_eof_rc = (*ss)->eof();
  15400. #if defined(OTL_PARANOID_EOF)
  15401. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  15402. #endif
  15403. (*ss)->operator>>(s);
  15404. break;
  15405. }
  15406. inc_next_ov();
  15407. return *this;
  15408. }
  15409. otl_stream &operator>>(otl_time &s) OTL_THROWS_OTL_EXCEPTION {
  15410. last_oper_was_read_op = true;
  15411. switch (shell->stream_type) {
  15412. case otl_odbc_no_stream:
  15413. break;
  15414. case otl_odbc_io_stream:
  15415. last_eof_rc = (*io)->eof();
  15416. #if defined(OTL_PARANOID_EOF)
  15417. throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&");
  15418. #endif
  15419. (*io)->operator>>(s);
  15420. break;
  15421. case otl_odbc_select_stream:
  15422. last_eof_rc = (*ss)->eof();
  15423. #if defined(OTL_PARANOID_EOF)
  15424. throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&");
  15425. #endif
  15426. (*ss)->operator>>(s);
  15427. break;
  15428. }
  15429. return *this;
  15430. }
  15431. otl_stream &operator<<(const otl_time &n) OTL_THROWS_OTL_EXCEPTION {
  15432. last_oper_was_read_op = false;
  15433. reset_end_marker();
  15434. switch (shell->stream_type) {
  15435. case otl_odbc_no_stream:
  15436. break;
  15437. case otl_odbc_io_stream:
  15438. (*io)->operator<<(n);
  15439. break;
  15440. case otl_odbc_select_stream:
  15441. (*ss)->operator<<(n);
  15442. if (!(*ov) && (*ss)->get_sl())
  15443. create_var_desc();
  15444. break;
  15445. }
  15446. return *this;
  15447. }
  15448. otl_stream &operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION {
  15449. last_oper_was_read_op = true;
  15450. #if defined(OTL_ODBC_STRING_TO_TIMESTAMP)
  15451. otl_var_desc *temp_next_var = describe_next_out_var();
  15452. if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) {
  15453. #if defined(OTL_UNICODE)
  15454. #if defined(OTL_UNICODE_CHAR_TYPE)
  15455. OTL_UNICODE_CHAR_TYPE tmp_str[100];
  15456. #else
  15457. OTL_CHAR tmp_str[100];
  15458. #endif
  15459. #else
  15460. char tmp_str[100];
  15461. #endif
  15462. (*this) >> tmp_str;
  15463. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  15464. if ((*this).is_null())
  15465. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  15466. else
  15467. OTL_ODBC_STRING_TO_TIMESTAMP(tmp_str, s);
  15468. #else
  15469. OTL_ODBC_STRING_TO_TIMESTAMP(tmp_str, s);
  15470. #endif
  15471. #if defined(OTL_ODBC_TIME_ZONE)
  15472. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_TZ_DATETIME(s), "operator >>",
  15473. "otl_datetime&");
  15474. #else
  15475. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  15476. "otl_datetime&");
  15477. #endif
  15478. return *this;
  15479. } else {
  15480. otl_time tmp;
  15481. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
  15482. (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \
  15483. defined(__clang__)
  15484. tmp.year = 1900;
  15485. tmp.month = 1;
  15486. tmp.day = 1;
  15487. tmp.hour = 0;
  15488. tmp.minute = 0;
  15489. tmp.second = 0;
  15490. tmp.fraction = 0;
  15491. #endif
  15492. (*this) >> tmp;
  15493. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  15494. if ((*this).is_null())
  15495. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  15496. else {
  15497. s.year = tmp.year;
  15498. s.month = tmp.month;
  15499. s.day = tmp.day;
  15500. s.hour = tmp.hour;
  15501. s.minute = tmp.minute;
  15502. s.second = tmp.second;
  15503. s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision);
  15504. }
  15505. #else
  15506. s.year = tmp.year;
  15507. s.month = tmp.month;
  15508. s.day = tmp.day;
  15509. s.hour = tmp.hour;
  15510. s.minute = tmp.minute;
  15511. s.second = tmp.second;
  15512. s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision);
  15513. #endif
  15514. }
  15515. #else
  15516. otl_time tmp;
  15517. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
  15518. (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \
  15519. defined(__clang__)
  15520. tmp.year = 1900;
  15521. tmp.month = 1;
  15522. tmp.day = 1;
  15523. tmp.hour = 0;
  15524. tmp.minute = 0;
  15525. tmp.second = 0;
  15526. tmp.fraction = 0;
  15527. #endif
  15528. (*this) >> tmp;
  15529. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  15530. if ((*this).is_null())
  15531. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  15532. else {
  15533. s.year = tmp.year;
  15534. s.month = tmp.month;
  15535. s.day = tmp.day;
  15536. s.hour = tmp.hour;
  15537. s.minute = tmp.minute;
  15538. s.second = tmp.second;
  15539. s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision);
  15540. }
  15541. #else
  15542. s.year = tmp.year;
  15543. s.month = tmp.month;
  15544. s.day = tmp.day;
  15545. s.hour = tmp.hour;
  15546. s.minute = tmp.minute;
  15547. s.second = tmp.second;
  15548. s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision);
  15549. #endif
  15550. #endif
  15551. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  15552. "otl_datetime&");
  15553. inc_next_ov();
  15554. return *this;
  15555. }
  15556. otl_stream &operator<<(const otl_datetime &s) OTL_THROWS_OTL_EXCEPTION {
  15557. otl_time tmp;
  15558. last_oper_was_read_op = false;
  15559. reset_end_marker();
  15560. #if defined(OTL_ODBC_TIMESTAMP_TO_STRING)
  15561. otl_var_desc *temp_next_var = describe_next_in_var();
  15562. if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) {
  15563. #if defined(OTL_UNICODE)
  15564. #if defined(OTL_UNICODE_CHAR_TYPE)
  15565. OTL_UNICODE_CHAR_TYPE tmp_str[100];
  15566. #else
  15567. OTL_CHAR tmp_str[100];
  15568. #endif
  15569. #else
  15570. char tmp_str[100];
  15571. #endif
  15572. OTL_ODBC_TIMESTAMP_TO_STRING(s, tmp_str);
  15573. #if defined(OTL_ODBC_TIME_ZONE)
  15574. OTL_TRACE_READ(OTL_TRACE_FORMAT_TZ_DATETIME(s), "operator <<",
  15575. "otl_datetime&");
  15576. #else
  15577. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<",
  15578. "otl_datetime&");
  15579. #endif
  15580. (*this) << tmp_str;
  15581. return *this;
  15582. } else {
  15583. tmp.year = OTL_SCAST(SQLSMALLINT, s.year);
  15584. tmp.month = OTL_SCAST(SQLUSMALLINT, s.month);
  15585. tmp.day = OTL_SCAST(SQLUSMALLINT, s.day);
  15586. tmp.hour = OTL_SCAST(SQLUSMALLINT, s.hour);
  15587. tmp.minute = OTL_SCAST(SQLUSMALLINT, s.minute);
  15588. tmp.second = OTL_SCAST(SQLUSMALLINT, s.second);
  15589. tmp.fraction = otl_to_fraction(OTL_SCAST(unsigned int, s.fraction),
  15590. s.frac_precision);
  15591. (*this) << tmp;
  15592. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  15593. "otl_datetime&");
  15594. inc_next_iov();
  15595. return *this;
  15596. }
  15597. #else
  15598. tmp.year = OTL_SCAST(SQLSMALLINT, s.year);
  15599. tmp.month = OTL_SCAST(SQLUSMALLINT, s.month);
  15600. tmp.day = OTL_SCAST(SQLUSMALLINT, s.day);
  15601. tmp.hour = OTL_SCAST(SQLUSMALLINT, s.hour);
  15602. tmp.minute = OTL_SCAST(SQLUSMALLINT, s.minute);
  15603. tmp.second = OTL_SCAST(SQLUSMALLINT, s.second);
  15604. tmp.fraction =
  15605. otl_to_fraction(OTL_SCAST(unsigned int, s.fraction), s.frac_precision);
  15606. (*this) << tmp;
  15607. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<",
  15608. "otl_datetime&");
  15609. inc_next_iov();
  15610. return *this;
  15611. #endif
  15612. }
  15613. #if !defined(OTL_UNICODE)
  15614. otl_stream &operator>>(char &c) OTL_THROWS_OTL_EXCEPTION {
  15615. last_oper_was_read_op = true;
  15616. switch (shell->stream_type) {
  15617. case otl_odbc_no_stream:
  15618. break;
  15619. case otl_odbc_io_stream:
  15620. last_eof_rc = (*io)->eof();
  15621. #if defined(OTL_PARANOID_EOF)
  15622. throw_if_eof_was_already_reached(last_eof_rc, "char&");
  15623. #endif
  15624. (*io)->operator>>(c);
  15625. break;
  15626. case otl_odbc_select_stream:
  15627. last_eof_rc = (*ss)->eof();
  15628. #if defined(OTL_PARANOID_EOF)
  15629. throw_if_eof_was_already_reached(last_eof_rc, "char&");
  15630. #endif
  15631. (*ss)->operator>>(c);
  15632. break;
  15633. }
  15634. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  15635. if ((*this).is_null())
  15636. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  15637. #endif
  15638. OTL_TRACE_WRITE("'" << c << "'", "operator >>", "char&")
  15639. inc_next_ov();
  15640. return *this;
  15641. }
  15642. #endif
  15643. #if !defined(OTL_UNICODE)
  15644. otl_stream &operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION {
  15645. last_oper_was_read_op = true;
  15646. switch (shell->stream_type) {
  15647. case otl_odbc_no_stream:
  15648. break;
  15649. case otl_odbc_io_stream:
  15650. last_eof_rc = (*io)->eof();
  15651. #if defined(OTL_PARANOID_EOF)
  15652. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&");
  15653. #endif
  15654. (*io)->operator>>(c);
  15655. break;
  15656. case otl_odbc_select_stream:
  15657. last_eof_rc = (*ss)->eof();
  15658. #if defined(OTL_PARANOID_EOF)
  15659. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&");
  15660. #endif
  15661. (*ss)->operator>>(c);
  15662. break;
  15663. }
  15664. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  15665. if ((*this).is_null())
  15666. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  15667. #endif
  15668. OTL_TRACE_WRITE("'" << c << "'", "operator >>", "unsigned char&")
  15669. inc_next_ov();
  15670. return *this;
  15671. }
  15672. #endif
  15673. #if !defined(OTL_UNICODE)
  15674. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  15675. otl_stream &operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION {
  15676. last_oper_was_read_op = true;
  15677. switch (shell->stream_type) {
  15678. case otl_odbc_no_stream:
  15679. break;
  15680. case otl_odbc_io_stream:
  15681. last_eof_rc = (*io)->eof();
  15682. #if defined(OTL_PARANOID_EOF)
  15683. throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&");
  15684. #endif
  15685. (*io)->operator>>(s);
  15686. break;
  15687. case otl_odbc_select_stream:
  15688. last_eof_rc = (*ss)->eof();
  15689. #if defined(OTL_PARANOID_EOF)
  15690. throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&");
  15691. #endif
  15692. (*ss)->operator>>(s);
  15693. break;
  15694. }
  15695. #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL)
  15696. if ((*this).is_null()) {
  15697. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s);
  15698. }
  15699. #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15700. if ((*this).is_null())
  15701. s = OTL_DEFAULT_STRING_NULL_TO_VAL;
  15702. #endif
  15703. OTL_TRACE_WRITE(s, "operator >>", "OTL_STRING_CONTAINER&")
  15704. inc_next_ov();
  15705. return *this;
  15706. }
  15707. #endif
  15708. #endif
  15709. #if !defined(OTL_UNICODE)
  15710. otl_stream &operator>>(char *s) OTL_THROWS_OTL_EXCEPTION {
  15711. last_oper_was_read_op = true;
  15712. switch (shell->stream_type) {
  15713. case otl_odbc_no_stream:
  15714. break;
  15715. case otl_odbc_io_stream:
  15716. last_eof_rc = (*io)->eof();
  15717. #if defined(OTL_PARANOID_EOF)
  15718. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  15719. #endif
  15720. (*io)->operator>>(s);
  15721. break;
  15722. case otl_odbc_select_stream:
  15723. last_eof_rc = (*ss)->eof();
  15724. #if defined(OTL_PARANOID_EOF)
  15725. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  15726. #endif
  15727. (*ss)->operator>>(s);
  15728. break;
  15729. }
  15730. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15731. if ((*this).is_null())
  15732. otl_strcpy(
  15733. OTL_RCAST(unsigned char *, s),
  15734. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  15735. #endif
  15736. OTL_TRACE_WRITE(s, "operator >>", "char*")
  15737. inc_next_ov();
  15738. return *this;
  15739. }
  15740. #endif
  15741. #if !defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  15742. template<const size_t N>
  15743. otl_stream &operator>>(std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
  15744. last_oper_was_read_op = true;
  15745. switch (shell->stream_type) {
  15746. case otl_odbc_no_stream:
  15747. break;
  15748. case otl_odbc_io_stream:
  15749. last_eof_rc = (*io)->eof();
  15750. #if defined(OTL_PARANOID_EOF)
  15751. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char,...>&");
  15752. #endif
  15753. (*io)->getString(s.data(),OTL_SCAST(int,N));
  15754. break;
  15755. case otl_odbc_select_stream:
  15756. last_eof_rc = (*ss)->eof();
  15757. #if defined(OTL_PARANOID_EOF)
  15758. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char,...>&");
  15759. #endif
  15760. (*ss)->getString(s.data(),OTL_SCAST(int,N));
  15761. break;
  15762. }
  15763. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15764. if ((*this).is_null())
  15765. otl_strcpy(OTL_RCAST(unsigned char *, s.data()),OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  15766. #endif
  15767. OTL_TRACE_WRITE(s, "operator >>", "std::array<char,...>&")
  15768. inc_next_ov();
  15769. return *this;
  15770. }
  15771. #endif
  15772. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  15773. template<const size_t N>
  15774. otl_stream &operator>>(std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
  15775. last_oper_was_read_op = true;
  15776. switch (shell->stream_type) {
  15777. case otl_odbc_no_stream:
  15778. break;
  15779. case otl_odbc_io_stream:
  15780. last_eof_rc = (*io)->eof();
  15781. #if defined(OTL_PARANOID_EOF)
  15782. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char16_t,...>&");
  15783. #endif
  15784. (*io)->getString(s.data(),OTL_SCAST(int,N));
  15785. break;
  15786. case otl_odbc_select_stream:
  15787. last_eof_rc = (*ss)->eof();
  15788. #if defined(OTL_PARANOID_EOF)
  15789. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char16_t,...>&");
  15790. #endif
  15791. (*ss)->getString(s.data(),OTL_SCAST(int,N));
  15792. break;
  15793. }
  15794. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15795. if ((*this).is_null())
  15796. otl_strcpy(OTL_RCAST(unsigned char *, s.data()),OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  15797. #endif
  15798. OTL_TRACE_WRITE(s, "operator >>", "std::array<char16_t,...>&")
  15799. inc_next_ov();
  15800. return *this;
  15801. }
  15802. #endif
  15803. #if defined(OTL_UNICODE_STRING_TYPE)
  15804. otl_stream &operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION {
  15805. last_oper_was_read_op = true;
  15806. switch (shell->stream_type) {
  15807. case otl_odbc_no_stream:
  15808. break;
  15809. case otl_odbc_io_stream:
  15810. last_eof_rc = (*io)->eof();
  15811. #if defined(OTL_PARANOID_EOF)
  15812. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&");
  15813. #endif
  15814. (*io)->operator>>(s);
  15815. break;
  15816. case otl_odbc_select_stream:
  15817. last_eof_rc = (*ss)->eof();
  15818. #if defined(OTL_PARANOID_EOF)
  15819. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&");
  15820. #endif
  15821. (*ss)->operator>>(s);
  15822. break;
  15823. }
  15824. #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL)
  15825. if ((*this).is_null()) {
  15826. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s);
  15827. }
  15828. #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15829. if ((*this).is_null())
  15830. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, OTL_DEFAULT_STRING_NULL_TO_VAL);
  15831. #endif
  15832. OTL_TRACE_WRITE(s.c_str(), "operator >>", "OTL_UNICODE_STRING_TYPE&");
  15833. inc_next_ov();
  15834. return *this;
  15835. }
  15836. #endif
  15837. otl_stream &operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION {
  15838. last_oper_was_read_op = true;
  15839. switch (shell->stream_type) {
  15840. case otl_odbc_no_stream:
  15841. break;
  15842. case otl_odbc_io_stream:
  15843. last_eof_rc = (*io)->eof();
  15844. #if defined(OTL_PARANOID_EOF)
  15845. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*");
  15846. #endif
  15847. (*io)->operator>>(s);
  15848. break;
  15849. case otl_odbc_select_stream:
  15850. last_eof_rc = (*ss)->eof();
  15851. #if defined(OTL_PARANOID_EOF)
  15852. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*");
  15853. #endif
  15854. (*ss)->operator>>(s);
  15855. break;
  15856. }
  15857. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15858. if ((*this).is_null())
  15859. otl_strcpy(OTL_RCAST(unsigned char *, s),
  15860. OTL_RCAST(unsigned char *,
  15861. OTL_CCAST(char *, OTL_DEFAULT_STRING_NULL_TO_VAL)));
  15862. #endif
  15863. #if defined(OTL_UNICODE)
  15864. OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>",
  15865. OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*")
  15866. #else
  15867. OTL_TRACE_WRITE(s, "operator >>", "unsigned char*")
  15868. #endif
  15869. inc_next_ov();
  15870. return *this;
  15871. }
  15872. #if defined(OTL_UNICODE)
  15873. otl_stream &operator>>(OTL_UNICODE_CHAR_TYPE &c) OTL_THROWS_OTL_EXCEPTION {
  15874. OTL_UNICODE_CHAR_TYPE s[1024];
  15875. last_oper_was_read_op = true;
  15876. switch (shell->stream_type) {
  15877. case otl_odbc_no_stream:
  15878. break;
  15879. case otl_odbc_io_stream:
  15880. last_eof_rc = (*io)->eof();
  15881. #if defined(OTL_PARANOID_EOF)
  15882. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&");
  15883. #endif
  15884. (*io)->operator>>(OTL_RCAST(unsigned char *, s));
  15885. break;
  15886. case otl_odbc_select_stream:
  15887. last_eof_rc = (*ss)->eof();
  15888. #if defined(OTL_PARANOID_EOF)
  15889. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&");
  15890. #endif
  15891. (*ss)->operator>>(OTL_RCAST(unsigned char *, s));
  15892. break;
  15893. }
  15894. #if defined(_MSC_VER) && (_MSC_VER >= 1700)
  15895. #pragma warning(push)
  15896. #pragma warning(disable : 6001)
  15897. #endif
  15898. c = s[0];
  15899. #if defined(_MSC_VER) && (_MSC_VER >= 1700)
  15900. #pragma warning(pop)
  15901. #endif
  15902. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  15903. if ((*this).is_null())
  15904. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  15905. #endif
  15906. OTL_TRACE_WRITE(c, "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "")
  15907. inc_next_ov();
  15908. return *this;
  15909. }
  15910. otl_stream &operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION {
  15911. last_oper_was_read_op = true;
  15912. switch (shell->stream_type) {
  15913. case otl_odbc_no_stream:
  15914. break;
  15915. case otl_odbc_io_stream:
  15916. last_eof_rc = (*io)->eof();
  15917. #if defined(OTL_PARANOID_EOF)
  15918. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*");
  15919. #endif
  15920. (*io)->operator>>(OTL_RCAST(unsigned char *, s));
  15921. break;
  15922. case otl_odbc_select_stream:
  15923. last_eof_rc = (*ss)->eof();
  15924. #if defined(OTL_PARANOID_EOF)
  15925. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*");
  15926. #endif
  15927. (*ss)->operator>>(OTL_RCAST(unsigned char *, s));
  15928. break;
  15929. }
  15930. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  15931. if ((*this).is_null())
  15932. otl_strcpy(
  15933. OTL_RCAST(unsigned char *, s),
  15934. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  15935. #endif
  15936. OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>",
  15937. OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*")
  15938. inc_next_ov();
  15939. return *this;
  15940. }
  15941. #endif
  15942. otl_stream &operator>>(int &n) OTL_THROWS_OTL_EXCEPTION {
  15943. last_oper_was_read_op = true;
  15944. switch (shell->stream_type) {
  15945. case otl_odbc_no_stream:
  15946. break;
  15947. case otl_odbc_io_stream:
  15948. last_eof_rc = (*io)->eof();
  15949. #if defined(OTL_PARANOID_EOF)
  15950. throw_if_eof_was_already_reached(last_eof_rc, "int&");
  15951. #endif
  15952. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  15953. (*io)->operator>>(n);
  15954. #else
  15955. (*io)->operator>><int, otl_var_int>(n);
  15956. #endif
  15957. break;
  15958. case otl_odbc_select_stream:
  15959. last_eof_rc = (*ss)->eof();
  15960. #if defined(OTL_PARANOID_EOF)
  15961. throw_if_eof_was_already_reached(last_eof_rc, "int&");
  15962. #endif
  15963. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  15964. (*ss)->operator>>(n);
  15965. #else
  15966. (*ss)->operator>><int, otl_var_int>(n);
  15967. #endif
  15968. break;
  15969. }
  15970. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  15971. if ((*this).is_null())
  15972. n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  15973. #endif
  15974. OTL_TRACE_WRITE(n, "operator >>", "int&")
  15975. inc_next_ov();
  15976. return *this;
  15977. }
  15978. otl_stream &operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION {
  15979. last_oper_was_read_op = true;
  15980. switch (shell->stream_type) {
  15981. case otl_odbc_no_stream:
  15982. break;
  15983. case otl_odbc_io_stream:
  15984. last_eof_rc = (*io)->eof();
  15985. #if defined(OTL_PARANOID_EOF)
  15986. throw_if_eof_was_already_reached(last_eof_rc, "unsigned int&");
  15987. #endif
  15988. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  15989. (*io)->operator>>(u);
  15990. #else
  15991. (*io)->operator>><unsigned, otl_var_unsigned_int>(u);
  15992. #endif
  15993. break;
  15994. case otl_odbc_select_stream:
  15995. last_eof_rc = (*ss)->eof();
  15996. #if defined(OTL_PARANOID_EOF)
  15997. throw_if_eof_was_already_reached(last_eof_rc, "unsigned int&");
  15998. #endif
  15999. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16000. (*ss)->operator>>(u);
  16001. #else
  16002. (*ss)->operator>><unsigned, otl_var_unsigned_int>(u);
  16003. #endif
  16004. break;
  16005. }
  16006. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16007. if ((*this).is_null())
  16008. u = OTL_SCAST(unsigned int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16009. #endif
  16010. OTL_TRACE_WRITE(u, "operator >>", "unsigned&")
  16011. inc_next_ov();
  16012. return *this;
  16013. }
  16014. otl_stream &operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION {
  16015. last_oper_was_read_op = true;
  16016. switch (shell->stream_type) {
  16017. case otl_odbc_no_stream:
  16018. break;
  16019. case otl_odbc_io_stream:
  16020. last_eof_rc = (*io)->eof();
  16021. #if defined(OTL_PARANOID_EOF)
  16022. throw_if_eof_was_already_reached(last_eof_rc, "short int&");
  16023. #endif
  16024. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16025. (*io)->operator>>(sh);
  16026. #else
  16027. (*io)->operator>><short, otl_var_short>(sh);
  16028. #endif
  16029. break;
  16030. case otl_odbc_select_stream:
  16031. last_eof_rc = (*ss)->eof();
  16032. #if defined(OTL_PARANOID_EOF)
  16033. throw_if_eof_was_already_reached(last_eof_rc, "short int&");
  16034. #endif
  16035. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16036. (*ss)->operator>>(sh);
  16037. #else
  16038. (*ss)->operator>><short, otl_var_short>(sh);
  16039. #endif
  16040. break;
  16041. }
  16042. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16043. if ((*this).is_null())
  16044. sh = OTL_SCAST(short int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16045. #endif
  16046. OTL_TRACE_WRITE(sh, "operator >>", "short int&")
  16047. inc_next_ov();
  16048. return *this;
  16049. }
  16050. otl_stream &operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION {
  16051. last_oper_was_read_op = true;
  16052. switch (shell->stream_type) {
  16053. case otl_odbc_no_stream:
  16054. break;
  16055. case otl_odbc_io_stream:
  16056. last_eof_rc = (*io)->eof();
  16057. #if defined(OTL_PARANOID_EOF)
  16058. throw_if_eof_was_already_reached(last_eof_rc, "long int&");
  16059. #endif
  16060. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16061. (*io)->operator>>(l);
  16062. #else
  16063. (*io)->operator>><long, otl_var_long_int>(l);
  16064. #endif
  16065. break;
  16066. case otl_odbc_select_stream:
  16067. last_eof_rc = (*ss)->eof();
  16068. #if defined(OTL_PARANOID_EOF)
  16069. throw_if_eof_was_already_reached(last_eof_rc, "long int&");
  16070. #endif
  16071. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16072. (*ss)->operator>>(l);
  16073. #else
  16074. (*ss)->operator>><long, otl_var_long_int>(l);
  16075. #endif
  16076. break;
  16077. }
  16078. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16079. if ((*this).is_null())
  16080. l = OTL_SCAST(long int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16081. #endif
  16082. OTL_TRACE_WRITE(l, "operator >>", "long int&")
  16083. inc_next_ov();
  16084. return *this;
  16085. }
  16086. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  16087. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  16088. otl_stream &operator>>(OTL_NUMERIC_TYPE_1 &l) OTL_THROWS_OTL_EXCEPTION {
  16089. last_oper_was_read_op = true;
  16090. switch (shell->stream_type) {
  16091. case otl_odbc_no_stream:
  16092. break;
  16093. case otl_odbc_io_stream:
  16094. last_eof_rc = (*io)->eof();
  16095. #if defined(OTL_PARANOID_EOF)
  16096. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16097. #endif
  16098. #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR)
  16099. {
  16100. otl_var_desc *var_desc = describe_next_out_var();
  16101. if (var_desc) {
  16102. if (var_desc->ftype == otl_var_char) {
  16103. char temp_val[otl_numeric_type_1_str_size];
  16104. #if defined(OTL_UNICODE)
  16105. OTL_CHAR unitemp_val[otl_numeric_type_1_str_size];
  16106. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16107. OTL_CHAR *uc = unitemp_val;
  16108. char *c = temp_val;
  16109. while (*uc) {
  16110. *c = OTL_SCAST(char, *uc);
  16111. ++c;
  16112. ++uc;
  16113. }
  16114. *c = 0;
  16115. #else
  16116. (*ss)->operator>>(temp_val);
  16117. #endif
  16118. OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l);
  16119. } else {
  16120. #if !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  16121. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16122. (*io)->operator>>(l);
  16123. #else
  16124. (*io)->operator>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(l);
  16125. #endif
  16126. #else
  16127. char var_info[256];
  16128. otl_var_info_var2(var_desc->name, var_desc->ftype, var_info,
  16129. sizeof(var_info));
  16130. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  16131. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  16132. (*io)->get_stm_label() ? (*io)->get_stm_label()
  16133. : (*io)->get_stm_text(),
  16134. var_info)));
  16135. #endif
  16136. }
  16137. }
  16138. }
  16139. #else
  16140. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16141. (*io)->operator>>(l);
  16142. #else
  16143. (*io)->operator>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(l);
  16144. #endif
  16145. #endif
  16146. break;
  16147. case otl_odbc_select_stream:
  16148. last_eof_rc = (*ss)->eof();
  16149. #if defined(OTL_PARANOID_EOF)
  16150. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16151. #endif
  16152. #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR)
  16153. {
  16154. otl_var_desc *var_desc = describe_next_out_var();
  16155. if (var_desc) {
  16156. if (var_desc->ftype == otl_var_char) {
  16157. #if defined(OTL_UNICODE)
  16158. OTL_CHAR unitemp_val[otl_numeric_type_1_str_size];
  16159. char temp_val[otl_numeric_type_1_str_size];
  16160. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16161. OTL_CHAR *uc = unitemp_val;
  16162. char *c = temp_val;
  16163. while (*uc) {
  16164. *c = OTL_SCAST(char, *uc);
  16165. ++c;
  16166. ++uc;
  16167. }
  16168. *c = 0;
  16169. OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l);
  16170. #else
  16171. char temp_val[otl_numeric_type_1_str_size];
  16172. (*ss)->operator>>(temp_val);
  16173. OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l);
  16174. #endif
  16175. } else {
  16176. #if !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  16177. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16178. (*ss)->operator>>(l);
  16179. #else
  16180. (*ss)->operator>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(l);
  16181. #endif
  16182. #else
  16183. char var_info[256];
  16184. otl_var_info_var2(var_desc->name, var_desc->ftype, var_info,
  16185. sizeof(var_info));
  16186. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  16187. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  16188. (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  16189. : (*ss)->get_stm_text(),
  16190. var_info)));
  16191. #endif
  16192. }
  16193. }
  16194. }
  16195. #else
  16196. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16197. (*ss)->operator>>(l);
  16198. #else
  16199. (*ss)->operator>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(l);
  16200. #endif
  16201. #endif
  16202. break;
  16203. }
  16204. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16205. if ((*this).is_null())
  16206. l = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16207. #endif
  16208. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16209. // VC ++
  16210. {
  16211. char temp_str[otl_numeric_type_1_str_size];
  16212. OTL_NUMERIC_TYPE_1_TO_STR(l, temp_str);
  16213. OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_1_ID "&")
  16214. }
  16215. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16216. OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_1_ID "&")
  16217. #endif
  16218. inc_next_ov();
  16219. return *this;
  16220. }
  16221. #endif
  16222. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  16223. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  16224. otl_stream &operator>>(OTL_NUMERIC_TYPE_2 &l) OTL_THROWS_OTL_EXCEPTION {
  16225. last_oper_was_read_op = true;
  16226. switch (shell->stream_type) {
  16227. case otl_odbc_no_stream:
  16228. break;
  16229. case otl_odbc_io_stream:
  16230. last_eof_rc = (*io)->eof();
  16231. #if defined(OTL_PARANOID_EOF)
  16232. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16233. #endif
  16234. #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR)
  16235. {
  16236. otl_var_desc *var_desc = describe_next_out_var();
  16237. if (var_desc) {
  16238. if (var_desc->ftype == otl_var_char) {
  16239. char temp_val[otl_numeric_type_2_str_size];
  16240. #if defined(OTL_UNICODE)
  16241. OTL_CHAR unitemp_val[otl_numeric_type_2_str_size];
  16242. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16243. OTL_CHAR *uc = unitemp_val;
  16244. char *c = temp_val;
  16245. while (*uc) {
  16246. *c = OTL_SCAST(char, *uc);
  16247. ++c;
  16248. ++uc;
  16249. }
  16250. *c = 0;
  16251. #else
  16252. (*ss)->operator>>(temp_val);
  16253. #endif
  16254. OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l);
  16255. } else {
  16256. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16257. (*io)->operator>>(l);
  16258. #else
  16259. (*io)->operator>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(l);
  16260. #endif
  16261. }
  16262. }
  16263. }
  16264. #else
  16265. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16266. (*io)->operator>>(l);
  16267. #else
  16268. (*io)->operator>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(l);
  16269. #endif
  16270. #endif
  16271. break;
  16272. case otl_odbc_select_stream:
  16273. last_eof_rc = (*ss)->eof();
  16274. #if defined(OTL_PARANOID_EOF)
  16275. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16276. #endif
  16277. #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR)
  16278. {
  16279. otl_var_desc *var_desc = describe_next_out_var();
  16280. if (var_desc) {
  16281. if (var_desc->ftype == otl_var_char) {
  16282. #if defined(OTL_UNICODE)
  16283. OTL_CHAR unitemp_val[otl_numeric_type_2_str_size];
  16284. char temp_val[otl_numeric_type_2_str_size];
  16285. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16286. OTL_CHAR *uc = unitemp_val;
  16287. char *c = temp_val;
  16288. while (*uc) {
  16289. *c = OTL_SCAST(char, *uc);
  16290. ++c;
  16291. ++uc;
  16292. }
  16293. *c = 0;
  16294. OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l);
  16295. #else
  16296. char temp_val[otl_numeric_type_2_str_size];
  16297. (*ss)->operator>>(temp_val);
  16298. OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l);
  16299. #endif
  16300. } else {
  16301. #if !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS)
  16302. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16303. (*ss)->operator>>(l);
  16304. #else
  16305. (*ss)->operator>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(l);
  16306. #endif
  16307. #else
  16308. char var_info[256];
  16309. otl_var_info_var2(var_desc->name, var_desc->ftype, var_info,
  16310. sizeof(var_info));
  16311. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  16312. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  16313. (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  16314. : (*ss)->get_stm_text(),
  16315. var_info)));
  16316. #endif
  16317. }
  16318. }
  16319. }
  16320. #else
  16321. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16322. (*ss)->operator>>(l);
  16323. #else
  16324. (*ss)->operator>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(l);
  16325. #endif
  16326. #endif
  16327. break;
  16328. }
  16329. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16330. if ((*this).is_null())
  16331. l = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16332. #endif
  16333. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16334. // VC ++
  16335. {
  16336. char temp_str[otl_numeric_type_2_str_size];
  16337. OTL_NUMERIC_TYPE_2_TO_STR(l, temp_str);
  16338. OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_2_ID "&")
  16339. }
  16340. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16341. OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_2_ID "&")
  16342. #endif
  16343. inc_next_ov();
  16344. return *this;
  16345. }
  16346. #endif
  16347. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  16348. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  16349. otl_stream &operator>>(OTL_NUMERIC_TYPE_3 &l) OTL_THROWS_OTL_EXCEPTION {
  16350. last_oper_was_read_op = true;
  16351. switch (shell->stream_type) {
  16352. case otl_odbc_no_stream:
  16353. break;
  16354. case otl_odbc_io_stream:
  16355. last_eof_rc = (*io)->eof();
  16356. #if defined(OTL_PARANOID_EOF)
  16357. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16358. #endif
  16359. #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR)
  16360. {
  16361. otl_var_desc *var_desc = describe_next_out_var();
  16362. if (var_desc) {
  16363. if (var_desc->ftype == otl_var_char) {
  16364. char temp_val[otl_numeric_type_3_str_size];
  16365. #if defined(OTL_UNICODE)
  16366. OTL_CHAR unitemp_val[otl_numeric_type_3_str_size];
  16367. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16368. OTL_CHAR *uc = unitemp_val;
  16369. char *c = temp_val;
  16370. while (*uc) {
  16371. *c = OTL_SCAST(char, *uc);
  16372. ++c;
  16373. ++uc;
  16374. }
  16375. *c = 0;
  16376. #else
  16377. (*ss)->operator>>(temp_val);
  16378. #endif
  16379. OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l);
  16380. } else {
  16381. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16382. (*io)->operator>>(l);
  16383. #else
  16384. (*io)->operator>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(l);
  16385. #endif
  16386. }
  16387. }
  16388. }
  16389. #else
  16390. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16391. (*io)->operator>>(l);
  16392. #else
  16393. (*io)->operator>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(l);
  16394. #endif
  16395. #endif
  16396. break;
  16397. case otl_odbc_select_stream:
  16398. last_eof_rc = (*ss)->eof();
  16399. #if defined(OTL_PARANOID_EOF)
  16400. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  16401. #endif
  16402. #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR)
  16403. {
  16404. otl_var_desc *var_desc = describe_next_out_var();
  16405. if (var_desc) {
  16406. if (var_desc->ftype == otl_var_char) {
  16407. #if defined(OTL_UNICODE)
  16408. OTL_CHAR unitemp_val[otl_numeric_type_3_str_size];
  16409. char temp_val[otl_numeric_type_3_str_size];
  16410. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16411. OTL_CHAR *uc = unitemp_val;
  16412. char *c = temp_val;
  16413. while (*uc) {
  16414. *c = OTL_SCAST(char, *uc);
  16415. ++c;
  16416. ++uc;
  16417. }
  16418. *c = 0;
  16419. OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l);
  16420. #else
  16421. char temp_val[otl_numeric_type_3_str_size];
  16422. (*ss)->operator>>(temp_val);
  16423. OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l);
  16424. #endif
  16425. } else {
  16426. #if !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  16427. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16428. (*ss)->operator>>(l);
  16429. #else
  16430. (*ss)->operator>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(l);
  16431. #endif
  16432. #else
  16433. char var_info[256];
  16434. otl_var_info_var2(var_desc->name, var_desc->ftype, var_info,
  16435. sizeof(var_info));
  16436. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  16437. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  16438. (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  16439. : (*ss)->get_stm_text(),
  16440. var_info)));
  16441. #endif
  16442. }
  16443. }
  16444. }
  16445. #else
  16446. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16447. (*ss)->operator>>(l);
  16448. #else
  16449. (*ss)->operator>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(l);
  16450. #endif
  16451. #endif
  16452. break;
  16453. }
  16454. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16455. if ((*this).is_null())
  16456. l = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16457. #endif
  16458. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16459. // VC ++
  16460. {
  16461. char temp_str[otl_numeric_type_3_str_size];
  16462. OTL_NUMERIC_TYPE_3_TO_STR(l, temp_str);
  16463. OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_3_ID "&")
  16464. }
  16465. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16466. OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_3_ID "&")
  16467. #endif
  16468. inc_next_ov();
  16469. return *this;
  16470. }
  16471. #endif
  16472. #if defined(OTL_BIGINT)
  16473. otl_stream &operator>>(OTL_BIGINT &l) OTL_THROWS_OTL_EXCEPTION {
  16474. last_oper_was_read_op = true;
  16475. switch (shell->stream_type) {
  16476. case otl_odbc_no_stream:
  16477. break;
  16478. case otl_odbc_io_stream:
  16479. last_eof_rc = (*io)->eof();
  16480. #if defined(OTL_PARANOID_EOF)
  16481. throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&");
  16482. #endif
  16483. #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR)
  16484. {
  16485. otl_var_desc *var_desc = describe_next_out_var();
  16486. if (var_desc) {
  16487. if (var_desc->ftype == otl_var_char) {
  16488. char temp_val[otl_bigint_str_size];
  16489. #if defined(OTL_UNICODE)
  16490. OTL_CHAR unitemp_val[otl_bigint_str_size];
  16491. (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val));
  16492. OTL_CHAR *uc = unitemp_val;
  16493. char *c = temp_val;
  16494. while (*uc) {
  16495. *c = OTL_SCAST(char, *uc);
  16496. ++c;
  16497. ++uc;
  16498. }
  16499. *c = 0;
  16500. #else
  16501. (*ss)->operator>>(temp_val);
  16502. #endif
  16503. OTL_STR_TO_BIGINT(temp_val, l);
  16504. } else
  16505. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16506. (*io)->operator>>(l);
  16507. #else
  16508. (*io)->operator>><OTL_BIGINT, otl_var_bigint>(l);
  16509. #endif
  16510. }
  16511. }
  16512. #else
  16513. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16514. (*io)->operator>>(l);
  16515. #else
  16516. (*io)->operator>><OTL_BIGINT, otl_var_bigint>(l);
  16517. #endif
  16518. #endif
  16519. break;
  16520. case otl_odbc_select_stream:
  16521. last_eof_rc = (*ss)->eof();
  16522. #if defined(OTL_PARANOID_EOF)
  16523. throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&");
  16524. #endif
  16525. #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR)
  16526. {
  16527. otl_var_desc *var_desc = describe_next_out_var();
  16528. if (var_desc) {
  16529. if (var_desc->ftype == otl_var_char) {
  16530. char temp_val[otl_bigint_str_size];
  16531. (*ss)->operator>>(temp_val);
  16532. OTL_STR_TO_BIGINT(temp_val, l);
  16533. } else
  16534. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16535. (*ss)->operator>>(l);
  16536. #else
  16537. (*ss)->operator>><OTL_BIGINT, otl_var_bigint>(l);
  16538. #endif
  16539. }
  16540. }
  16541. #else
  16542. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16543. (*ss)->operator>>(l);
  16544. #else
  16545. (*ss)->operator>><OTL_BIGINT, otl_var_bigint>(l);
  16546. #endif
  16547. #endif
  16548. break;
  16549. }
  16550. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16551. if ((*this).is_null())
  16552. l = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16553. #endif
  16554. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16555. // VC ++
  16556. {
  16557. char temp_str[otl_bigint_str_size];
  16558. _i64toa(l, temp_str, 10);
  16559. OTL_TRACE_WRITE(temp_str, "operator >>", "BIGINT&")
  16560. }
  16561. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16562. OTL_TRACE_WRITE(l, "operator >>", "BIGINT&")
  16563. #endif
  16564. inc_next_ov();
  16565. return *this;
  16566. }
  16567. #endif
  16568. #if defined(OTL_UBIGINT)
  16569. otl_stream &operator>>(OTL_UBIGINT &l) OTL_THROWS_OTL_EXCEPTION {
  16570. last_oper_was_read_op = true;
  16571. switch (shell->stream_type) {
  16572. case otl_odbc_no_stream:
  16573. break;
  16574. case otl_odbc_io_stream:
  16575. last_eof_rc = (*io)->eof();
  16576. #if defined(OTL_PARANOID_EOF)
  16577. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&");
  16578. #endif
  16579. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16580. (*io)->operator>>(l);
  16581. #else
  16582. (*io)->operator>><OTL_UBIGINT, otl_var_ubigint>(l);
  16583. #endif
  16584. break;
  16585. case otl_odbc_select_stream:
  16586. last_eof_rc = (*ss)->eof();
  16587. #if defined(OTL_PARANOID_EOF)
  16588. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&");
  16589. #endif
  16590. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16591. (*ss)->operator>>(l);
  16592. #else
  16593. (*ss)->operator>><OTL_UBIGINT, otl_var_ubigint>(l);
  16594. #endif
  16595. break;
  16596. }
  16597. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16598. if ((*this).is_null())
  16599. l = OTL_SCAST(OTL_UBIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16600. #endif
  16601. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16602. // VC ++
  16603. {
  16604. char temp_str[otl_ubigint_str_size];
  16605. _ui64toa(l, temp_str, 10);
  16606. OTL_TRACE_WRITE(temp_str, "operator >>", "UBIGINT&")
  16607. }
  16608. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  16609. OTL_TRACE_WRITE(l, "operator >>", "UBIGINT&")
  16610. #endif
  16611. inc_next_ov();
  16612. return *this;
  16613. }
  16614. #endif
  16615. otl_stream &operator>>(float &f) OTL_THROWS_OTL_EXCEPTION {
  16616. last_oper_was_read_op = true;
  16617. switch (shell->stream_type) {
  16618. case otl_odbc_no_stream:
  16619. break;
  16620. case otl_odbc_io_stream:
  16621. last_eof_rc = (*io)->eof();
  16622. #if defined(OTL_PARANOID_EOF)
  16623. throw_if_eof_was_already_reached(last_eof_rc, "float&");
  16624. #endif
  16625. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16626. (*io)->operator>>(f);
  16627. #else
  16628. (*io)->operator>><float, otl_var_float>(f);
  16629. #endif
  16630. break;
  16631. case otl_odbc_select_stream:
  16632. last_eof_rc = (*ss)->eof();
  16633. #if defined(OTL_PARANOID_EOF)
  16634. throw_if_eof_was_already_reached(last_eof_rc, "float&");
  16635. #endif
  16636. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16637. (*ss)->operator>>(f);
  16638. #else
  16639. (*ss)->operator>><float, otl_var_float>(f);
  16640. #endif
  16641. break;
  16642. }
  16643. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16644. if ((*this).is_null())
  16645. f = OTL_SCAST(float, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16646. #endif
  16647. OTL_TRACE_WRITE(f, "operator >>", "float&")
  16648. inc_next_ov();
  16649. return *this;
  16650. }
  16651. otl_stream &operator>>(double &d) OTL_THROWS_OTL_EXCEPTION {
  16652. last_oper_was_read_op = true;
  16653. switch (shell->stream_type) {
  16654. case otl_odbc_no_stream:
  16655. break;
  16656. case otl_odbc_io_stream:
  16657. last_eof_rc = (*io)->eof();
  16658. #if defined(OTL_PARANOID_EOF)
  16659. throw_if_eof_was_already_reached(last_eof_rc, "double&");
  16660. #endif
  16661. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16662. (*io)->operator>>(d);
  16663. #else
  16664. (*io)->operator>><double, otl_var_double>(d);
  16665. #endif
  16666. break;
  16667. case otl_odbc_select_stream:
  16668. last_eof_rc = (*ss)->eof();
  16669. #if defined(OTL_PARANOID_EOF)
  16670. throw_if_eof_was_already_reached(last_eof_rc, "double&");
  16671. #endif
  16672. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16673. (*ss)->operator>>(d);
  16674. #else
  16675. (*ss)->operator>><double, otl_var_double>(d);
  16676. #endif
  16677. break;
  16678. }
  16679. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  16680. if ((*this).is_null())
  16681. d = OTL_SCAST(double, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  16682. #endif
  16683. OTL_TRACE_WRITE(d, "operator >>", "double&")
  16684. inc_next_ov();
  16685. return *this;
  16686. }
  16687. otl_stream &operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION {
  16688. last_oper_was_read_op = true;
  16689. switch (shell->stream_type) {
  16690. case otl_odbc_no_stream:
  16691. break;
  16692. case otl_odbc_io_stream:
  16693. last_eof_rc = (*io)->eof();
  16694. #if defined(OTL_PARANOID_EOF)
  16695. throw_if_eof_was_already_reached(last_eof_rc, "otl_long_string&");
  16696. #endif
  16697. (*io)->operator>>(s);
  16698. break;
  16699. case otl_odbc_select_stream:
  16700. last_eof_rc = (*ss)->eof();
  16701. #if defined(OTL_PARANOID_EOF)
  16702. throw_if_eof_was_already_reached(last_eof_rc, "otl_long_string&");
  16703. #endif
  16704. (*ss)->operator>>(s);
  16705. break;
  16706. }
  16707. OTL_TRACE_WRITE(" string length: " << s.len(), "operator >>",
  16708. "otl_long_string&")
  16709. inc_next_ov();
  16710. return *this;
  16711. }
  16712. otl_stream &operator<<(const char c) OTL_THROWS_OTL_EXCEPTION {
  16713. last_oper_was_read_op = false;
  16714. reset_end_marker();
  16715. switch (shell->stream_type) {
  16716. case otl_odbc_no_stream:
  16717. break;
  16718. case otl_odbc_io_stream:
  16719. (*io)->operator<<(c);
  16720. break;
  16721. case otl_odbc_select_stream:
  16722. (*ss)->operator<<(c);
  16723. if (!(*ov) && (*ss)->get_sl())
  16724. create_var_desc();
  16725. break;
  16726. }
  16727. OTL_TRACE_READ("'" << c << "'", "operator <<", "char");
  16728. inc_next_iov();
  16729. return *this;
  16730. }
  16731. otl_stream &operator<<(const unsigned char c) OTL_THROWS_OTL_EXCEPTION {
  16732. last_oper_was_read_op = false;
  16733. reset_end_marker();
  16734. OTL_TRACE_READ("'" << c << "'", "operator <<", "unsigned char");
  16735. switch (shell->stream_type) {
  16736. case otl_odbc_no_stream:
  16737. break;
  16738. case otl_odbc_io_stream:
  16739. (*io)->operator<<(c);
  16740. break;
  16741. case otl_odbc_select_stream:
  16742. (*ss)->operator<<(c);
  16743. if (!(*ov) && (*ss)->get_sl())
  16744. create_var_desc();
  16745. break;
  16746. }
  16747. inc_next_iov();
  16748. return *this;
  16749. }
  16750. #if defined(OTL_UNICODE)
  16751. otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE *s)
  16752. OTL_THROWS_OTL_EXCEPTION {
  16753. last_oper_was_read_op = false;
  16754. reset_end_marker();
  16755. OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"",
  16756. "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*");
  16757. switch (shell->stream_type) {
  16758. case otl_odbc_no_stream:
  16759. break;
  16760. case otl_odbc_io_stream:
  16761. (*io)->operator<<(OTL_RCAST(const unsigned char *, s));
  16762. break;
  16763. case otl_odbc_select_stream:
  16764. (*ss)->operator<<(OTL_RCAST(const unsigned char *, s));
  16765. if (!(*ov) && (*ss)->get_sl())
  16766. create_var_desc();
  16767. break;
  16768. }
  16769. inc_next_iov();
  16770. return *this;
  16771. }
  16772. otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE c)
  16773. OTL_THROWS_OTL_EXCEPTION {
  16774. OTL_UNICODE_CHAR_TYPE s[2];
  16775. s[0] = c;
  16776. s[1] = 0;
  16777. (*this) << s;
  16778. return *this;
  16779. }
  16780. #endif
  16781. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  16782. otl_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s)
  16783. OTL_THROWS_OTL_EXCEPTION {
  16784. last_oper_was_read_op = false;
  16785. reset_end_marker();
  16786. #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)
  16787. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_THIRD_PARTY_STRING_VIEW_CLASS");
  16788. #else
  16789. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STD_STRING_VIEW_CLASS");
  16790. #endif
  16791. switch (shell->stream_type) {
  16792. case otl_odbc_no_stream:
  16793. break;
  16794. case otl_odbc_io_stream:
  16795. (*io)->operator<<(s);
  16796. break;
  16797. case otl_odbc_select_stream:
  16798. (*ss)->operator<<(s);
  16799. if (!(*ov) && (*ss)->get_sl())
  16800. create_var_desc();
  16801. break;
  16802. }
  16803. inc_next_iov();
  16804. return *this;
  16805. }
  16806. #endif
  16807. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  16808. otl_stream &operator<<(const OTL_STRING_CONTAINER &s)
  16809. OTL_THROWS_OTL_EXCEPTION {
  16810. last_oper_was_read_op = false;
  16811. reset_end_marker();
  16812. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STRING_CONTAINER&");
  16813. switch (shell->stream_type) {
  16814. case otl_odbc_no_stream:
  16815. break;
  16816. case otl_odbc_io_stream:
  16817. (*io)->operator<<(s);
  16818. break;
  16819. case otl_odbc_select_stream:
  16820. (*ss)->operator<<(s);
  16821. if (!(*ov) && (*ss)->get_sl())
  16822. create_var_desc();
  16823. break;
  16824. }
  16825. inc_next_iov();
  16826. return *this;
  16827. }
  16828. #endif
  16829. #if defined(OTL_UNICODE_STRING_TYPE)
  16830. otl_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s)
  16831. OTL_THROWS_OTL_EXCEPTION {
  16832. last_oper_was_read_op = false;
  16833. reset_end_marker();
  16834. OTL_TRACE_READ("\"" << s.c_str() << "\"", "operator <<",
  16835. "OTL_UNICODE_STRING_TYPE&");
  16836. switch (shell->stream_type) {
  16837. case otl_odbc_no_stream:
  16838. break;
  16839. case otl_odbc_io_stream:
  16840. (*io)->operator<<(s);
  16841. break;
  16842. case otl_odbc_select_stream:
  16843. (*ss)->operator<<(s);
  16844. if (!(*ov) && (*ss)->get_sl())
  16845. create_var_desc();
  16846. break;
  16847. }
  16848. inc_next_iov();
  16849. return *this;
  16850. }
  16851. #endif
  16852. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  16853. otl_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s)
  16854. OTL_THROWS_OTL_EXCEPTION {
  16855. last_oper_was_read_op = false;
  16856. reset_end_marker();
  16857. #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)
  16858. OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<",
  16859. "OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS");
  16860. #else
  16861. OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<",
  16862. "OTL_STD_UNICODE_STRING_VIEW_CLASS");
  16863. #endif
  16864. switch (shell->stream_type) {
  16865. case otl_odbc_no_stream:
  16866. break;
  16867. case otl_odbc_io_stream:
  16868. (*io)->operator<<(s);
  16869. break;
  16870. case otl_odbc_select_stream:
  16871. (*ss)->operator<<(s);
  16872. if (!(*ov) && (*ss)->get_sl())
  16873. create_var_desc();
  16874. break;
  16875. }
  16876. inc_next_iov();
  16877. return *this;
  16878. }
  16879. #endif
  16880. #if !defined(OTL_UNICODE)
  16881. otl_stream &operator<<(const char *s) OTL_THROWS_OTL_EXCEPTION {
  16882. last_oper_was_read_op = false;
  16883. reset_end_marker();
  16884. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "char*");
  16885. switch (shell->stream_type) {
  16886. case otl_odbc_no_stream:
  16887. break;
  16888. case otl_odbc_io_stream:
  16889. (*io)->operator<<(s);
  16890. break;
  16891. case otl_odbc_select_stream:
  16892. (*ss)->operator<<(s);
  16893. if (!(*ov) && (*ss)->get_sl())
  16894. create_var_desc();
  16895. break;
  16896. }
  16897. inc_next_iov();
  16898. return *this;
  16899. }
  16900. #endif
  16901. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  16902. template<const size_t N>
  16903. otl_stream &operator<<(const std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
  16904. last_oper_was_read_op = false;
  16905. reset_end_marker();
  16906. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char,...>&");
  16907. switch (shell->stream_type) {
  16908. case otl_odbc_no_stream:
  16909. break;
  16910. case otl_odbc_io_stream:
  16911. (*io)->operator<<(s);
  16912. break;
  16913. case otl_odbc_select_stream:
  16914. (*ss)->operator<<(s);
  16915. if (!(*ov) && (*ss)->get_sl())
  16916. create_var_desc();
  16917. break;
  16918. }
  16919. inc_next_iov();
  16920. return *this;
  16921. }
  16922. #endif
  16923. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  16924. template<const size_t N>
  16925. otl_stream &operator<<(const std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
  16926. last_oper_was_read_op = false;
  16927. reset_end_marker();
  16928. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char16_t,...>&");
  16929. switch (shell->stream_type) {
  16930. case otl_odbc_no_stream:
  16931. break;
  16932. case otl_odbc_io_stream:
  16933. (*io)->operator<<(s);
  16934. break;
  16935. case otl_odbc_select_stream:
  16936. (*ss)->operator<<(s);
  16937. if (!(*ov) && (*ss)->get_sl())
  16938. create_var_desc();
  16939. break;
  16940. }
  16941. inc_next_iov();
  16942. return *this;
  16943. }
  16944. #endif
  16945. otl_stream &operator<<(const unsigned char *s) OTL_THROWS_OTL_EXCEPTION {
  16946. last_oper_was_read_op = false;
  16947. reset_end_marker();
  16948. #if defined(OTL_UNICODE)
  16949. OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"",
  16950. "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*");
  16951. #else
  16952. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "unsigned char*");
  16953. #endif
  16954. switch (shell->stream_type) {
  16955. case otl_odbc_no_stream:
  16956. break;
  16957. case otl_odbc_io_stream:
  16958. (*io)->operator<<(s);
  16959. break;
  16960. case otl_odbc_select_stream:
  16961. (*ss)->operator<<(s);
  16962. if (!(*ov) && (*ss)->get_sl())
  16963. create_var_desc();
  16964. break;
  16965. }
  16966. inc_next_iov();
  16967. return *this;
  16968. }
  16969. otl_stream &operator<<(const int n) OTL_THROWS_OTL_EXCEPTION {
  16970. last_oper_was_read_op = false;
  16971. reset_end_marker();
  16972. OTL_TRACE_READ(n, "operator <<", "int");
  16973. switch (shell->stream_type) {
  16974. case otl_odbc_no_stream:
  16975. break;
  16976. case otl_odbc_io_stream:
  16977. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16978. (*io)->operator<<(n);
  16979. #else
  16980. (*io)->operator<<<int, otl_var_int>(n);
  16981. #endif
  16982. break;
  16983. case otl_odbc_select_stream:
  16984. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  16985. (*ss)->operator<<(n);
  16986. #else
  16987. (*ss)->operator<<<int, otl_var_int>(n);
  16988. #endif
  16989. if (!(*ov) && (*ss)->get_sl())
  16990. create_var_desc();
  16991. break;
  16992. }
  16993. inc_next_iov();
  16994. return *this;
  16995. }
  16996. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  16997. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  16998. otl_stream &operator<<(const OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION {
  16999. last_oper_was_read_op = false;
  17000. reset_end_marker();
  17001. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17002. // VC ++
  17003. {
  17004. char temp_str[otl_numeric_type_1_str_size];
  17005. OTL_NUMERIC_TYPE_1_TO_STR(n, temp_str);
  17006. OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_1_ID)
  17007. }
  17008. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17009. OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_1_ID);
  17010. #endif
  17011. switch (shell->stream_type) {
  17012. case otl_odbc_no_stream:
  17013. break;
  17014. case otl_odbc_io_stream:
  17015. #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR)
  17016. {
  17017. otl_var_desc *var_desc = describe_next_in_var();
  17018. if (var_desc) {
  17019. if (var_desc->ftype == otl_var_char) {
  17020. char temp_val[otl_numeric_type_1_str_size];
  17021. OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val);
  17022. #if defined(OTL_UNICODE)
  17023. OTL_CHAR unitemp_val[otl_numeric_type_1_str_size];
  17024. OTL_CHAR *uc = unitemp_val;
  17025. char *c = temp_val;
  17026. while (*c) {
  17027. *uc = OTL_SCAST(OTL_CHAR, *c);
  17028. ++c;
  17029. ++uc;
  17030. }
  17031. *uc = 0;
  17032. (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val));
  17033. #else
  17034. (*io)->operator<<(temp_val);
  17035. #endif
  17036. } else {
  17037. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17038. (*io)->operator<<(n);
  17039. #else
  17040. (*io)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
  17041. #endif
  17042. }
  17043. }
  17044. }
  17045. #else
  17046. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17047. (*io)->operator<<(n);
  17048. #else
  17049. (*io)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
  17050. #endif
  17051. #endif
  17052. break;
  17053. case otl_odbc_select_stream:
  17054. #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR)
  17055. {
  17056. otl_var_desc *var_desc = describe_next_in_var();
  17057. if (var_desc) {
  17058. if (var_desc->ftype == otl_var_char) {
  17059. char temp_val[otl_numeric_type_1_str_size];
  17060. OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val);
  17061. (*ss)->operator<<(temp_val);
  17062. } else {
  17063. #if 1
  17064. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17065. (*ss)->operator<<(n);
  17066. #else
  17067. (*ss)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
  17068. #endif
  17069. #endif
  17070. }
  17071. }
  17072. }
  17073. #else
  17074. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17075. (*ss)->operator<<(n);
  17076. #else
  17077. (*ss)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
  17078. #endif
  17079. #endif
  17080. if (!(*ov) && (*ss)->get_sl())
  17081. create_var_desc();
  17082. break;
  17083. }
  17084. inc_next_iov();
  17085. return *this;
  17086. }
  17087. #endif
  17088. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  17089. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  17090. otl_stream &operator<<(const OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION {
  17091. last_oper_was_read_op = false;
  17092. reset_end_marker();
  17093. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17094. // VC ++
  17095. {
  17096. char temp_str[otl_numeric_type_2_str_size];
  17097. OTL_NUMERIC_TYPE_2_TO_STR(n, temp_str);
  17098. OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_2_ID)
  17099. }
  17100. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17101. OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_2_ID);
  17102. #endif
  17103. switch (shell->stream_type) {
  17104. case otl_odbc_no_stream:
  17105. break;
  17106. case otl_odbc_io_stream:
  17107. #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR)
  17108. {
  17109. otl_var_desc *var_desc = describe_next_in_var();
  17110. if (var_desc) {
  17111. if (var_desc->ftype == otl_var_char) {
  17112. char temp_val[otl_numeric_type_2_str_size];
  17113. OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val);
  17114. #if defined(OTL_UNICODE)
  17115. OTL_CHAR unitemp_val[otl_numeric_type_2_str_size];
  17116. OTL_CHAR *uc = unitemp_val;
  17117. char *c = temp_val;
  17118. while (*c) {
  17119. *uc = OTL_SCAST(OTL_CHAR, *c);
  17120. ++c;
  17121. ++uc;
  17122. }
  17123. *uc = 0;
  17124. (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val));
  17125. #else
  17126. (*io)->operator<<(temp_val);
  17127. #endif
  17128. } else {
  17129. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17130. (*io)->operator<<(n);
  17131. #else
  17132. (*io)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
  17133. #endif
  17134. }
  17135. }
  17136. }
  17137. #else
  17138. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17139. (*io)->operator<<(n);
  17140. #else
  17141. (*io)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
  17142. #endif
  17143. #endif
  17144. break;
  17145. case otl_odbc_select_stream:
  17146. #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR)
  17147. {
  17148. otl_var_desc *var_desc = describe_next_in_var();
  17149. if (var_desc) {
  17150. if (var_desc->ftype == otl_var_char) {
  17151. char temp_val[otl_numeric_type_2_str_size];
  17152. OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val);
  17153. (*ss)->operator<<(temp_val);
  17154. } else {
  17155. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17156. (*ss)->operator<<(n);
  17157. #else
  17158. (*ss)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
  17159. #endif
  17160. }
  17161. }
  17162. }
  17163. #else
  17164. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17165. (*ss)->operator<<(n);
  17166. #else
  17167. (*ss)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
  17168. #endif
  17169. #endif
  17170. if (!(*ov) && (*ss)->get_sl())
  17171. create_var_desc();
  17172. break;
  17173. }
  17174. inc_next_iov();
  17175. return *this;
  17176. }
  17177. #endif
  17178. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  17179. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  17180. otl_stream &operator<<(const OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION {
  17181. last_oper_was_read_op = false;
  17182. reset_end_marker();
  17183. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17184. // VC ++
  17185. {
  17186. char temp_str[otl_numeric_type_3_str_size];
  17187. OTL_NUMERIC_TYPE_3_TO_STR(n, temp_str);
  17188. OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_3_ID)
  17189. }
  17190. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17191. OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_3_ID);
  17192. #endif
  17193. switch (shell->stream_type) {
  17194. case otl_odbc_no_stream:
  17195. break;
  17196. case otl_odbc_io_stream:
  17197. #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR)
  17198. {
  17199. otl_var_desc *var_desc = describe_next_in_var();
  17200. if (var_desc) {
  17201. if (var_desc->ftype == otl_var_char) {
  17202. char temp_val[otl_numeric_type_3_str_size];
  17203. OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val);
  17204. #if defined(OTL_UNICODE)
  17205. OTL_CHAR unitemp_val[otl_numeric_type_3_str_size];
  17206. OTL_CHAR *uc = unitemp_val;
  17207. char *c = temp_val;
  17208. while (*c) {
  17209. *uc = OTL_SCAST(OTL_CHAR, *c);
  17210. ++c;
  17211. ++uc;
  17212. }
  17213. *uc = 0;
  17214. (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val));
  17215. #else
  17216. (*io)->operator<<(temp_val);
  17217. #endif
  17218. } else {
  17219. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17220. (*io)->operator<<(n);
  17221. #else
  17222. (*io)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
  17223. #endif
  17224. }
  17225. }
  17226. }
  17227. #else
  17228. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17229. (*io)->operator<<(n);
  17230. #else
  17231. (*io)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
  17232. #endif
  17233. #endif
  17234. break;
  17235. case otl_odbc_select_stream:
  17236. #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR)
  17237. {
  17238. otl_var_desc *var_desc = describe_next_in_var();
  17239. if (var_desc) {
  17240. if (var_desc->ftype == otl_var_char) {
  17241. char temp_val[otl_numeric_type_3_str_size];
  17242. OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val);
  17243. (*ss)->operator<<(temp_val);
  17244. } else {
  17245. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17246. (*ss)->operator<<(n);
  17247. #else
  17248. (*ss)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
  17249. #endif
  17250. }
  17251. }
  17252. }
  17253. #else
  17254. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17255. (*ss)->operator<<(n);
  17256. #else
  17257. (*ss)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
  17258. #endif
  17259. #endif
  17260. if (!(*ov) && (*ss)->get_sl())
  17261. create_var_desc();
  17262. break;
  17263. }
  17264. inc_next_iov();
  17265. return *this;
  17266. }
  17267. #endif
  17268. #if defined(OTL_BIGINT)
  17269. otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION {
  17270. last_oper_was_read_op = false;
  17271. reset_end_marker();
  17272. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17273. // VC ++
  17274. {
  17275. char temp_str[otl_bigint_str_size];
  17276. _i64toa(n, temp_str, 10);
  17277. OTL_TRACE_READ(temp_str, "operator <<", "BIGINT")
  17278. }
  17279. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17280. OTL_TRACE_READ(n, "operator <<", "BIGINT");
  17281. #endif
  17282. switch (shell->stream_type) {
  17283. case otl_odbc_no_stream:
  17284. break;
  17285. case otl_odbc_io_stream:
  17286. #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR)
  17287. {
  17288. otl_var_desc *var_desc = describe_next_in_var();
  17289. if (var_desc) {
  17290. if (var_desc->ftype == otl_var_char) {
  17291. char temp_val[otl_bigint_str_size];
  17292. OTL_BIGINT_TO_STR(n, temp_val);
  17293. #if defined(OTL_UNICODE)
  17294. OTL_CHAR unitemp_val[otl_bigint_str_size];
  17295. OTL_CHAR *uc = unitemp_val;
  17296. char *c = temp_val;
  17297. while (*c) {
  17298. *uc = OTL_SCAST(OTL_CHAR, *c);
  17299. ++c;
  17300. ++uc;
  17301. }
  17302. *uc = 0;
  17303. (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val));
  17304. #else
  17305. (*io)->operator<<(temp_val);
  17306. #endif
  17307. } else
  17308. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17309. (*io)->operator<<(n);
  17310. #else
  17311. (*io)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  17312. #endif
  17313. }
  17314. }
  17315. #else
  17316. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17317. (*io)->operator<<(n);
  17318. #else
  17319. (*io)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  17320. #endif
  17321. #endif
  17322. break;
  17323. case otl_odbc_select_stream:
  17324. #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR)
  17325. {
  17326. otl_var_desc *var_desc = describe_next_in_var();
  17327. if (var_desc) {
  17328. if (var_desc->ftype == otl_var_char) {
  17329. char temp_val[otl_bigint_str_size];
  17330. OTL_BIGINT_TO_STR(n, temp_val);
  17331. (*ss)->operator<<(temp_val);
  17332. } else
  17333. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17334. (*ss)->operator<<(n);
  17335. #else
  17336. (*ss)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  17337. #endif
  17338. }
  17339. }
  17340. #else
  17341. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17342. (*ss)->operator<<(n);
  17343. #else
  17344. (*ss)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  17345. #endif
  17346. #endif
  17347. if (!(*ov) && (*ss)->get_sl())
  17348. create_var_desc();
  17349. break;
  17350. }
  17351. inc_next_iov();
  17352. return *this;
  17353. }
  17354. #endif
  17355. #if defined(OTL_UBIGINT)
  17356. otl_stream &operator<<(const OTL_UBIGINT n) OTL_THROWS_OTL_EXCEPTION {
  17357. last_oper_was_read_op = false;
  17358. reset_end_marker();
  17359. #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17360. // VC ++
  17361. {
  17362. char temp_str[otl_ubigint_str_size];
  17363. _ui64toa(n, temp_str, 10);
  17364. OTL_TRACE_READ(temp_str, "operator <<", "UBIGINT")
  17365. }
  17366. #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL)
  17367. OTL_TRACE_READ(n, "operator <<", "UBIGINT");
  17368. #endif
  17369. switch (shell->stream_type) {
  17370. case otl_odbc_no_stream:
  17371. break;
  17372. case otl_odbc_io_stream:
  17373. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17374. (*io)->operator<<(n);
  17375. #else
  17376. (*io)->operator<<<OTL_UBIGINT, otl_var_ubigint>(n);
  17377. #endif
  17378. break;
  17379. case otl_odbc_select_stream:
  17380. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17381. (*ss)->operator<<(n);
  17382. #else
  17383. (*ss)->operator<<<OTL_UBIGINT, otl_var_ubigint>(n);
  17384. #endif
  17385. if (!(*ov) && (*ss)->get_sl())
  17386. create_var_desc();
  17387. break;
  17388. }
  17389. inc_next_iov();
  17390. return *this;
  17391. }
  17392. #endif
  17393. otl_stream &operator<<(const unsigned u) OTL_THROWS_OTL_EXCEPTION {
  17394. last_oper_was_read_op = false;
  17395. reset_end_marker();
  17396. OTL_TRACE_READ(u, "operator <<", "unsigned int");
  17397. switch (shell->stream_type) {
  17398. case otl_odbc_no_stream:
  17399. break;
  17400. case otl_odbc_io_stream:
  17401. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17402. (*io)->operator<<(u);
  17403. #else
  17404. (*io)->operator<<<unsigned, otl_var_unsigned_int>(u);
  17405. #endif
  17406. break;
  17407. case otl_odbc_select_stream:
  17408. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17409. (*ss)->operator<<(u);
  17410. #else
  17411. (*ss)->operator<<<unsigned, otl_var_unsigned_int>(u);
  17412. #endif
  17413. if (!(*ov) && (*ss)->get_sl())
  17414. create_var_desc();
  17415. break;
  17416. }
  17417. inc_next_iov();
  17418. return *this;
  17419. }
  17420. otl_stream &operator<<(const short sh) OTL_THROWS_OTL_EXCEPTION {
  17421. last_oper_was_read_op = false;
  17422. reset_end_marker();
  17423. OTL_TRACE_READ(sh, "operator <<", "short int");
  17424. switch (shell->stream_type) {
  17425. case otl_odbc_no_stream:
  17426. break;
  17427. case otl_odbc_io_stream:
  17428. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17429. (*io)->operator<<(sh);
  17430. #else
  17431. (*io)->operator<<<short, otl_var_short>(sh);
  17432. #endif
  17433. break;
  17434. case otl_odbc_select_stream:
  17435. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17436. (*ss)->operator<<(sh);
  17437. #else
  17438. (*ss)->operator<<<short, otl_var_short>(sh);
  17439. #endif
  17440. if (!(*ov) && (*ss)->get_sl())
  17441. create_var_desc();
  17442. break;
  17443. }
  17444. inc_next_iov();
  17445. return *this;
  17446. }
  17447. otl_stream &operator<<(const long int l) OTL_THROWS_OTL_EXCEPTION {
  17448. last_oper_was_read_op = false;
  17449. reset_end_marker();
  17450. OTL_TRACE_READ(l, "operator <<", "long int");
  17451. switch (shell->stream_type) {
  17452. case otl_odbc_no_stream:
  17453. break;
  17454. case otl_odbc_io_stream:
  17455. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17456. (*io)->operator<<(l);
  17457. #else
  17458. (*io)->operator<<<long, otl_var_long_int>(l);
  17459. #endif
  17460. break;
  17461. case otl_odbc_select_stream:
  17462. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17463. (*ss)->operator<<(l);
  17464. #else
  17465. (*ss)->operator<<<long, otl_var_long_int>(l);
  17466. #endif
  17467. if (!(*ov) && (*ss)->get_sl())
  17468. create_var_desc();
  17469. break;
  17470. }
  17471. inc_next_iov();
  17472. return *this;
  17473. }
  17474. otl_stream &operator<<(const float f) OTL_THROWS_OTL_EXCEPTION {
  17475. last_oper_was_read_op = false;
  17476. reset_end_marker();
  17477. OTL_TRACE_READ(f, "operator <<", "float");
  17478. switch (shell->stream_type) {
  17479. case otl_odbc_no_stream:
  17480. break;
  17481. case otl_odbc_io_stream:
  17482. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17483. (*io)->operator<<(f);
  17484. #else
  17485. (*io)->operator<<<float, otl_var_float>(f);
  17486. #endif
  17487. break;
  17488. case otl_odbc_select_stream:
  17489. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17490. (*ss)->operator<<(f);
  17491. #else
  17492. (*ss)->operator<<<float, otl_var_float>(f);
  17493. #endif
  17494. if (!(*ov) && (*ss)->get_sl())
  17495. create_var_desc();
  17496. break;
  17497. }
  17498. inc_next_iov();
  17499. return *this;
  17500. }
  17501. otl_stream &operator<<(const double d) OTL_THROWS_OTL_EXCEPTION {
  17502. last_oper_was_read_op = false;
  17503. reset_end_marker();
  17504. OTL_TRACE_READ(d, "operator <<", "double");
  17505. switch (shell->stream_type) {
  17506. case otl_odbc_no_stream:
  17507. break;
  17508. case otl_odbc_io_stream:
  17509. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17510. (*io)->operator<<(d);
  17511. #else
  17512. (*io)->operator<<<double, otl_var_double>(d);
  17513. #endif
  17514. break;
  17515. case otl_odbc_select_stream:
  17516. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  17517. (*ss)->operator<<(d);
  17518. #else
  17519. (*ss)->operator<<<double, otl_var_double>(d);
  17520. #endif
  17521. if (!(*ov) && (*ss)->get_sl())
  17522. create_var_desc();
  17523. break;
  17524. }
  17525. inc_next_iov();
  17526. return *this;
  17527. }
  17528. otl_stream &operator<<(const otl_null &n) OTL_THROWS_OTL_EXCEPTION {
  17529. last_oper_was_read_op = false;
  17530. reset_end_marker();
  17531. OTL_TRACE_READ("NULL", "operator <<", "otl_null&");
  17532. switch (shell->stream_type) {
  17533. case otl_odbc_no_stream:
  17534. break;
  17535. case otl_odbc_io_stream:
  17536. (*io)->operator<<(n);
  17537. break;
  17538. case otl_odbc_select_stream:
  17539. (*ss)->operator<<(n);
  17540. if (!(*ov) && (*ss)->get_sl())
  17541. create_var_desc();
  17542. break;
  17543. }
  17544. inc_next_iov();
  17545. return *this;
  17546. }
  17547. otl_stream &operator<<(const otl_long_string &d) OTL_THROWS_OTL_EXCEPTION {
  17548. last_oper_was_read_op = false;
  17549. reset_end_marker();
  17550. OTL_TRACE_READ(" len= " << d.len(), "operator <<", "otl_long_string&");
  17551. switch (shell->stream_type) {
  17552. case otl_odbc_no_stream:
  17553. break;
  17554. case otl_odbc_io_stream:
  17555. (*io)->operator<<(d);
  17556. break;
  17557. case otl_odbc_select_stream:
  17558. (*ss)->operator<<(d);
  17559. if (!(*ov) && (*ss)->get_sl())
  17560. create_var_desc();
  17561. break;
  17562. }
  17563. inc_next_iov();
  17564. return *this;
  17565. }
  17566. private:
  17567. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  17568. public:
  17569. otl_stream &operator=(const otl_stream &) = delete;
  17570. otl_stream(const otl_stream &) = delete;
  17571. #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS)
  17572. otl_stream &operator>>(bool &) = delete;
  17573. otl_stream &operator<<(const bool) = delete;
  17574. #endif
  17575. #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS)
  17576. otl_stream &operator>>(unsigned long int &) = delete;
  17577. otl_stream &operator<<(const unsigned long int) = delete;
  17578. #endif
  17579. private:
  17580. #else
  17581. otl_stream &operator=(const otl_stream &) { return *this; }
  17582. otl_stream(const otl_stream &)
  17583. : shell(nullptr), shell_pt(), connected(0), ss(nullptr), io(nullptr),
  17584. adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr),
  17585. next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr),
  17586. next_ov_ndx(nullptr), override_(nullptr), end_marker(0),
  17587. oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false),
  17588. buf_size_(0) {}
  17589. #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS)
  17590. otl_stream &operator>>(bool &) OTL_NO_THROW { return *this; }
  17591. otl_stream &operator<<(const bool) OTL_NO_THROW { return *this; }
  17592. #endif
  17593. #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS)
  17594. otl_stream &operator>>(unsigned long int &) OTL_NO_THROW { return *this; }
  17595. otl_stream &operator<<(const unsigned long int) OTL_NO_THROW { return *this; }
  17596. #endif
  17597. #endif
  17598. };
  17599. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  17600. inline bool operator!=(const otl_for_range_loop_odbc_stream_adapter& a1,
  17601. const otl_for_range_loop_odbc_stream_adapter& /*a2*/){
  17602. return !a1.str_->eof();
  17603. }
  17604. #endif
  17605. inline otl_connect &operator>>(otl_connect &connect, otl_stream &s) {
  17606. const char *cmd = connect.getCmd();
  17607. const char *invalid_cmd = "*** INVALID COMMAND ***";
  17608. if (!cmd)
  17609. cmd = invalid_cmd;
  17610. s.open(s.getBufSize(), cmd, connect);
  17611. return connect;
  17612. }
  17613. #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \
  17614. defined(OTL_VALUE_TEMPLATE)
  17615. template <OTL_TYPE_NAME TData>
  17616. inline otl_stream &operator<<(otl_stream &s,
  17617. const otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  17618. if (var.is_null())
  17619. s << otl_null();
  17620. else
  17621. s << var.v;
  17622. return s;
  17623. }
  17624. template <OTL_TYPE_NAME TData, const TData null_value>
  17625. inline otl_stream &operator<<
  17626. (otl_stream &s,
  17627. const otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
  17628. if (var.is_null())
  17629. s << otl_null();
  17630. else
  17631. s << var.v;
  17632. return s;
  17633. }
  17634. template <OTL_TYPE_NAME TData>
  17635. inline otl_stream &operator>>(otl_stream &s,
  17636. otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  17637. s>>var.v;
  17638. if(s.is_null())
  17639. var.set_null(true);
  17640. else
  17641. var.set_null(false);
  17642. return s;
  17643. }
  17644. template <OTL_TYPE_NAME TData, const TData null_value>
  17645. inline otl_stream &operator>>
  17646. (otl_stream &s,
  17647. otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
  17648. s>>var.v;
  17649. if(s.is_null())
  17650. var.set_null(true);
  17651. else
  17652. var.set_null(false);
  17653. return s;
  17654. }
  17655. #endif
  17656. class otl_nocommit_stream : public otl_stream {
  17657. public:
  17658. otl_nocommit_stream() OTL_NO_THROW : otl_stream() { set_commit(0); }
  17659. otl_nocommit_stream(const otl_stream_buffer_size_type arr_size,
  17660. const char *sqlstm, otl_connect &db,
  17661. const int implicit_select = otl_explicit_select)
  17662. OTL_THROWS_OTL_EXCEPTION:
  17663. otl_stream(arr_size, sqlstm, db, implicit_select) { set_commit(0); }
  17664. void open(otl_stream_buffer_size_type arr_size, const char *sqlstm,
  17665. otl_connect &db, const int implicit_select =
  17666. otl_explicit_select) OTL_THROWS_OTL_EXCEPTION {
  17667. otl_stream::open(arr_size, sqlstm, db, implicit_select);
  17668. set_commit(0);
  17669. }
  17670. };
  17671. inline otl_stream &endr(otl_stream &s) {
  17672. s.check_end_of_row();
  17673. return s;
  17674. }
  17675. OTL_ODBC_NAMESPACE_END
  17676. #endif
  17677. // ==================== OTL-Adapter for Oracle 8 =====================
  17678. #if defined(OTL_ORA8)
  17679. #if defined(__STDC__)
  17680. #define OTL_STDC_DEFINED
  17681. #else
  17682. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
  17683. #pragma clang diagnostic push
  17684. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  17685. #endif
  17686. #define __STDC__ 1 // making OCI function prototypes show up in oci.h
  17687. #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
  17688. #pragma clang diagnostic pop
  17689. #endif
  17690. #endif
  17691. #if defined(OTL_ORA_TEXT_ON)
  17692. #define text OTL_ORA_TEXT
  17693. #endif
  17694. #include <oci.h>
  17695. #if !defined(OTL_ORA_DOES_NOT_UNDEF_MIN_MAX)
  17696. #if defined(min)
  17697. #undef min
  17698. #endif
  17699. #if defined(max)
  17700. #undef max
  17701. #endif
  17702. #endif
  17703. #define OTL_UTF8_BYTES_PER_CHAR (4)
  17704. #if defined(OTL_ORA8_PROC)
  17705. extern "C" {
  17706. #include <sql2oci.h>
  17707. }
  17708. #endif
  17709. OTL_ORA8_NAMESPACE_BEGIN
  17710. const int inVarChar2 = 1;
  17711. const int inNumber = 2;
  17712. const int inLong = 8;
  17713. const int inRowId = 104;
  17714. const int inDate = 12;
  17715. const int inRaw = 23;
  17716. const int inLongRaw = 24;
  17717. const int inChar = 96;
  17718. #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)
  17719. const int inBFloat = SQLT_IBFLOAT;
  17720. const int inBDouble = SQLT_IBDOUBLE;
  17721. #endif
  17722. const int inMslabel = 105;
  17723. const int inUserDefinedType = 108;
  17724. const int inRef = 111;
  17725. const int inCLOB = 112;
  17726. const int inBLOB = 113;
  17727. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  17728. const int inTimestamp = SQLT_TIMESTAMP;
  17729. const int inTimestamp_TZ = SQLT_TIMESTAMP_TZ;
  17730. const int inTimestamp_LTZ = SQLT_TIMESTAMP_LTZ;
  17731. const int inIntervalYM = SQLT_INTERVAL_YM;
  17732. const int inIntervalDS = SQLT_INTERVAL_DS;
  17733. #endif
  17734. const int extVarChar2 = 1;
  17735. const int extNumber = 2;
  17736. const int extInt = 3;
  17737. const int extFloat = 4;
  17738. #if defined(OTL_ORA_MAP_STRINGS_TO_CHARZ)
  17739. const int extCChar = 97;
  17740. #else
  17741. const int extCChar = 5;
  17742. #endif
  17743. const int extVarNum = 6;
  17744. const int extLong = 8;
  17745. const int extVarChar = 9;
  17746. const int extRowId = 11;
  17747. const int extDate = 12;
  17748. const int extVarRaw = 15;
  17749. const int extRaw = extVarRaw;
  17750. const int extLongRaw = 24;
  17751. const int extUInt = 68;
  17752. const int extLongVarChar = 94;
  17753. const int extLongVarRaw = 95;
  17754. const int extChar = 96;
  17755. const int extCharZ = 97;
  17756. const int extMslabel = 105;
  17757. const int extCLOB = inCLOB;
  17758. const int extBLOB = inBLOB;
  17759. #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \
  17760. !defined(OTL_ORA_LEGACY_NUMERIC_TYPES)
  17761. const int extBFloat = SQLT_BFLOAT;
  17762. const int extBDouble = SQLT_BDOUBLE;
  17763. #endif
  17764. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  17765. const int extTimestamp = SQLT_TIMESTAMP;
  17766. const int extTimestamp_TZ = SQLT_TIMESTAMP_TZ;
  17767. const int extTimestamp_LTZ = SQLT_TIMESTAMP_LTZ;
  17768. #endif
  17769. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  17770. typedef otl_datetime otl_time0;
  17771. #else
  17772. typedef otl_oracle_date otl_time0;
  17773. #endif
  17774. class otl_exc {
  17775. public:
  17776. unsigned char msg[1000];
  17777. int code;
  17778. char sqlstate[32];
  17779. #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET)
  17780. int error_offset;
  17781. #endif
  17782. #if defined(OTL_EXTENDED_EXCEPTION)
  17783. char **msg_arr;
  17784. char **sqlstate_arr;
  17785. int *code_arr;
  17786. int arr_len;
  17787. #endif
  17788. enum {
  17789. disabled = 0,
  17790. enabled = 1
  17791. };
  17792. otl_exc()
  17793. : msg(), code(0), sqlstate()
  17794. #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET)
  17795. ,
  17796. error_offset(-1)
  17797. #endif
  17798. #if defined(OTL_EXTENDED_EXCEPTION)
  17799. ,
  17800. msg_arr(nullptr), sqlstate_arr(nullptr), code_arr(nullptr), arr_len(0)
  17801. #endif
  17802. {
  17803. sqlstate[0] = 0;
  17804. msg[0] = 0;
  17805. }
  17806. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) && \
  17807. !defined(OTL_EXTENDED_EXCEPTION)
  17808. otl_exc(const otl_exc &) = default;
  17809. #endif
  17810. virtual ~otl_exc() {}
  17811. void init(const char *amsg, const int acode) {
  17812. OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg), amsg);
  17813. code = acode;
  17814. #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET)
  17815. error_offset = -1;
  17816. #endif
  17817. #if defined(OTL_EXTENDED_EXCEPTION)
  17818. msg_arr = nullptr;
  17819. sqlstate_arr = nullptr;
  17820. code_arr = nullptr;
  17821. arr_len = 0;
  17822. #endif
  17823. }
  17824. };
  17825. class otl_cur;
  17826. class otl_var;
  17827. class otl_conn {
  17828. private:
  17829. friend class otl_cur;
  17830. friend class otl_var;
  17831. OCIEnv *envhp; // OCI environment handle
  17832. OCIServer *srvhp; // OCI Server handle
  17833. OCIError *errhp; // OCI Error handle
  17834. OCISvcCtx *svchp; // OCI Service context handle
  17835. OCISession *authp; // OCI Session handle
  17836. int auto_commit;
  17837. int extern_lda;
  17838. int attached;
  17839. int in_session;
  17840. int char_set_;
  17841. int session_begin_count;
  17842. int session_mode_;
  17843. int ext_cred;
  17844. int last_status;
  17845. char *xa_server_external_name;
  17846. char *xa_server_internal_name;
  17847. #if defined(OTL_ORA_OCI_ENV_CREATE)
  17848. bool threaded_mode;
  17849. #endif
  17850. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  17851. int lob_prefetch_size;
  17852. #endif
  17853. #if defined(OTL_ORA_SDO_GEOMETRY)
  17854. OCIType *geometryTDO;
  17855. #endif
  17856. public:
  17857. enum bigint_type {
  17858. #if defined(OTL_BIGINT) && \
  17859. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  17860. !defined(OTL_BIGINT_TO_STR))
  17861. var_bigint = otl_var_bigint,
  17862. bigint_size = sizeof(OTL_BIGINT)
  17863. #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG)
  17864. var_bigint = otl_var_long_int,
  17865. bigint_size = sizeof(long)
  17866. #else
  17867. var_bigint = otl_var_char,
  17868. bigint_size = otl_bigint_str_size
  17869. #endif
  17870. };
  17871. enum ubigint_type {
  17872. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  17873. var_ubigint = otl_var_ubigint,
  17874. ubigint_size = sizeof(OTL_UBIGINT)
  17875. #else
  17876. var_ubigint = otl_var_char,
  17877. ubigint_size = otl_ubigint_str_size
  17878. #endif
  17879. };
  17880. #if defined(OTL_ORA_OCI_ENV_CREATE)
  17881. void set_threaded_mode(const bool athreaded_mode) {
  17882. threaded_mode = athreaded_mode;
  17883. }
  17884. #endif
  17885. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  17886. OTL_NODISCARD int set_lob_prefetch_size(const int prefetch_size = 0) {
  17887. lob_prefetch_size = prefetch_size;
  17888. ub4 temp_size = OTL_SCAST(ub4, prefetch_size);
  17889. int status = 0;
  17890. status =
  17891. OCIAttrSet(OTL_RCAST(dvoid *, authp), OTL_SCAST(ub4, OCI_HTYPE_SESSION),
  17892. OTL_RCAST(dvoid *, &temp_size), 0,
  17893. OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, errhp);
  17894. if (status != OCI_SUCCESS)
  17895. return 0;
  17896. else
  17897. return 1;
  17898. }
  17899. OTL_NODISCARD int get_lob_prefetch_size() const { return lob_prefetch_size; }
  17900. #endif
  17901. void cleanup(void) {
  17902. (void)session_end();
  17903. (void)server_detach();
  17904. }
  17905. OTL_NODISCARD int get_session_begin_count() const { return session_begin_count; }
  17906. OTL_NODISCARD int get_extern_lda() const { return extern_lda; }
  17907. OTL_NODISCARD int get_last_status() const { return last_status; }
  17908. OTL_NODISCARD int get_auto_commit() const { return auto_commit; }
  17909. OTL_NODISCARD OCIEnv *get_envhp() { return envhp; }
  17910. OTL_NODISCARD OCIError *get_errhp() { return errhp; }
  17911. OTL_NODISCARD OCISvcCtx *get_svchp() { return svchp; }
  17912. OTL_NODISCARD OCIServer *get_srvhp() { return srvhp; }
  17913. OTL_NODISCARD OCISession *get_authp() { return authp; }
  17914. OTL_NODISCARD int get_char_set() const { return char_set_; }
  17915. OTL_NODISCARD int get_connection_type(void) { return 0; }
  17916. #if !defined(OTL_ORA_OCI_ENV_CREATE)
  17917. OTL_NODISCARD static int initialize(const int threaded_mode = 0) {
  17918. int status;
  17919. int mode;
  17920. if (threaded_mode)
  17921. mode = OCI_THREADED;
  17922. else
  17923. mode = OCI_DEFAULT;
  17924. status = OCIInitialize(OTL_SCAST(ub4, mode),
  17925. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  17926. nullptr,
  17927. #else
  17928. OTL_RCAST(dvoid *, 0),
  17929. #endif
  17930. nullptr, nullptr, nullptr);
  17931. if (status != OCI_SUCCESS)
  17932. return 0;
  17933. else
  17934. return 1;
  17935. #else
  17936. OTL_NODISCARD static int initialize(const int /*threaded_mode*/) {
  17937. return 1;
  17938. #endif
  17939. }
  17940. #if defined(OTL_ORA_SDO_GEOMETRY)
  17941. OTL_NODISCARD OCIType* getGeometryTDO(){
  17942. return geometryTDO;
  17943. }
  17944. #endif
  17945. otl_conn()
  17946. : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr),
  17947. authp(nullptr), auto_commit(0), extern_lda(0), attached(0),
  17948. in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0),
  17949. session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS),
  17950. xa_server_external_name(nullptr), xa_server_internal_name(nullptr)
  17951. #if defined(OTL_ORA_OCI_ENV_CREATE)
  17952. ,
  17953. threaded_mode(false)
  17954. #endif
  17955. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  17956. ,
  17957. lob_prefetch_size(0)
  17958. #endif
  17959. #if defined(OTL_ORA_SDO_GEOMETRY)
  17960. , geometryTDO(nullptr)
  17961. #endif
  17962. {
  17963. }
  17964. #if defined(OTL_ORA_OCI_ENV_CREATE)
  17965. void set_connect_mode(bool mode) { threaded_mode = mode; }
  17966. #endif
  17967. void set_char_set(const int char_set) { char_set_ = char_set; }
  17968. void set_xa_server_external_name(const char *name) {
  17969. if (xa_server_external_name) {
  17970. delete[] xa_server_external_name;
  17971. xa_server_external_name = nullptr;
  17972. }
  17973. size_t len = strlen(name) + 1;
  17974. xa_server_external_name = new char[len];
  17975. OTL_STRCPY_S(xa_server_external_name, len, name);
  17976. }
  17977. void set_xa_server_internal_name(const char *name) {
  17978. if (xa_server_internal_name) {
  17979. delete[] xa_server_internal_name;
  17980. xa_server_internal_name = nullptr;
  17981. }
  17982. size_t len = strlen(name) + 1;
  17983. xa_server_internal_name = new char[len];
  17984. OTL_STRCPY_S(xa_server_internal_name, len, name);
  17985. }
  17986. void delete_xa_strings(void) {
  17987. if (xa_server_external_name) {
  17988. delete[] xa_server_external_name;
  17989. xa_server_external_name = nullptr;
  17990. }
  17991. if (xa_server_internal_name) {
  17992. delete[] xa_server_internal_name;
  17993. xa_server_internal_name = nullptr;
  17994. }
  17995. }
  17996. virtual ~otl_conn() { delete_xa_strings(); }
  17997. void set_timeout(const int /*atimeout*/ = 0) {}
  17998. void set_cursor_type(const int /*acursor_type*/ = 0) {}
  17999. OTL_NODISCARD int cancel(void) {
  18000. int status;
  18001. status = OCIBreak(srvhp, errhp);
  18002. if (status)
  18003. return 0;
  18004. else
  18005. return 1;
  18006. }
  18007. OTL_NODISCARD int server_attach(const char *tnsname) {
  18008. int &status = last_status;
  18009. envhp = nullptr;
  18010. srvhp = nullptr;
  18011. errhp = nullptr;
  18012. svchp = nullptr;
  18013. authp = nullptr;
  18014. extern_lda = 0;
  18015. attached = 0;
  18016. in_session = 0;
  18017. session_begin_count = 0;
  18018. #if !defined(OTL_ORA_OCI_ENV_CREATE)
  18019. status = OCIEnvInit(OTL_RCAST(OCIEnv **, &envhp), OCI_DEFAULT, 0, nullptr);
  18020. #else
  18021. status = OCIEnvCreate(OTL_RCAST(OCIEnv **, &envhp),
  18022. #if defined(OTL_ORA_OCI_ENV_CREATE_MODE)
  18023. OTL_ORA_OCI_ENV_CREATE_MODE,
  18024. #else
  18025. threaded_mode ? OCI_THREADED : OCI_DEFAULT,
  18026. #endif
  18027. nullptr, nullptr, nullptr, nullptr, 0, nullptr);
  18028. #endif
  18029. if (status)
  18030. return 0;
  18031. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18032. void *temp_errhp = &errhp;
  18033. #endif
  18034. status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp),
  18035. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18036. OTL_RCAST(dvoid **, temp_errhp),
  18037. #else
  18038. OTL_RCAST(dvoid **, &errhp),
  18039. #endif
  18040. OCI_HTYPE_ERROR, 0, nullptr);
  18041. if (status)
  18042. return 0;
  18043. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18044. void *temp_srvhp = &srvhp;
  18045. #endif
  18046. status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp),
  18047. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18048. OTL_RCAST(dvoid **, temp_srvhp),
  18049. #else
  18050. OTL_RCAST(dvoid **, &srvhp),
  18051. #endif
  18052. OCI_HTYPE_SERVER, 0, nullptr);
  18053. if (status)
  18054. return 0;
  18055. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18056. void *temp_svchp = &svchp;
  18057. #endif
  18058. status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp),
  18059. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18060. OTL_RCAST(dvoid **, temp_svchp),
  18061. #else
  18062. OTL_RCAST(dvoid **, &svchp),
  18063. #endif
  18064. OCI_HTYPE_SVCCTX, 0, nullptr);
  18065. if (status)
  18066. return 0;
  18067. status = OCIServerAttach(
  18068. srvhp, errhp,
  18069. tnsname == nullptr ? OTL_RCAST(text *, OTL_CCAST(char *, ""))
  18070. : OTL_RCAST(text *, OTL_CCAST(char *, tnsname)),
  18071. tnsname == nullptr ? 0
  18072. : OTL_SCAST(sb4, strlen(OTL_CCAST(char *, tnsname))),
  18073. 0);
  18074. if (status)
  18075. return 0;
  18076. status = OCIAttrSet(OTL_RCAST(dvoid *, svchp), OCI_HTYPE_SVCCTX,
  18077. OTL_RCAST(dvoid *, srvhp), 0, OCI_ATTR_SERVER,
  18078. OTL_RCAST(OCIError *, errhp));
  18079. if (status)
  18080. return 0;
  18081. if (xa_server_external_name != nullptr &&
  18082. xa_server_internal_name != nullptr) {
  18083. status = OCIAttrSet(OTL_RCAST(dvoid *, srvhp), OCI_HTYPE_SERVER,
  18084. OTL_RCAST(dvoid *, xa_server_external_name), 0,
  18085. OCI_ATTR_EXTERNAL_NAME, errhp);
  18086. if (status)
  18087. return 0;
  18088. status = OCIAttrSet(OTL_RCAST(dvoid *, srvhp), OCI_HTYPE_SERVER,
  18089. OTL_RCAST(dvoid *, xa_server_internal_name), 0,
  18090. OCI_ATTR_INTERNAL_NAME, errhp);
  18091. if (status)
  18092. return 0;
  18093. }
  18094. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18095. void *temp_authp = &authp;
  18096. #endif
  18097. status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp),
  18098. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18099. OTL_RCAST(dvoid **, temp_authp),
  18100. #else
  18101. OTL_RCAST(dvoid **, &authp),
  18102. #endif
  18103. OTL_SCAST(ub4, OCI_HTYPE_SESSION), 0, nullptr);
  18104. if (status)
  18105. return 0;
  18106. attached = 1;
  18107. return 1;
  18108. }
  18109. OTL_NODISCARD int session_begin(const int aauto_commit) {
  18110. int &status = last_status;
  18111. int cred_type;
  18112. if (!attached)
  18113. return 0;
  18114. if (session_begin_count == 0)
  18115. return 0;
  18116. if (ext_cred)
  18117. cred_type = OCI_CRED_EXT;
  18118. else
  18119. cred_type = OCI_CRED_RDBMS;
  18120. status =
  18121. OCISessionBegin(svchp, errhp, authp, OTL_SCAST(unsigned, cred_type),
  18122. OTL_SCAST(ub4, session_mode_));
  18123. if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
  18124. return 0;
  18125. in_session = 1;
  18126. auto_commit = aauto_commit;
  18127. ++session_begin_count;
  18128. return 1;
  18129. }
  18130. OTL_NODISCARD int session_begin(const char *userid, const char *password,
  18131. const int aauto_commit,
  18132. const int session_mode = OCI_DEFAULT) {
  18133. int &status = last_status;
  18134. int cred_type;
  18135. if (!attached)
  18136. return 0;
  18137. if (userid[0] == 0 && password[0] == 0) {
  18138. ext_cred = 1;
  18139. cred_type = OCI_CRED_EXT;
  18140. } else {
  18141. ext_cred = 0;
  18142. cred_type = OCI_CRED_RDBMS;
  18143. status = OCIAttrSet(OTL_RCAST(dvoid *, authp),
  18144. OTL_SCAST(ub4, OCI_HTYPE_SESSION),
  18145. OTL_RCAST(dvoid *, OTL_CCAST(char *, userid)),
  18146. OTL_SCAST(ub4, strlen(OTL_CCAST(char *, userid))),
  18147. OTL_SCAST(ub4, OCI_ATTR_USERNAME), errhp);
  18148. if (status)
  18149. return 0;
  18150. status = OCIAttrSet(OTL_RCAST(dvoid *, authp),
  18151. OTL_SCAST(ub4, OCI_HTYPE_SESSION),
  18152. OTL_RCAST(dvoid *, OTL_CCAST(char *, password)),
  18153. OTL_SCAST(ub4, strlen(OTL_CCAST(char *, password))),
  18154. OTL_SCAST(ub4, OCI_ATTR_PASSWORD), errhp);
  18155. if (status)
  18156. return 0;
  18157. }
  18158. session_mode_ = session_mode;
  18159. status =
  18160. OCISessionBegin(svchp, errhp, authp, OTL_SCAST(unsigned, cred_type),
  18161. OTL_SCAST(ub4, session_mode_));
  18162. if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
  18163. return 0;
  18164. status = OCIAttrSet(
  18165. OTL_RCAST(dvoid *, svchp), OTL_SCAST(ub4, OCI_HTYPE_SVCCTX),
  18166. OTL_RCAST(dvoid *, authp), 0, OTL_SCAST(ub4, OCI_ATTR_SESSION), errhp);
  18167. if (status)return 0;
  18168. #if defined(OTL_ORA_SDO_GEOMETRY)
  18169. OCIParam *paramp = nullptr;
  18170. OCIRef *type_ref = nullptr;
  18171. OCIDescribe *dschp = nullptr;
  18172. void* temp_ptr2=OTL_RCAST(void*, &dschp);
  18173. status = OCIHandleAlloc(
  18174. OTL_RCAST(dvoid *, envhp), OTL_RCAST(dvoid**,temp_ptr2),
  18175. OTL_SCAST(ub4, OCI_HTYPE_DESCRIBE), 0, nullptr);
  18176. if(status)return 0;
  18177. text objptr[] = "MDSYS.SDO_GEOMETRY";
  18178. size_t objp_len = strlen(OTL_RCAST(char*,objptr));
  18179. status = OCIDescribeAny(
  18180. svchp, errhp,
  18181. OTL_RCAST(dvoid *, objptr),
  18182. OTL_SCAST(ub4, objp_len),
  18183. OTL_SCAST(ub1, OCI_OTYPE_NAME),
  18184. OTL_SCAST(ub1, OCI_DEFAULT),
  18185. OTL_SCAST(ub1, OCI_PTYPE_TYPE), dschp);
  18186. if(status)return 0;
  18187. status = OCIAttrGet(
  18188. OTL_RCAST(dvoid *, dschp),
  18189. OTL_SCAST(ub4, OCI_HTYPE_DESCRIBE),
  18190. OTL_RCAST(dvoid *, &paramp),
  18191. nullptr,
  18192. OTL_SCAST(ub4, OCI_ATTR_PARAM), errhp);
  18193. if(status)return 0;
  18194. status = OCIAttrGet(
  18195. OTL_RCAST(dvoid *, paramp),
  18196. OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  18197. OTL_RCAST(dvoid *, &type_ref),
  18198. nullptr,
  18199. OTL_SCAST(ub4, OCI_ATTR_REF_TDO), errhp);
  18200. if(status)return 0;
  18201. #if defined(__clang__)
  18202. #pragma clang diagnostic push
  18203. #pragma clang diagnostic ignored "-Wold-style-cast"
  18204. #endif
  18205. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  18206. #pragma GCC diagnostic push
  18207. #pragma GCC diagnostic ignored "-Wold-style-cast"
  18208. #endif
  18209. void* temp_ptr=OTL_RCAST(void*,&geometryTDO);
  18210. status = OCIObjectPin(
  18211. envhp,
  18212. errhp,
  18213. type_ref,
  18214. nullptr,
  18215. /*OCIPinOpt::*/OCI_PIN_ANY,
  18216. OTL_SCAST(ub2, OCI_DURATION_SESSION),
  18217. /*OCILockOpt::*/OCI_LOCK_NONE,
  18218. OTL_RCAST(dvoid**,temp_ptr));
  18219. if(status)return 0;
  18220. #if defined(__clang__)
  18221. #pragma clang diagnostic pop
  18222. #endif
  18223. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  18224. #pragma GCC diagnostic pop
  18225. #endif
  18226. #endif
  18227. in_session = 1;
  18228. auto_commit = aauto_commit;
  18229. ++session_begin_count;
  18230. return 1;
  18231. }
  18232. #if defined(OTL_ORA8I) || defined(OTL_ORA9I)
  18233. OTL_NODISCARD int change_password(const char *user_name, const char *password,
  18234. const char *new_password) {
  18235. int &status = last_status;
  18236. OCIAttrSet(OTL_RCAST(dvoid *, svchp), OTL_SCAST(ub4, OCI_HTYPE_SVCCTX),
  18237. OTL_RCAST(dvoid *, authp), 0, OTL_SCAST(ub4, OCI_ATTR_SESSION),
  18238. errhp);
  18239. status = OCIPasswordChange(
  18240. svchp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, user_name)),
  18241. OTL_SCAST(ub4, strlen(user_name)),
  18242. OTL_RCAST(text *, OTL_CCAST(char *, password)),
  18243. OTL_SCAST(ub4, strlen(password)),
  18244. OTL_RCAST(text *, OTL_CCAST(char *, new_password)),
  18245. OTL_SCAST(ub4, strlen(new_password)), OCI_AUTH);
  18246. if (status)
  18247. return 0;
  18248. else
  18249. return 1;
  18250. }
  18251. #endif
  18252. OTL_NODISCARD int server_detach(void) {
  18253. int rc = 0;
  18254. if (attached) {
  18255. OCIServerDetach(srvhp, errhp, OTL_SCAST(ub4, OCI_DEFAULT));
  18256. rc = 1;
  18257. }
  18258. if (authp != nullptr)
  18259. OCIHandleFree(OTL_RCAST(dvoid *, authp),
  18260. OTL_SCAST(ub4, OCI_HTYPE_SESSION));
  18261. if (errhp != nullptr)
  18262. OCIHandleFree(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, OCI_HTYPE_ERROR));
  18263. if (svchp != nullptr)
  18264. OCIHandleFree(OTL_RCAST(dvoid *, svchp),
  18265. OTL_SCAST(ub4, OCI_HTYPE_SVCCTX));
  18266. if (srvhp != nullptr)
  18267. OCIHandleFree(OTL_RCAST(dvoid *, srvhp),
  18268. OTL_SCAST(ub4, OCI_HTYPE_SERVER));
  18269. if (envhp != nullptr)
  18270. OCIHandleFree(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV));
  18271. auto_commit = 0;
  18272. attached = 0;
  18273. in_session = 0;
  18274. envhp = nullptr;
  18275. srvhp = nullptr;
  18276. errhp = nullptr;
  18277. svchp = nullptr;
  18278. authp = nullptr;
  18279. delete_xa_strings();
  18280. return rc;
  18281. }
  18282. OTL_NODISCARD int session_end(void) {
  18283. int &status = last_status;
  18284. if (!in_session)
  18285. return 0;
  18286. status = OCISessionEnd(svchp, errhp, authp, 0);
  18287. if (status)
  18288. return 0;
  18289. in_session = 0;
  18290. auto_commit = 0;
  18291. return 1;
  18292. }
  18293. OTL_NODISCARD int auto_commit_on(void) {
  18294. auto_commit = 1;
  18295. return 1;
  18296. }
  18297. OTL_NODISCARD int auto_commit_off(void) {
  18298. auto_commit = 0;
  18299. return 1;
  18300. }
  18301. OTL_NODISCARD int rlogon(const char *connect_str, const int aauto_commit) {
  18302. int status;
  18303. char username[256];
  18304. char passwd[256];
  18305. char tnsname[1024];
  18306. char *tnsname_ptr = nullptr;
  18307. char *username_ptr = username;
  18308. char *c = OTL_CCAST(char *, connect_str);
  18309. char *passwd_ptr = passwd;
  18310. char prev_c = ' ';
  18311. auto_commit = aauto_commit;
  18312. username[0] = 0;
  18313. passwd[0] = 0;
  18314. tnsname[0] = 0;
  18315. while (*c && *c != '/' && (OTL_SCAST(unsigned, username_ptr - username) <
  18316. sizeof(username) - 1)) {
  18317. *username_ptr = *c;
  18318. ++c;
  18319. ++username_ptr;
  18320. }
  18321. *username_ptr = 0;
  18322. if (*c == '/')
  18323. ++c;
  18324. prev_c = ' ';
  18325. while (*c && !(*c == '@' && prev_c != '\\') &&
  18326. (OTL_SCAST(unsigned, passwd_ptr - passwd) < sizeof(passwd) - 1)) {
  18327. if (prev_c == '\\')
  18328. --passwd_ptr;
  18329. *passwd_ptr = *c;
  18330. prev_c = *c;
  18331. ++c;
  18332. ++passwd_ptr;
  18333. }
  18334. *passwd_ptr = 0;
  18335. if (*c == '@') {
  18336. ++c;
  18337. tnsname_ptr = tnsname;
  18338. while (*c && (OTL_SCAST(unsigned, tnsname_ptr - tnsname) <
  18339. sizeof(tnsname) - 1)) {
  18340. *tnsname_ptr = *c;
  18341. ++c;
  18342. ++tnsname_ptr;
  18343. }
  18344. *tnsname_ptr = 0;
  18345. }
  18346. envhp = nullptr;
  18347. srvhp = nullptr;
  18348. errhp = nullptr;
  18349. svchp = nullptr;
  18350. authp = nullptr;
  18351. extern_lda = 0;
  18352. attached = 0;
  18353. in_session = 0;
  18354. OTL_TRACE_RLOGON_ORA8(0x1, "otl_connect", "rlogon", tnsname, username,
  18355. passwd, auto_commit)
  18356. status = server_attach(tnsname);
  18357. if (!status)
  18358. return 0;
  18359. status = session_begin(username, passwd, aauto_commit);
  18360. if (!status)
  18361. return 0;
  18362. return 1;
  18363. }
  18364. OTL_NODISCARD int ext_logon(OCIEnv *a_envhp, OCISvcCtx *a_svchp,
  18365. const int aauto_commit = 0) {
  18366. int &status = last_status;
  18367. envhp = a_envhp;
  18368. svchp = a_svchp;
  18369. errhp = nullptr;
  18370. srvhp = nullptr;
  18371. authp = nullptr;
  18372. extern_lda = 1;
  18373. auto_commit = aauto_commit;
  18374. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18375. void *temp_errhp = &errhp;
  18376. #endif
  18377. status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp),
  18378. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18379. OTL_RCAST(dvoid **, temp_errhp),
  18380. #else
  18381. OTL_RCAST(dvoid **, &errhp),
  18382. #endif
  18383. OCI_HTYPE_ERROR, 0, nullptr);
  18384. if (status)
  18385. return 0;
  18386. return 1;
  18387. }
  18388. OTL_NODISCARD int logoff(void) {
  18389. int rc;
  18390. if (extern_lda) {
  18391. OCIHandleFree(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, OCI_HTYPE_ERROR));
  18392. envhp = nullptr;
  18393. svchp = nullptr;
  18394. errhp = nullptr;
  18395. extern_lda = 0;
  18396. } else {
  18397. rc = session_end();
  18398. if (!rc)
  18399. return 0;
  18400. rc = server_detach();
  18401. if (!rc)
  18402. return 0;
  18403. }
  18404. auto_commit = 0;
  18405. return 1;
  18406. }
  18407. void error(otl_exc &exception_struct) {
  18408. sb4 errcode;
  18409. size_t len;
  18410. OCIErrorGet(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, 1), nullptr, &errcode,
  18411. OTL_RCAST(text *, exception_struct.msg),
  18412. OTL_SCAST(ub4, sizeof(exception_struct.msg)), OCI_HTYPE_ERROR);
  18413. exception_struct.code = errcode;
  18414. len = strlen(OTL_RCAST(char *, exception_struct.msg));
  18415. exception_struct.msg[len] = 0;
  18416. }
  18417. OTL_NODISCARD int commit(void) {
  18418. last_status = OCITransCommit(svchp, errhp, OTL_SCAST(ub4, OCI_DEFAULT));
  18419. return !last_status;
  18420. }
  18421. #if defined(OTL_ORA10G_R2)
  18422. OTL_NODISCARD int commit_nowait(void) {
  18423. #if defined(OCI_TRANS_WRITENOWAIT)
  18424. last_status =
  18425. OCITransCommit(svchp, errhp, OTL_SCAST(ub4, OCI_TRANS_WRITENOWAIT));
  18426. #else
  18427. last_status = OCITransCommit(svchp, errhp, OTL_SCAST(ub4, 0x00000008));
  18428. #endif
  18429. return !last_status;
  18430. }
  18431. #endif
  18432. OTL_NODISCARD int rollback(void) {
  18433. last_status = OCITransRollback(svchp, errhp, OTL_SCAST(ub4, OCI_DEFAULT));
  18434. return !last_status;
  18435. }
  18436. private:
  18437. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  18438. public:
  18439. otl_conn(const otl_conn &) = delete;
  18440. otl_conn &operator=(const otl_conn &) = delete;
  18441. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  18442. otl_conn(otl_conn &&) = delete;
  18443. otl_conn &operator=(otl_conn &&) = delete;
  18444. #endif
  18445. private:
  18446. #else
  18447. otl_conn(const otl_conn &)
  18448. : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr),
  18449. authp(nullptr), auto_commit(0), extern_lda(0), attached(0),
  18450. in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0),
  18451. session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS),
  18452. xa_server_external_name(nullptr), xa_server_internal_name(nullptr)
  18453. #if defined(OTL_ORA_OCI_ENV_CREATE)
  18454. ,
  18455. threaded_mode(false)
  18456. #endif
  18457. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  18458. ,
  18459. lob_prefetch_size(0)
  18460. #endif
  18461. {
  18462. }
  18463. otl_conn &operator=(const otl_conn &) { return *this; }
  18464. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  18465. otl_conn(otl_conn &&)
  18466. : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr),
  18467. authp(nullptr), auto_commit(0), extern_lda(0), attached(0),
  18468. in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0),
  18469. session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS),
  18470. xa_server_external_name(nullptr), xa_server_internal_name(nullptr)
  18471. #if defined(OTL_ORA_OCI_ENV_CREATE)
  18472. ,
  18473. threaded_mode(false)
  18474. #endif
  18475. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  18476. ,
  18477. lob_prefetch_size(0)
  18478. #endif
  18479. {
  18480. }
  18481. otl_conn &operator=(otl_conn &&) { return *this; }
  18482. #endif
  18483. #endif
  18484. };
  18485. class otl_cur0 {
  18486. public:
  18487. virtual ~otl_cur0() {}
  18488. };
  18489. class otl_cur;
  18490. class otl_inout_stream;
  18491. class otl_refcur_stream;
  18492. class otl_ref_select_stream;
  18493. #if defined(OTL_ORA_SDO_GEOMETRY)
  18494. struct oci_spatial_geometry{
  18495. bool isNull;
  18496. unsigned int gtype;
  18497. int srid;
  18498. double x, y, z;
  18499. STD_NAMESPACE_PREFIX vector<int> eleminfo;
  18500. STD_NAMESPACE_PREFIX vector<double> ordinates;
  18501. };
  18502. #endif
  18503. class otl_var {
  18504. private:
  18505. friend class otl_cur;
  18506. friend class otl_inout_stream;
  18507. friend class otl_refcur_stream;
  18508. friend class otl_ref_select_stream;
  18509. ub1 *p_v;
  18510. sb2 *p_ind;
  18511. ub2 *p_rlen;
  18512. ub2 *p_rcode;
  18513. int ftype;
  18514. int array_size;
  18515. int elem_size;
  18516. bool nls_flag;
  18517. OCILobLocator **lob;
  18518. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18519. OCIDateTime **timestamp;
  18520. #endif
  18521. OCIStmt *cda;
  18522. otl_conn *connect;
  18523. ub1 *buf;
  18524. int buf_len;
  18525. int real_buf_len;
  18526. int ext_buf_flag;
  18527. int act_elem_size;
  18528. ub4 max_tab_len;
  18529. ub4 cur_tab_len;
  18530. int pl_tab_flag;
  18531. int lob_stream_flag;
  18532. int vparam_type;
  18533. otl_adapter_enum otl_adapter;
  18534. bool lob_stream_mode;
  18535. #if defined(OTL_UNICODE)
  18536. sb4 unicode_var_len;
  18537. #endif
  18538. ub2 csid;
  18539. #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8)
  18540. ub1 csfrm;
  18541. #endif
  18542. ub4 read_blob_amt;
  18543. ub4 total_read_blob_amt;
  18544. bool charz_flag;
  18545. bool select_stm_flag;
  18546. #if defined(OTL_ORA_SDO_GEOMETRY)
  18547. OCIType *oraOCIType;
  18548. struct OCISDOPointObj{
  18549. OCINumber x;
  18550. OCINumber y;
  18551. OCINumber z;
  18552. };
  18553. struct OCISDOGeometryObj{
  18554. OCINumber gtype;
  18555. OCINumber srid;
  18556. OCISDOPointObj point;
  18557. OCIArray *elem_info;
  18558. OCIArray *ordinates;
  18559. };
  18560. struct OCISDOPointInd{
  18561. OCIInd _atomic;
  18562. OCIInd x;
  18563. OCIInd y;
  18564. OCIInd z;
  18565. };
  18566. struct OCISDOGeometryInd{
  18567. OCIInd _atomic;
  18568. OCIInd gtype;
  18569. OCIInd srid;
  18570. OCISDOPointInd point;
  18571. OCIInd elem_info;
  18572. OCIInd ordinates;
  18573. };
  18574. OCISDOGeometryObj **sdoobj;
  18575. OCISDOGeometryInd **sdoind;
  18576. bool needFree;
  18577. #endif
  18578. public:
  18579. void set_total_read_blob_amt(const int new_total_read_blob_amt) {
  18580. total_read_blob_amt = OTL_SCAST(ub4, new_total_read_blob_amt);
  18581. }
  18582. OTL_NODISCARD otl_adapter_enum get_otl_adapter() const { return otl_adapter; }
  18583. OTL_NODISCARD OCIStmt *get_cda() { return cda; }
  18584. OTL_NODISCARD OCIStmt **get_cda_ptr() { return &cda; }
  18585. void set_nls_flag(const bool anls_flag) { nls_flag = anls_flag; }
  18586. void set_lob_stream_mode(const bool alob_stream_mode) {
  18587. lob_stream_mode = alob_stream_mode;
  18588. }
  18589. void set_vparam_type(const int avparam_type) { vparam_type = avparam_type; }
  18590. void set_charz_flag(const bool acharz_flag) { charz_flag = acharz_flag; }
  18591. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  18592. #pragma GCC diagnostic push
  18593. #pragma GCC diagnostic ignored "-Wold-style-cast"
  18594. #endif
  18595. otl_var()
  18596. : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr),
  18597. ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr),
  18598. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18599. timestamp(nullptr),
  18600. #endif
  18601. cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0),
  18602. real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0),
  18603. cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1),
  18604. otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter), lob_stream_mode(false),
  18605. #if defined(OTL_UNICODE)
  18606. unicode_var_len(0),
  18607. #endif
  18608. csid(0),
  18609. #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8)
  18610. csfrm(SQLCS_IMPLICIT),
  18611. #endif
  18612. read_blob_amt(0),
  18613. total_read_blob_amt(0), charz_flag(false), select_stm_flag(false)
  18614. #if defined(OTL_ORA_SDO_GEOMETRY)
  18615. ,oraOCIType(nullptr)
  18616. ,sdoobj(nullptr)
  18617. ,sdoind(nullptr)
  18618. #endif
  18619. {
  18620. }
  18621. virtual ~otl_var() {
  18622. if (ftype == otl_var_refcur && cda != nullptr) {
  18623. OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT);
  18624. cda = nullptr;
  18625. }
  18626. if (ftype == otl_var_blob || (ftype == otl_var_clob && lob != nullptr)) {
  18627. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18628. OCIArrayDescriptorFree(OTL_RCAST(dvoid**,lob),
  18629. OTL_SCAST(ub4, OCI_DTYPE_LOB));
  18630. #else
  18631. for (int i = 0; i < array_size; ++i)
  18632. OCIDescriptorFree(OTL_RCAST(dvoid *, lob[i]),
  18633. OTL_SCAST(ub4, OCI_DTYPE_LOB));
  18634. #endif
  18635. }
  18636. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18637. if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp ||
  18638. ((ftype == otl_var_ltz_timestamp) && timestamp != nullptr))) {
  18639. ub4 dtype = 0;
  18640. switch (ftype) {
  18641. case otl_var_timestamp:
  18642. dtype = OCI_DTYPE_TIMESTAMP;
  18643. break;
  18644. case otl_var_ltz_timestamp:
  18645. dtype = OCI_DTYPE_TIMESTAMP_LTZ;
  18646. break;
  18647. case otl_var_tz_timestamp:
  18648. dtype = OCI_DTYPE_TIMESTAMP_TZ;
  18649. break;
  18650. }
  18651. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18652. OCIArrayDescriptorFree(OTL_RCAST(dvoid**,timestamp),dtype);
  18653. #else
  18654. for (int i = 0; i < array_size; ++i)
  18655. OCIDescriptorFree(OTL_RCAST(dvoid *, timestamp[i]), dtype);
  18656. #endif
  18657. }
  18658. #endif
  18659. if(p_v)
  18660. delete[] p_v;
  18661. if(p_ind)
  18662. delete[] p_ind;
  18663. if(p_rlen)
  18664. delete[] p_rlen;
  18665. if(p_rcode)
  18666. delete[] p_rcode;
  18667. if (!ext_buf_flag)
  18668. delete[] buf;
  18669. #if defined(__clang__)
  18670. #pragma clang diagnostic push
  18671. #pragma clang diagnostic ignored "-Wold-style-cast"
  18672. #endif
  18673. #if defined(OTL_ORA_SDO_GEOMETRY)
  18674. if(sdoobj){
  18675. if(needFree){
  18676. for(int i = 0;i < array_size;i++){
  18677. OCIObjectFree(connect->get_envhp(),
  18678. connect->get_errhp(),
  18679. OTL_RCAST(dvoid*, sdoobj[i]),
  18680. OCI_OBJECTFREE_FORCE);
  18681. }
  18682. }
  18683. delete[] sdoobj;
  18684. }
  18685. if(sdoind)delete[] sdoind;
  18686. #endif
  18687. #if defined(__clang__)
  18688. #pragma clang diagnostic pop
  18689. #endif
  18690. }
  18691. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  18692. #pragma GCC diagnostic pop
  18693. #endif
  18694. OTL_NODISCARD int write_dt(void *trg, const void *src, const int
  18695. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18696. #else
  18697. sz
  18698. #endif
  18699. ) {
  18700. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18701. OCIDateTime *trg_ptr = OTL_RCAST(OCIDateTime *, trg);
  18702. otl_datetime *src_ptr = OTL_RCAST(otl_datetime *, OTL_CCAST(void *, src));
  18703. int rc = 0;
  18704. if (ftype != otl_var_tz_timestamp) {
  18705. rc = OCIDateTimeConstruct(
  18706. connect->envhp, connect->errhp, trg_ptr,
  18707. OTL_SCAST(sb2, src_ptr->year), OTL_SCAST(ub1, src_ptr->month),
  18708. OTL_SCAST(ub1, src_ptr->day), OTL_SCAST(ub1, src_ptr->hour),
  18709. OTL_SCAST(ub1, src_ptr->minute), OTL_SCAST(ub1, src_ptr->second),
  18710. OTL_SCAST(ub4,
  18711. otl_to_fraction(OTL_SCAST(unsigned int, src_ptr->fraction),
  18712. src_ptr->frac_precision)),
  18713. nullptr, 0);
  18714. } else {
  18715. int tz_hour = src_ptr->tz_hour;
  18716. int tz_minute = src_ptr->tz_minute;
  18717. char tz_str[60];
  18718. char *tzc = otl_itoa(tz_hour, tz_str);
  18719. *tzc = ':';
  18720. ++tzc;
  18721. tzc = otl_itoa(tz_minute, tzc);
  18722. size_t tz_len = OTL_SCAST(size_t, tzc - tz_str);
  18723. rc = OCIDateTimeConstruct(
  18724. connect->envhp, connect->errhp, trg_ptr,
  18725. OTL_SCAST(sb2, src_ptr->year), OTL_SCAST(ub1, src_ptr->month),
  18726. OTL_SCAST(ub1, src_ptr->day), OTL_SCAST(ub1, src_ptr->hour),
  18727. OTL_SCAST(ub1, src_ptr->minute), OTL_SCAST(ub1, src_ptr->second),
  18728. OTL_SCAST(ub4,
  18729. otl_to_fraction(OTL_SCAST(unsigned int, src_ptr->fraction),
  18730. src_ptr->frac_precision)),
  18731. OTL_RCAST(text *, tz_str), tz_len);
  18732. }
  18733. if (rc != 0)
  18734. return 0;
  18735. return 1;
  18736. #else
  18737. memcpy(trg, src, OTL_SCAST(size_t, sz));
  18738. return 1;
  18739. #endif
  18740. }
  18741. OTL_NODISCARD int read_dt(void *trg, const void *src, const int
  18742. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18743. #else
  18744. sz
  18745. #endif
  18746. ) {
  18747. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18748. OCIDateTime *src_ptr = OTL_RCAST(OCIDateTime *, OTL_CCAST(void *, src));
  18749. otl_datetime *trg_ptr = OTL_RCAST(otl_datetime *, OTL_CCAST(void *, trg));
  18750. sb2 year;
  18751. ub1 month, day, hour, minute, sec;
  18752. ub4 fsec;
  18753. sb1 tz_hour;
  18754. sb1 tz_minute;
  18755. int rc = OCIDateTimeGetDate(connect->envhp, connect->errhp, src_ptr, &year,
  18756. &month, &day);
  18757. if (rc != 0)
  18758. return 0;
  18759. rc = OCIDateTimeGetTime(connect->envhp, connect->errhp, src_ptr, &hour,
  18760. &minute, &sec, &fsec);
  18761. if (rc != 0)
  18762. return 0;
  18763. trg_ptr->year = year;
  18764. trg_ptr->month = month;
  18765. trg_ptr->day = day;
  18766. trg_ptr->hour = hour;
  18767. trg_ptr->minute = minute;
  18768. trg_ptr->second = sec;
  18769. trg_ptr->fraction = otl_from_fraction(fsec, trg_ptr->frac_precision);
  18770. trg_ptr->tz_hour = 0;
  18771. trg_ptr->tz_minute = 0;
  18772. if (ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) {
  18773. rc = OCIDateTimeGetTimeZoneOffset(connect->envhp, connect->errhp, src_ptr,
  18774. &tz_hour, &tz_minute);
  18775. if (rc != 0)
  18776. return 0;
  18777. trg_ptr->tz_hour = tz_hour;
  18778. trg_ptr->tz_minute = tz_minute;
  18779. }
  18780. return 1;
  18781. #else
  18782. memcpy(trg, src, OTL_SCAST(size_t, sz));
  18783. return 1;
  18784. #endif
  18785. }
  18786. OTL_NODISCARD int actual_elem_size(void) { return act_elem_size; }
  18787. void init(const bool aselect_stm_flag, const int aftype, int &aelem_size,
  18788. const otl_stream_buffer_size_type aarray_size,
  18789. const void *connect_struct = nullptr, const int apl_tab_flag = 0
  18790. #if defined(OTL_ORA_SDO_GEOMETRY)
  18791. ,OCIType* oraOCIType_ =nullptr
  18792. #endif
  18793. ) {
  18794. int i;
  18795. ub4 lobEmpty = 0;
  18796. select_stm_flag = aselect_stm_flag;
  18797. connect = OTL_RCAST(otl_conn *, OTL_CCAST(void *, connect_struct));
  18798. ftype = aftype;
  18799. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  18800. if (ftype == otl_var_nchar) {
  18801. ftype = otl_var_char;
  18802. nls_flag = true;
  18803. } else if (ftype == otl_var_nclob) {
  18804. ftype = otl_var_clob;
  18805. nls_flag = true;
  18806. }
  18807. #endif
  18808. pl_tab_flag = apl_tab_flag;
  18809. act_elem_size = aelem_size;
  18810. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18811. if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp ||
  18812. ftype == otl_var_ltz_timestamp) &&
  18813. apl_tab_flag)
  18814. act_elem_size = sizeof(otl_oracle_date);
  18815. #endif
  18816. #if defined(OTL_ORA_SDO_GEOMETRY)
  18817. if(ftype == otl_var_sdo_geometry){
  18818. array_size = aarray_size;
  18819. elem_size = aelem_size;
  18820. oraOCIType = oraOCIType_;
  18821. lob = nullptr;
  18822. p_v = nullptr;
  18823. p_ind = nullptr;
  18824. p_rlen = nullptr;
  18825. p_rcode = nullptr;
  18826. if(oraOCIType){
  18827. sdoind = new OCISDOGeometryInd*[OTL_SCAST(size_t, array_size)];
  18828. sdoobj = new OCISDOGeometryObj*[OTL_SCAST(size_t, array_size)];
  18829. p_ind = new sb2[OTL_SCAST(size_t, array_size)];
  18830. for(size_t j = 0;j < OTL_SCAST(size_t, array_size);j++){
  18831. sdoind[j] = nullptr;
  18832. sdoobj[j] = nullptr;
  18833. p_ind[j] = 0;
  18834. }
  18835. }else{
  18836. sdoind = nullptr;
  18837. sdoobj = nullptr;
  18838. }
  18839. }else
  18840. #endif
  18841. if (ftype == otl_var_refcur) {
  18842. array_size = aarray_size;
  18843. elem_size = 1;
  18844. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18845. void *temp_cda = &cda;
  18846. #endif
  18847. OCIHandleAlloc(OTL_RCAST(dvoid *, connect->get_envhp()),
  18848. #if defined(__GNUC__) && (__GNUC__ >= 4)
  18849. OTL_RCAST(dvoid **, temp_cda),
  18850. #else
  18851. OTL_RCAST(dvoid **, &cda),
  18852. #endif
  18853. OCI_HTYPE_STMT, 0, nullptr);
  18854. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18855. } else if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp ||
  18856. ftype == otl_var_ltz_timestamp) &&
  18857. !apl_tab_flag) {
  18858. array_size = aarray_size;
  18859. elem_size = sizeof(OCIDateTime *);
  18860. act_elem_size = elem_size;
  18861. timestamp = new OCIDateTime *[OTL_SCAST(size_t,array_size)];
  18862. p_v = OTL_RCAST(ub1 *, timestamp);
  18863. p_ind = new sb2[OTL_SCAST(size_t,array_size)];
  18864. p_rlen = new ub2[OTL_SCAST(size_t,array_size)];
  18865. p_rcode = new ub2[OTL_SCAST(size_t,array_size)];
  18866. for (i = 0; i < array_size; ++i) {
  18867. p_ind[i] = OTL_SCAST(short, elem_size);
  18868. p_rlen[i] = OTL_SCAST(unsigned short, elem_size);
  18869. p_rcode[i] = 0;
  18870. }
  18871. if (connect != nullptr) {
  18872. otl_datetime dt;
  18873. ub4 dtype = 0;
  18874. switch (ftype) {
  18875. case otl_var_timestamp:
  18876. dtype = OCI_DTYPE_TIMESTAMP;
  18877. break;
  18878. case otl_var_ltz_timestamp:
  18879. dtype = OCI_DTYPE_TIMESTAMP_LTZ;
  18880. break;
  18881. case otl_var_tz_timestamp:
  18882. dtype = OCI_DTYPE_TIMESTAMP_TZ;
  18883. break;
  18884. }
  18885. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18886. OCIArrayDescriptorAlloc
  18887. (OTL_RCAST(dvoid*,connect->envhp),
  18888. OTL_RCAST(dvoid**,&timestamp[0]),
  18889. dtype,
  18890. OTL_SCAST(ub4,array_size),
  18891. 0,
  18892. nullptr);
  18893. #endif
  18894. for (i = 0; i < array_size; ++i) {
  18895. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18896. #else
  18897. OCIDescriptorAlloc(OTL_RCAST(dvoid *, connect->envhp),
  18898. OTL_RCAST(dvoid **, &timestamp[i]), dtype, 0,
  18899. nullptr);
  18900. #endif
  18901. (void)write_dt(timestamp[i], &dt, 1);
  18902. }
  18903. } else
  18904. timestamp = nullptr;
  18905. #endif
  18906. } else if (ftype == otl_var_blob || ftype == otl_var_clob) {
  18907. array_size = aarray_size;
  18908. elem_size = aelem_size;
  18909. lob = new OCILobLocator *[OTL_SCAST(size_t,array_size)];
  18910. p_v = OTL_RCAST(ub1 *, lob);
  18911. p_ind = new sb2[OTL_SCAST(size_t,array_size)];
  18912. p_rlen = nullptr;
  18913. p_rcode = nullptr;
  18914. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18915. if (connect != nullptr){
  18916. OCIArrayDescriptorAlloc
  18917. (OTL_RCAST(dvoid*,connect->envhp),
  18918. OTL_RCAST(dvoid**,&lob[0]),
  18919. OTL_SCAST(ub4, OCI_DTYPE_LOB),
  18920. OTL_SCAST(ub4,array_size),
  18921. 0,
  18922. nullptr);
  18923. }
  18924. #endif
  18925. if (connect != nullptr) {
  18926. for (i = 0; i < array_size; ++i) {
  18927. #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C)
  18928. #else
  18929. OCIDescriptorAlloc(OTL_RCAST(dvoid *, connect->get_envhp()),
  18930. OTL_RCAST(dvoid **, &lob[i]),
  18931. OTL_SCAST(ub4, OCI_DTYPE_LOB), 0, nullptr);
  18932. #endif
  18933. lobEmpty = 0;
  18934. OCIAttrSet(OTL_RCAST(dvoid *, lob[i]), OCI_DTYPE_LOB,
  18935. OTL_RCAST(dvoid *, &lobEmpty), 0, OCI_ATTR_LOBEMPTY,
  18936. OTL_RCAST(OCIError *, connect->get_errhp()));
  18937. }
  18938. } else
  18939. lob = nullptr;
  18940. } else {
  18941. if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) {
  18942. elem_size = aelem_size + OTL_SCAST(int, sizeof(sb4));
  18943. array_size = 1;
  18944. } else if (ftype == otl_var_raw) {
  18945. elem_size = aelem_size + OTL_SCAST(int, sizeof(short int));
  18946. array_size = aarray_size;
  18947. } else {
  18948. elem_size = aelem_size;
  18949. array_size = aarray_size;
  18950. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  18951. if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp ||
  18952. ftype == otl_var_ltz_timestamp) &&
  18953. apl_tab_flag) {
  18954. elem_size = sizeof(otl_oracle_date);
  18955. aelem_size = elem_size; // sending feedback back to the template class
  18956. }
  18957. #endif
  18958. }
  18959. #if defined(OTL_UNICODE)
  18960. if (ftype == otl_var_char) {
  18961. unsigned int unicode_buffer_size =
  18962. OTL_SCAST(unsigned int, OTL_SCAST(unsigned, elem_size) *
  18963. OTL_SCAST(unsigned, array_size) *
  18964. sizeof(OTL_WCHAR));
  18965. p_v = new ub1[unicode_buffer_size];
  18966. memset(p_v, 0, unicode_buffer_size);
  18967. } else if (ftype == otl_var_varchar_long) {
  18968. unsigned int unicode_buffer_size = OTL_SCAST(unsigned, elem_size);
  18969. p_v = new ub1[unicode_buffer_size];
  18970. memset(p_v, 0, unicode_buffer_size);
  18971. } else {
  18972. p_v = new ub1
  18973. [OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)];
  18974. memset(p_v, 0,
  18975. OTL_SCAST(size_t, elem_size) * OTL_SCAST(unsigned, array_size));
  18976. }
  18977. #elif defined(OTL_ORA_UTF8)
  18978. if (ftype == otl_var_char) {
  18979. unsigned int buffer_size =
  18980. OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size);
  18981. if (select_stm_flag)
  18982. buffer_size *= OTL_UTF8_BYTES_PER_CHAR; // 3 bytes per UTF8 char on
  18983. // SELECT by default
  18984. p_v = new ub1[buffer_size];
  18985. memset(p_v, 0, buffer_size);
  18986. } else if (ftype == otl_var_varchar_long) {
  18987. p_v = new ub1[OTL_SCAST(size_t,elem_size)];
  18988. memset(p_v, 0, OTL_SCAST(size_t, elem_size));
  18989. } else {
  18990. p_v = new ub1
  18991. [OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)];
  18992. memset(p_v, 0,
  18993. OTL_SCAST(size_t, elem_size) * OTL_SCAST(unsigned, array_size));
  18994. }
  18995. #else
  18996. p_v = new ub1[OTL_SCAST(unsigned, elem_size) *
  18997. OTL_SCAST(unsigned, array_size)];
  18998. memset(p_v, 0, OTL_SCAST(unsigned, elem_size) *
  18999. OTL_SCAST(unsigned, array_size));
  19000. #endif
  19001. p_ind = new sb2[OTL_SCAST(size_t,array_size)];
  19002. p_rlen = new ub2[OTL_SCAST(size_t,array_size)];
  19003. p_rcode = new ub2[OTL_SCAST(size_t,array_size)];
  19004. if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long ||
  19005. ftype == otl_var_raw) {
  19006. if (aelem_size > otl_short_int_max)
  19007. p_ind[0] = 0;
  19008. else
  19009. p_ind[0] = OTL_SCAST(short, aelem_size);
  19010. p_rcode[0] = 0;
  19011. } else {
  19012. for (i = 0; i < array_size; ++i) {
  19013. #if defined(OTL_UNICODE)
  19014. if (ftype == otl_var_char) {
  19015. p_ind[i] =
  19016. OTL_SCAST(sb2, elem_size * OTL_SCAST(short, sizeof(OTL_WCHAR)));
  19017. p_rlen[i] =
  19018. OTL_SCAST(ub2, elem_size * OTL_SCAST(short, sizeof(OTL_WCHAR)));
  19019. p_rcode[i] = 0;
  19020. } else {
  19021. p_ind[i] = OTL_SCAST(short, elem_size);
  19022. p_rlen[i] = OTL_SCAST(unsigned short, elem_size);
  19023. p_rcode[i] = 0;
  19024. }
  19025. #else
  19026. if (ftype == otl_var_raw) {
  19027. p_ind[i] = OTL_SCAST(short, elem_size);
  19028. p_rlen[i] = OTL_SCAST(unsigned short, elem_size);
  19029. p_rcode[i] = 0;
  19030. } else {
  19031. if (elem_size > otl_short_int_max)
  19032. p_ind[i] = 0;
  19033. else {
  19034. p_ind[i] = OTL_SCAST(short, elem_size);
  19035. p_rlen[i] = OTL_SCAST(unsigned short, elem_size);
  19036. }
  19037. p_rcode[i] = 0;
  19038. }
  19039. #endif
  19040. }
  19041. }
  19042. }
  19043. max_tab_len = OTL_SCAST(ub4, array_size);
  19044. cur_tab_len = 0;
  19045. }
  19046. void set_pl_tab_len(const int apl_tab_len) {
  19047. max_tab_len = OTL_SCAST(ub4, array_size);
  19048. cur_tab_len = OTL_SCAST(ub4, apl_tab_len);
  19049. }
  19050. OTL_NODISCARD int get_pl_tab_len(void) { return OTL_SCAST(int, cur_tab_len); }
  19051. OTL_NODISCARD int get_max_pl_tab_len(void) { return OTL_SCAST(int, max_tab_len); }
  19052. OTL_NODISCARD int get_blob_len(const int ndx, int &alen) {
  19053. ub4 blen = 0;
  19054. int rc;
  19055. alen = 0;
  19056. rc = OCILobGetLength(connect->get_svchp(), connect->get_errhp(), lob[ndx],
  19057. &blen);
  19058. alen = OTL_SCAST(int, blen);
  19059. if (rc != OCI_SUCCESS)
  19060. return 0;
  19061. return 1;
  19062. }
  19063. OTL_NODISCARD int is_blob_initialized(const int ndx, int &is_init) {
  19064. int rc;
  19065. is_init = 0;
  19066. rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(),
  19067. lob[ndx], &is_init);
  19068. if (rc != OCI_SUCCESS)
  19069. return 0;
  19070. else
  19071. return 1;
  19072. }
  19073. OTL_NODISCARD int get_blob(const int ndx, unsigned char *abuf, const int buf_size,
  19074. int &len) {
  19075. int byte_buf_size = buf_size;
  19076. #if defined(OTL_UNICODE)
  19077. if (ftype == otl_var_clob)
  19078. byte_buf_size =
  19079. OTL_SCAST(int, buf_size * OTL_SCAST(int, sizeof(OTL_CHAR)));
  19080. #endif
  19081. ub4 amt = OTL_SCAST(ub4, byte_buf_size);
  19082. ub4 offset = 1;
  19083. int rc;
  19084. #if defined(OTL_UNICODE)
  19085. if (ftype == otl_var_clob || ftype == otl_var_nclob)
  19086. memset(OTL_RCAST(void *, abuf), 0, OTL_SCAST(size_t, buf_size));
  19087. #endif
  19088. int is_init = 0;
  19089. rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(),
  19090. lob[ndx], &is_init);
  19091. if (rc != 0)
  19092. return 0;
  19093. if (!is_init) {
  19094. len = 0;
  19095. return 1;
  19096. }
  19097. #if defined(OTL_UNICODE)
  19098. if (ftype == otl_var_clob)
  19099. csid = OTL_UNICODE_ID;
  19100. else
  19101. csid = 0;
  19102. #else
  19103. csid = 0;
  19104. #endif
  19105. do {
  19106. rc = OCILobRead(
  19107. connect->get_svchp(), connect->get_errhp(), lob[ndx], &amt, offset,
  19108. OTL_RCAST(dvoid *, abuf + offset - 1),
  19109. OTL_SCAST(ub4, byte_buf_size) - offset + 1, nullptr, nullptr, csid,
  19110. OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set()));
  19111. offset += amt;
  19112. } while (rc == OCI_NEED_DATA);
  19113. len = OTL_SCAST(int, offset) - 1;
  19114. if (rc != OCI_SUCCESS) {
  19115. len = 0;
  19116. return 0;
  19117. }
  19118. return 1;
  19119. }
  19120. void set_lob_stream_flag(const int flg = 1) { lob_stream_flag = flg; }
  19121. OTL_NODISCARD int close_lob(void) {
  19122. #if defined(OTL_ORA8I) || defined(OTL_ORA9I)
  19123. int rc;
  19124. boolean flag = 0;
  19125. rc =
  19126. OCILobIsOpen(connect->get_svchp(), connect->get_errhp(), lob[0], &flag);
  19127. if (rc != OCI_SUCCESS)
  19128. return 0;
  19129. if (flag != TRUE)
  19130. return 1;
  19131. rc = OCILobClose(connect->get_svchp(), connect->get_errhp(), lob[0]);
  19132. if (rc != OCI_SUCCESS)
  19133. return 0;
  19134. #endif
  19135. return 1;
  19136. }
  19137. void close_temporary_lob(void) {
  19138. #ifdef OTL_ORA_CUSTOM_FREE_TEMP_LOB
  19139. OCILobFreeTemporary(connect->svchp, connect->errhp, lob[0]);
  19140. #endif
  19141. }
  19142. OTL_NODISCARD int put_blob(void) {
  19143. if ((ftype != otl_var_clob && ftype != otl_var_blob) || lob_stream_flag ||
  19144. buf == nullptr || buf_len == 0)
  19145. return 1;
  19146. int rc;
  19147. int byte_buf_len = buf_len;
  19148. #if defined(OTL_UNICODE)
  19149. if (ftype == otl_var_clob)
  19150. byte_buf_len = OTL_SCAST(int, buf_len * OTL_SCAST(int, sizeof(OTL_CHAR)));
  19151. #endif
  19152. ub4 amt = OTL_SCAST(ub4, buf_len);
  19153. ub4 offset = 1;
  19154. #if defined(OTL_UNICODE)
  19155. if (ftype == otl_var_clob)
  19156. csid = OTL_UNICODE_ID;
  19157. else
  19158. csid = 0;
  19159. #else
  19160. csid = 0;
  19161. #endif
  19162. rc = OCILobWrite(
  19163. connect->get_svchp(), connect->get_errhp(), lob[0], &amt, offset,
  19164. OTL_RCAST(dvoid *, buf), OTL_SCAST(ub4, byte_buf_len), OCI_ONE_PIECE,
  19165. nullptr, nullptr, csid,
  19166. OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set()));
  19167. if (rc != 0)
  19168. return 0;
  19169. return 1;
  19170. }
  19171. OTL_NODISCARD int read_blob(otl_long_string &s, const int andx, int &aoffset,
  19172. int alob_len) {
  19173. ub4 byte_buf_size = OTL_SCAST(ub4, s.get_buf_size());
  19174. #if defined(OTL_UNICODE)
  19175. if (ftype == otl_var_clob)
  19176. byte_buf_size = OTL_SCAST(ub4, byte_buf_size * sizeof(OTL_CHAR));
  19177. #endif
  19178. ub4 &amt = read_blob_amt;
  19179. amt = 0;
  19180. if (aoffset == 1)
  19181. total_read_blob_amt = 0;
  19182. ub4 &offset = total_read_blob_amt;
  19183. if (offset == 0)
  19184. offset = 1;
  19185. int rc;
  19186. int is_init = 0;
  19187. rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(), lob[0],
  19188. &is_init);
  19189. if (rc != OCI_SUCCESS)
  19190. return 0;
  19191. if (!is_init) {
  19192. s.set_len(0);
  19193. return 1;
  19194. }
  19195. #if defined(OTL_UNICODE)
  19196. if (ftype == otl_var_clob)
  19197. csid = OTL_UNICODE_ID;
  19198. else
  19199. csid = 0;
  19200. #else
  19201. csid = 0;
  19202. #endif
  19203. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  19204. if (connect->get_lob_prefetch_size() > 0) {
  19205. ub4 pom_blen = 0;
  19206. rc = OCILobGetLength(connect->get_svchp(), connect->get_errhp(),
  19207. lob[andx], &pom_blen);
  19208. if (rc != OCI_SUCCESS)
  19209. return 0;
  19210. amt = pom_blen;
  19211. }
  19212. #endif
  19213. rc = OCILobRead(
  19214. connect->get_svchp(), connect->get_errhp(), lob[andx], &amt, offset,
  19215. OTL_RCAST(dvoid *, s.v), OTL_SCAST(ub4, byte_buf_size), nullptr,
  19216. nullptr, csid,
  19217. OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set()));
  19218. #if defined(OTL_UNICODE)
  19219. if (ftype == otl_var_clob && aoffset > 1 && amt == byte_buf_size)
  19220. amt /= OTL_SCAST(ub4, sizeof(OTL_CHAR));
  19221. #endif
  19222. #if defined(OTL_ORA_UTF8)
  19223. switch (rc) {
  19224. case OCI_SUCCESS:
  19225. s.set_len(OTL_SCAST(int, amt));
  19226. offset += amt;
  19227. if (ftype == otl_var_blob)
  19228. aoffset += s.len();
  19229. else
  19230. aoffset = alob_len + 1;
  19231. return 1;
  19232. case OCI_NEED_DATA:
  19233. s.set_len(OTL_SCAST(int, amt));
  19234. offset += amt;
  19235. if (ftype == otl_var_blob)
  19236. aoffset += s.len();
  19237. else
  19238. aoffset = 2;
  19239. return 1;
  19240. case OCI_ERROR:
  19241. default:
  19242. s.set_len(0);
  19243. return 0;
  19244. }
  19245. #else
  19246. switch (rc) {
  19247. case OCI_SUCCESS:
  19248. if (aoffset == 1)
  19249. s.set_len(alob_len);
  19250. else
  19251. s.set_len(alob_len - aoffset + 1);
  19252. break;
  19253. case OCI_NEED_DATA:
  19254. s.set_len(OTL_SCAST(int, amt));
  19255. break;
  19256. case OCI_ERROR:
  19257. s.set_len(0);
  19258. break;
  19259. }
  19260. if (rc == OCI_NEED_DATA || rc == OCI_SUCCESS) {
  19261. aoffset += s.len();
  19262. return 1;
  19263. } else
  19264. return 0;
  19265. #endif
  19266. }
  19267. OTL_NODISCARD int write_blob(const otl_long_string &s, const int alob_len, int &aoffset,
  19268. otl_cur0 & /* cur */) {
  19269. if (!lob_stream_flag)
  19270. return 1;
  19271. int rc;
  19272. int byte_s_length = s.len();
  19273. #if defined(OTL_UNICODE)
  19274. if (ftype == otl_var_clob)
  19275. byte_s_length =
  19276. OTL_SCAST(int, s.len() * OTL_SCAST(int, sizeof(OTL_CHAR)));
  19277. #endif
  19278. ub4 offset = OTL_SCAST(ub4, aoffset);
  19279. ub4 amt = 0;
  19280. ub1 mode;
  19281. if (aoffset == 1 && alob_len > s.len())
  19282. mode = OCI_FIRST_PIECE;
  19283. else if (aoffset == 1 && alob_len <= s.len()) {
  19284. mode = OCI_ONE_PIECE;
  19285. amt = OTL_SCAST(ub4, s.len());
  19286. } else if ((aoffset - 1) + s.len() < alob_len)
  19287. mode = OCI_NEXT_PIECE;
  19288. else
  19289. mode = OCI_LAST_PIECE;
  19290. #if defined(OTL_UNICODE)
  19291. if (ftype == otl_var_clob)
  19292. csid = OTL_UNICODE_ID;
  19293. else
  19294. csid = 0;
  19295. #else
  19296. csid = 0;
  19297. #endif
  19298. if (mode == OCI_FIRST_PIECE || mode == OCI_ONE_PIECE) {
  19299. rc = OCILobTrim(connect->get_svchp(), connect->get_errhp(), lob[0], 0);
  19300. if (rc != OCI_SUCCESS)
  19301. return 0;
  19302. }
  19303. if (alob_len == 0)
  19304. return 1;
  19305. rc = OCILobWrite(
  19306. connect->get_svchp(), connect->get_errhp(), lob[0],
  19307. OTL_RCAST(ub4 *, &amt), offset, OTL_RCAST(dvoid *, s.v),
  19308. OTL_SCAST(ub4, byte_s_length), mode, nullptr, nullptr, csid,
  19309. OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set()));
  19310. if (rc == OCI_NEED_DATA || rc == OCI_SUCCESS ||
  19311. rc == OCI_SUCCESS_WITH_INFO) {
  19312. aoffset += s.len();
  19313. return 1;
  19314. }
  19315. return 0;
  19316. }
  19317. OTL_NODISCARD int save_blob(const unsigned char *abuf, const int len,
  19318. const int extern_buffer_flag) {
  19319. if (extern_buffer_flag) {
  19320. if (buf != nullptr && !ext_buf_flag) {
  19321. delete[] buf;
  19322. buf = nullptr;
  19323. }
  19324. ext_buf_flag = 1;
  19325. buf_len = len;
  19326. real_buf_len = len;
  19327. buf = OTL_CCAST(unsigned char *, abuf);
  19328. } else {
  19329. if (!ext_buf_flag && buf != nullptr && real_buf_len >= len) {
  19330. ext_buf_flag = 0;
  19331. buf_len = len;
  19332. #if defined(OTL_UNICODE)
  19333. memcpy(buf, abuf, OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR));
  19334. #else
  19335. memcpy(buf, abuf, OTL_SCAST(size_t, buf_len));
  19336. #endif
  19337. } else {
  19338. if (buf != nullptr && !ext_buf_flag) {
  19339. delete[] buf;
  19340. buf = nullptr;
  19341. }
  19342. ext_buf_flag = 0;
  19343. buf_len = len;
  19344. real_buf_len = len;
  19345. #if defined(OTL_UNICODE)
  19346. buf = new ub1[OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR)];
  19347. memcpy(buf, abuf, OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR));
  19348. #else
  19349. buf = new ub1[OTL_SCAST(size_t,buf_len)];
  19350. memcpy(buf, abuf, OTL_SCAST(size_t, buf_len));
  19351. #endif
  19352. }
  19353. }
  19354. return 1;
  19355. }
  19356. #if defined(OTL_ORA_SDO_GEOMETRY)
  19357. OTL_NODISCARD bool getValue(OCINumber *num, unsigned int &value){
  19358. int status = OCINumberToInt(connect->get_errhp(),
  19359. num,
  19360. sizeof(unsigned int),
  19361. OCI_NUMBER_UNSIGNED,
  19362. OTL_RCAST(dvoid*, &value));
  19363. if(status)
  19364. return false;
  19365. else
  19366. return true;
  19367. }
  19368. OTL_NODISCARD bool getValue(OCINumber *num, int &value){
  19369. int status = OCINumberToInt(connect->get_errhp(),
  19370. num, sizeof(int),
  19371. OCI_NUMBER_SIGNED,
  19372. OTL_RCAST(dvoid*, &value));
  19373. if(status)
  19374. return false;
  19375. else
  19376. return true;
  19377. }
  19378. OTL_NODISCARD bool getValue(OCINumber *num, double &value){
  19379. int status = OCINumberToReal(connect->get_errhp(),
  19380. num, sizeof(double),
  19381. OTL_RCAST(dvoid*, &value));
  19382. if(status)
  19383. return false;
  19384. else
  19385. return true;
  19386. }
  19387. OTL_NODISCARD bool getArraySize(OCIColl *coll, int &nSize){
  19388. int status = OCICollSize(connect->get_envhp(),
  19389. connect->get_errhp(),
  19390. coll,
  19391. OTL_RCAST(sb4*, &nSize));
  19392. if(status)
  19393. return false;
  19394. else
  19395. return true;
  19396. }
  19397. OTL_NODISCARD int read_geometry(oci_spatial_geometry& geometry, int ndx){
  19398. if(!sdoobj || !sdoind || !sdoobj[ndx] || !sdoind[ndx]){
  19399. geometry.isNull = true;
  19400. return 0;
  19401. }
  19402. #if defined(__clang__)
  19403. #pragma clang diagnostic push
  19404. #pragma clang diagnostic ignored "-Wold-style-cast"
  19405. #endif
  19406. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19407. #pragma GCC diagnostic push
  19408. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19409. #endif
  19410. if(sdoind[ndx]->_atomic == OCI_IND_NULL){
  19411. geometry.isNull = true;
  19412. return 1;
  19413. }
  19414. #if defined(__clang__)
  19415. #pragma clang diagnostic pop
  19416. #endif
  19417. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19418. #pragma GCC diagnostic pop
  19419. #endif
  19420. if(!getValue(&sdoobj[ndx]->gtype, geometry.gtype)){
  19421. geometry.isNull = true;
  19422. return 0;
  19423. }
  19424. int nDims = (geometry.gtype / 1000) % 10;
  19425. int iType = geometry.gtype % 100;
  19426. if(iType == 0){
  19427. geometry.isNull = true;
  19428. return 0;
  19429. }
  19430. if((geometry.gtype / 100) % 10 != 0){
  19431. return 0;
  19432. }
  19433. #if defined(__clang__)
  19434. #pragma clang diagnostic push
  19435. #pragma clang diagnostic ignored "-Wold-style-cast"
  19436. #endif
  19437. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19438. #pragma GCC diagnostic push
  19439. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19440. #endif
  19441. if(sdoind[ndx]->srid == OCI_IND_NOTNULL){
  19442. if(!getValue(&sdoobj[ndx]->srid, geometry.srid)){
  19443. geometry.isNull = true;
  19444. return 0;
  19445. }
  19446. #if defined(__clang__)
  19447. #pragma clang diagnostic pop
  19448. #endif
  19449. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19450. #pragma GCC diagnostic pop
  19451. #endif
  19452. }
  19453. int nElems;
  19454. if(!getArraySize(sdoobj[ndx]->elem_info, nElems)){
  19455. geometry.isNull = true;
  19456. return 0;
  19457. }
  19458. int nOrds;
  19459. if(!getArraySize(sdoobj[ndx]->ordinates, nOrds)){
  19460. geometry.isNull = true;
  19461. return 0;
  19462. }
  19463. if(iType == 1 && nElems == 0){
  19464. #if defined(__clang__)
  19465. #pragma clang diagnostic push
  19466. #pragma clang diagnostic ignored "-Wold-style-cast"
  19467. #endif
  19468. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19469. #pragma GCC diagnostic push
  19470. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19471. #endif
  19472. if(sdoind[ndx]->_atomic != OCI_IND_NOTNULL ||
  19473. sdoind[ndx]->point.x != OCI_IND_NOTNULL ||
  19474. sdoind[ndx]->point.y != OCI_IND_NOTNULL){
  19475. geometry.isNull = true;
  19476. return 0;
  19477. }
  19478. #if defined(__clang__)
  19479. #pragma clang diagnostic pop
  19480. #endif
  19481. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19482. #pragma GCC diagnostic pop
  19483. #endif
  19484. if(!getValue(&sdoobj[ndx]->point.x, geometry.x)){
  19485. geometry.isNull = true;
  19486. return 0;
  19487. }
  19488. if(!getValue(&sdoobj[ndx]->point.y, geometry.y)){
  19489. geometry.isNull = true;
  19490. return 0;
  19491. }
  19492. #if defined(__clang__)
  19493. #pragma clang diagnostic push
  19494. #pragma clang diagnostic ignored "-Wold-style-cast"
  19495. #endif
  19496. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19497. #pragma GCC diagnostic push
  19498. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19499. #endif
  19500. if(nDims > 2){
  19501. if(sdoind[ndx]->point.z != OCI_IND_NOTNULL){
  19502. geometry.isNull = true;
  19503. return 0;
  19504. }
  19505. if(!getValue(&sdoobj[ndx]->point.z, geometry.z)){
  19506. geometry.isNull = true;
  19507. return 0;
  19508. }
  19509. }
  19510. #if defined(__clang__)
  19511. #pragma clang diagnostic pop
  19512. #endif
  19513. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19514. #pragma GCC diagnostic pop
  19515. #endif
  19516. geometry.isNull = false;
  19517. return 1;
  19518. }else{
  19519. #if defined(__clang__)
  19520. #pragma clang diagnostic push
  19521. #pragma clang diagnostic ignored "-Wold-style-cast"
  19522. #endif
  19523. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19524. #pragma GCC diagnostic push
  19525. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19526. #endif
  19527. if(sdoind[ndx]->_atomic != OCI_IND_NOTNULL){
  19528. geometry.isNull = true;
  19529. return 0;
  19530. }
  19531. #if defined(__clang__)
  19532. #pragma clang diagnostic pop
  19533. #endif
  19534. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19535. #pragma GCC diagnostic pop
  19536. #endif
  19537. geometry.eleminfo.resize(OTL_SCAST(size_t,nElems));
  19538. #if defined(OTL_ORA10G_R2)
  19539. {
  19540. uword nelems = OTL_SCAST(uword,nElems);
  19541. std::vector<boolean> exists(OTL_SCAST(size_t,nElems));
  19542. std::vector<OCINumber*> numbers(OTL_SCAST(size_t,nElems));
  19543. int result = OCICollGetElemArray(connect->get_envhp(), connect->get_errhp(),
  19544. sdoobj[ndx]->elem_info,
  19545. OTL_SCAST(sb4, 0),
  19546. &exists[0],
  19547. OTL_RCAST(void**, &numbers[0]), nullptr, &nelems);
  19548. if(result || !exists[0]){
  19549. geometry.isNull = true;
  19550. return 0;
  19551. }
  19552. for(unsigned int i = 0; i < nelems; i++){
  19553. if(!getValue(numbers[i], geometry.eleminfo[i])){
  19554. geometry.isNull = true;
  19555. return 0;
  19556. }
  19557. }
  19558. }
  19559. #else
  19560. for(int i = 0; i < nElems;i++){
  19561. boolean exists(true);
  19562. OCINumber* numbers;
  19563. int result = OCICollGetElem(connect->get_envhp(),
  19564. connect->get_errhp(),
  19565. sdoobj[ndx]->elem_info,
  19566. i,
  19567. &exists, (void**)&numbers,
  19568. 0);
  19569. if(result || !exists){
  19570. geometry.isNull = true;
  19571. return 0;
  19572. }
  19573. if(!getValue(numbers, geometry.eleminfo[i])){
  19574. geometry.isNull = true;
  19575. return 0;
  19576. }
  19577. }
  19578. #endif
  19579. geometry.ordinates.resize(OTL_SCAST(size_t,nOrds));
  19580. #if defined(OTL_ORA10G_R2)
  19581. {
  19582. std::vector<boolean> exists(OTL_SCAST(size_t,nOrds));
  19583. std::vector<OCINumber*> numbers(OTL_SCAST(size_t,nOrds));
  19584. uword nords = OTL_SCAST(uword,nOrds);
  19585. int result = OCICollGetElemArray(connect->get_envhp(),
  19586. connect->get_errhp(),
  19587. sdoobj[ndx]->ordinates,
  19588. OTL_SCAST(sb4, 0),
  19589. &exists[0],
  19590. OTL_RCAST(void**, &numbers[0]), nullptr, &nords);
  19591. if(result != OCI_SUCCESS || !exists[0]){
  19592. geometry.isNull = true;
  19593. return 0;
  19594. }
  19595. result = OCINumberToRealArray(connect->get_errhp(),
  19596. OTL_CCAST(const OCINumber **,&numbers[0]),
  19597. nords,
  19598. sizeof(double),
  19599. &geometry.ordinates[0]);
  19600. if(result != OCI_SUCCESS){
  19601. geometry.isNull = true;
  19602. return 0;
  19603. }
  19604. }
  19605. #else
  19606. for(int i = 0; i < nOrds;i++){
  19607. boolean exists(true);
  19608. void* numbers;
  19609. int result = OCICollGetElem(connect->get_envhp(),
  19610. connect->get_errhp(),
  19611. sdoobj[ndx]->ordinates,
  19612. i,
  19613. &exists,
  19614. (void**)&numbers,
  19615. 0);
  19616. if(result || !exists){
  19617. geometry.isNull = true;
  19618. return 0;
  19619. }
  19620. if(!getValue((OCINumber*)numbers, geometry.ordinates[i])){
  19621. geometry.isNull = true;
  19622. return 0;
  19623. }
  19624. }
  19625. #endif
  19626. }
  19627. geometry.isNull = false;
  19628. return 1;
  19629. }
  19630. OTL_NODISCARD int write_geometry(const oci_spatial_geometry& g, int ndx){
  19631. sb4 n;
  19632. int status = OCICollSize(connect->get_envhp(),
  19633. connect->get_errhp(),
  19634. sdoobj[ndx]->elem_info,
  19635. &n);
  19636. if(status)return 0;
  19637. status = OCICollTrim(connect->get_envhp(),
  19638. connect->get_errhp(),
  19639. n,
  19640. sdoobj[ndx]->elem_info);
  19641. if(status)return 0;
  19642. status = OCICollSize(connect->get_envhp(),
  19643. connect->get_errhp(),
  19644. sdoobj[ndx]->ordinates,
  19645. &n);
  19646. if(status)return 0;
  19647. status = OCICollTrim(connect->get_envhp(),
  19648. connect->get_errhp(),
  19649. n,
  19650. sdoobj[ndx]->ordinates);
  19651. if(status)return 0;
  19652. if(g.isNull){
  19653. #if defined(__clang__)
  19654. #pragma clang diagnostic push
  19655. #pragma clang diagnostic ignored "-Wold-style-cast"
  19656. #endif
  19657. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19658. #pragma GCC diagnostic push
  19659. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19660. #endif
  19661. sdoind[ndx]->_atomic = OCI_IND_NULL;
  19662. #if defined(__clang__)
  19663. #pragma clang diagnostic pop
  19664. #endif
  19665. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19666. #pragma GCC diagnostic pop
  19667. #endif
  19668. }else{
  19669. #if defined(__clang__)
  19670. #pragma clang diagnostic push
  19671. #pragma clang diagnostic ignored "-Wold-style-cast"
  19672. #endif
  19673. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19674. #pragma GCC diagnostic push
  19675. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19676. #endif
  19677. sdoind[ndx]->_atomic = OCI_IND_NOTNULL;
  19678. sdoind[ndx]->gtype = OCI_IND_NOTNULL;
  19679. sdoind[ndx]->srid = OCI_IND_NOTNULL;
  19680. #if defined(__clang__)
  19681. #pragma clang diagnostic pop
  19682. #endif
  19683. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19684. #pragma GCC diagnostic pop
  19685. #endif
  19686. status = OCINumberFromInt(connect->get_errhp(),
  19687. OTL_RCAST(CONST dvoid*, &g.gtype),
  19688. sizeof(unsigned int),
  19689. OCI_NUMBER_UNSIGNED,
  19690. &sdoobj[ndx]->gtype);
  19691. if(status)return 0;
  19692. status = OCINumberFromInt(connect->get_errhp(),
  19693. OTL_RCAST(CONST dvoid*, &g.srid),
  19694. sizeof(int),
  19695. OCI_NUMBER_SIGNED,
  19696. &sdoobj[ndx]->srid);
  19697. if(status)return 0;
  19698. if(g.gtype % 100 == 1){
  19699. #if defined(__clang__)
  19700. #pragma clang diagnostic push
  19701. #pragma clang diagnostic ignored "-Wold-style-cast"
  19702. #endif
  19703. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19704. #pragma GCC diagnostic push
  19705. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19706. #endif
  19707. sdoind[ndx]->point._atomic = OCI_IND_NOTNULL;
  19708. sdoind[ndx]->point.x = OCI_IND_NOTNULL;
  19709. sdoind[ndx]->point.y = OCI_IND_NOTNULL;
  19710. sdoind[ndx]->elem_info = OCI_IND_NULL;
  19711. sdoind[ndx]->ordinates = OCI_IND_NULL;
  19712. #if defined(__clang__)
  19713. #pragma clang diagnostic pop
  19714. #endif
  19715. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19716. #pragma GCC diagnostic pop
  19717. #endif
  19718. status = OCINumberFromReal(connect->get_errhp(),
  19719. OTL_RCAST(CONST dvoid*, &g.x),
  19720. sizeof(double),
  19721. &sdoobj[ndx]->point.x);
  19722. if(status)return 0;
  19723. status = OCINumberFromReal(connect->get_errhp(),
  19724. OTL_RCAST(CONST dvoid*, &g.y),
  19725. sizeof(double),
  19726. &sdoobj[ndx]->point.y);
  19727. if(status)return 0;
  19728. if((g.gtype / 1000 % 10) == 3){
  19729. #if defined(__clang__)
  19730. #pragma clang diagnostic push
  19731. #pragma clang diagnostic ignored "-Wold-style-cast"
  19732. #endif
  19733. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19734. #pragma GCC diagnostic push
  19735. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19736. #endif
  19737. sdoind[ndx]->point.z = OCI_IND_NOTNULL;
  19738. #if defined(__clang__)
  19739. #pragma clang diagnostic pop
  19740. #endif
  19741. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19742. #pragma GCC diagnostic pop
  19743. #endif
  19744. status = OCINumberFromReal(connect->get_errhp(),
  19745. OTL_RCAST(CONST dvoid*, &g.z),
  19746. sizeof(double),
  19747. &sdoobj[ndx]->point.z);
  19748. if(status)return 0;
  19749. }else
  19750. #if defined(__clang__)
  19751. #pragma clang diagnostic push
  19752. #pragma clang diagnostic ignored "-Wold-style-cast"
  19753. #endif
  19754. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19755. #pragma GCC diagnostic push
  19756. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19757. #endif
  19758. sdoind[ndx]->point.z = OCI_IND_NULL;
  19759. #if defined(__clang__)
  19760. #pragma clang diagnostic pop
  19761. #endif
  19762. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19763. #pragma GCC diagnostic pop
  19764. #endif
  19765. }else{
  19766. #if defined(__clang__)
  19767. #pragma clang diagnostic push
  19768. #pragma clang diagnostic ignored "-Wold-style-cast"
  19769. #endif
  19770. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19771. #pragma GCC diagnostic push
  19772. #pragma GCC diagnostic ignored "-Wold-style-cast"
  19773. #endif
  19774. sdoind[ndx]->point._atomic = OCI_IND_NULL;
  19775. sdoind[ndx]->elem_info = g.eleminfo.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL;
  19776. sdoind[ndx]->ordinates = g.ordinates.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL;
  19777. #if defined(__clang__)
  19778. #pragma clang diagnostic pop
  19779. #endif
  19780. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  19781. #pragma GCC diagnostic pop
  19782. #endif
  19783. for(std::size_t ind_elem = 0;ind_elem < g.eleminfo.size();ind_elem++){
  19784. OCINumber n2;
  19785. status = OCINumberFromInt(connect->get_errhp(),
  19786. OTL_RCAST(CONST dvoid*,
  19787. &g.eleminfo[ind_elem]),
  19788. sizeof(int),
  19789. OCI_NUMBER_SIGNED,
  19790. &n2);
  19791. if(status)return 0;
  19792. status = OCICollAppend(connect->get_envhp(),
  19793. connect->get_errhp(),
  19794. OTL_RCAST(CONST dvoid*, &n2),
  19795. nullptr,
  19796. sdoobj[ndx]->elem_info);
  19797. if(status)return 0;
  19798. }
  19799. for(std::size_t ind_elem = 0;ind_elem < g.ordinates.size();ind_elem++){
  19800. OCINumber n2;
  19801. status = OCINumberFromReal(connect->get_errhp(),
  19802. OTL_RCAST(CONST dvoid*,
  19803. &g.ordinates[ind_elem]),
  19804. sizeof(double),
  19805. &n2);
  19806. if(status)return 0;
  19807. status = OCICollAppend(connect->get_envhp(),
  19808. connect->get_errhp(),
  19809. OTL_RCAST(CONST dvoid*, &n2),
  19810. nullptr,
  19811. sdoobj[ndx]->ordinates);
  19812. if(status)return 0;
  19813. }
  19814. }
  19815. }
  19816. return 1;
  19817. }
  19818. #endif
  19819. void set_null(int ndx) { p_ind[ndx] = -1; }
  19820. void set_not_null(int ndx, int pelem_size) {
  19821. switch (ftype) {
  19822. case otl_var_char:
  19823. if (pelem_size > otl_short_int_max)
  19824. p_ind[ndx] = 0;
  19825. else
  19826. p_ind[ndx] = OTL_SCAST(short, pelem_size);
  19827. break;
  19828. case otl_var_varchar_long:
  19829. case otl_var_raw_long:
  19830. p_ind[0] = 0;
  19831. break;
  19832. case otl_var_raw:
  19833. if (pelem_size > otl_short_int_max)
  19834. p_ind[ndx] = 0;
  19835. else
  19836. p_ind[ndx] = OTL_SCAST(short, pelem_size);
  19837. break;
  19838. case otl_var_clob:
  19839. case otl_var_blob:
  19840. if (lob_stream_flag == 0) {
  19841. ub4 lobEmpty = 0;
  19842. OCIAttrSet(OTL_RCAST(dvoid *, lob[ndx]), OCI_DTYPE_LOB,
  19843. OTL_RCAST(dvoid *, &lobEmpty), 0, OCI_ATTR_LOBEMPTY,
  19844. OTL_RCAST(OCIError *, connect->get_errhp()));
  19845. }
  19846. break;
  19847. default:
  19848. p_ind[ndx] = OTL_SCAST(short, pelem_size);
  19849. break;
  19850. }
  19851. }
  19852. void set_len(int len, int ndx) {
  19853. if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) {
  19854. #if defined(OTL_UNICODE)
  19855. if (ftype == otl_var_varchar_long)
  19856. *OTL_RCAST(sb4 *, p_v) = len * OTL_SCAST(sb4, sizeof(OTL_CHAR));
  19857. else
  19858. *OTL_RCAST(sb4 *, p_v) = len;
  19859. #else
  19860. *OTL_RCAST(sb4 *, p_v) = len;
  19861. #endif
  19862. } else
  19863. p_rlen[ndx] = OTL_SCAST(unsigned short, len);
  19864. }
  19865. int get_len(int ndx) {
  19866. if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) {
  19867. if (p_ind[0] == -1)
  19868. return 0;
  19869. else {
  19870. #if defined(OTL_UNICODE)
  19871. #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES)
  19872. if (ftype == otl_var_varchar_long)
  19873. return *OTL_RCAST(sb4 *, p_v);
  19874. else
  19875. return *OTL_RCAST(sb4 *, p_v);
  19876. #else
  19877. if (ftype == otl_var_varchar_long)
  19878. return (*OTL_RCAST(sb4 *, p_v)) / sizeof(OTL_CHAR);
  19879. else
  19880. return *OTL_RCAST(sb4 *, p_v);
  19881. #endif
  19882. #else
  19883. return *OTL_RCAST(sb4 *, p_v);
  19884. #endif
  19885. }
  19886. } else
  19887. return p_rlen[ndx];
  19888. }
  19889. OTL_NODISCARD int is_null(int ndx) { return p_ind[ndx] == -1; }
  19890. OTL_NODISCARD void *val(int ndx, int pelem_size) {
  19891. switch (ftype) {
  19892. #if defined(OTL_UNICODE)
  19893. case otl_var_char:
  19894. return OTL_RCAST(
  19895. void *,
  19896. &p_v[OTL_SCAST(unsigned, ndx * pelem_size) * sizeof(OTL_WCHAR)]);
  19897. #endif
  19898. #if defined(OTL_ORA_UTF8)
  19899. case otl_var_char:
  19900. if (select_stm_flag)
  19901. return OTL_RCAST(void *, &p_v[OTL_SCAST(unsigned, ndx * pelem_size) *
  19902. OTL_UTF8_BYTES_PER_CHAR]);
  19903. else
  19904. return OTL_RCAST(void *, &p_v[OTL_SCAST(unsigned, ndx * pelem_size)]);
  19905. #endif
  19906. case otl_var_raw:
  19907. return OTL_RCAST(
  19908. void *, &p_v[(OTL_SCAST(unsigned, ndx)) *
  19909. (OTL_SCAST(unsigned, pelem_size) + sizeof(short int))]);
  19910. case otl_var_varchar_long:
  19911. case otl_var_raw_long:
  19912. return OTL_RCAST(void *, p_v + sizeof(sb4));
  19913. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  19914. case otl_var_timestamp:
  19915. case otl_var_tz_timestamp:
  19916. case otl_var_ltz_timestamp:
  19917. if (!pl_tab_flag)
  19918. return OTL_RCAST(void *, timestamp[ndx]);
  19919. #endif
  19920. default:
  19921. return OTL_RCAST(
  19922. void *,
  19923. &p_v[OTL_SCAST(unsigned, ndx) * OTL_SCAST(unsigned, pelem_size)]);
  19924. }
  19925. }
  19926. OTL_NODISCARD static int int2ext(int int_type) {
  19927. switch (int_type) {
  19928. case inVarChar2:
  19929. return extCChar;
  19930. case inNumber:
  19931. return extFloat;
  19932. case inLong:
  19933. return extLongVarChar;
  19934. case inRowId:
  19935. return extCChar;
  19936. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  19937. case inDate:
  19938. return extTimestamp;
  19939. case inTimestamp:
  19940. return extTimestamp;
  19941. case inTimestamp_TZ:
  19942. return extTimestamp_TZ;
  19943. case inTimestamp_LTZ:
  19944. return extTimestamp_LTZ;
  19945. case inIntervalYM:
  19946. return extCChar;
  19947. case inIntervalDS:
  19948. return extCChar;
  19949. #else
  19950. case inDate:
  19951. return extDate;
  19952. #endif
  19953. case inRaw:
  19954. return extRaw;
  19955. case inLongRaw:
  19956. return extLongVarRaw;
  19957. case inChar:
  19958. return extCChar;
  19959. #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)
  19960. #if defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES)
  19961. case inBFloat:
  19962. return extBFloat;
  19963. case inBDouble:
  19964. return extBDouble;
  19965. #else
  19966. case inBFloat:
  19967. return extFloat;
  19968. case inBDouble:
  19969. return extFloat;
  19970. #endif
  19971. #endif
  19972. case inCLOB:
  19973. return extCLOB;
  19974. case inBLOB:
  19975. return extBLOB;
  19976. default:
  19977. return otl_unsupported_type;
  19978. }
  19979. }
  19980. OTL_NODISCARD static int datatype_size(int aftype, int maxsz, int int_type,
  19981. int max_long_size) {
  19982. switch (aftype) {
  19983. case extCChar:
  19984. switch (int_type) {
  19985. #if defined(OTL_ORA_TIMESTAMP)
  19986. case inIntervalYM:
  19987. return 30;
  19988. case inIntervalDS:
  19989. return 30;
  19990. #endif
  19991. case inRowId:
  19992. return 30;
  19993. case inDate:
  19994. return otl_oracle_date_size;
  19995. case inRaw:
  19996. return max_long_size;
  19997. default:
  19998. return maxsz + 1;
  19999. }
  20000. #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \
  20001. defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES)
  20002. case extBFloat:
  20003. case extBDouble:
  20004. return sizeof(double);
  20005. #endif
  20006. case extLongVarChar:
  20007. return max_long_size;
  20008. case extLongVarRaw:
  20009. return max_long_size;
  20010. case extRaw:
  20011. return maxsz;
  20012. case extCLOB:
  20013. return max_long_size;
  20014. case extBLOB:
  20015. return max_long_size;
  20016. case extFloat:
  20017. return sizeof(double);
  20018. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20019. case extDate:
  20020. return sizeof(OCIDateTime *);
  20021. case extTimestamp:
  20022. case extTimestamp_TZ:
  20023. case extTimestamp_LTZ:
  20024. return sizeof(OCIDateTime *);
  20025. #else
  20026. case extDate:
  20027. return otl_oracle_date_size;
  20028. #endif
  20029. default:
  20030. return 0;
  20031. }
  20032. }
  20033. static void map_ftype(otl_column_desc &desc, const int max_long_size,
  20034. int &aftype, int &aelem_size,
  20035. otl_select_struct_override &a_override,
  20036. const int column_ndx, const int /*connection_type*/) {
  20037. int ndx = a_override.find(column_ndx);
  20038. if (ndx == -1) {
  20039. aftype = int2ext(desc.dbtype);
  20040. aelem_size = datatype_size(aftype, OTL_SCAST(int, desc.dbsize),
  20041. desc.dbtype, max_long_size);
  20042. switch (aftype) {
  20043. #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \
  20044. defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES)
  20045. case extBFloat:
  20046. case extBDouble:
  20047. if (a_override.get_all_mask() & otl_all_num2str) {
  20048. aftype = otl_var_char;
  20049. aelem_size = otl_num_str_size;
  20050. } else
  20051. aftype = otl_var_double;
  20052. break;
  20053. #endif
  20054. case extCChar:
  20055. aftype = otl_var_char;
  20056. break;
  20057. case extRaw:
  20058. aftype = otl_var_raw;
  20059. break;
  20060. case extFloat:
  20061. if (a_override.get_all_mask() & otl_all_num2str) {
  20062. aftype = otl_var_char;
  20063. aelem_size = otl_num_str_size;
  20064. } else {
  20065. #if defined(OTL_ORA_CUSTOM_MAP_NUMBER_ON_SELECT)
  20066. OTL_ORA_CUSTOM_MAP_NUMBER_ON_SELECT(aftype, aelem_size, desc);
  20067. #else
  20068. aftype = otl_var_double;
  20069. #endif
  20070. }
  20071. break;
  20072. case extLongVarChar:
  20073. aftype = otl_var_varchar_long;
  20074. break;
  20075. case extLongVarRaw:
  20076. aftype = otl_var_raw_long;
  20077. break;
  20078. case extCLOB:
  20079. aftype = otl_var_clob;
  20080. break;
  20081. case extBLOB:
  20082. aftype = otl_var_blob;
  20083. break;
  20084. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20085. case extDate:
  20086. case extTimestamp:
  20087. if (a_override.get_all_mask() & otl_all_date2str) {
  20088. aftype = otl_var_char;
  20089. aelem_size = otl_date_str_size;
  20090. } else
  20091. aftype = otl_var_timestamp;
  20092. break;
  20093. case extTimestamp_TZ:
  20094. if (a_override.get_all_mask() & otl_all_date2str) {
  20095. aftype = otl_var_char;
  20096. aelem_size = otl_date_str_size;
  20097. } else
  20098. aftype = otl_var_tz_timestamp;
  20099. break;
  20100. case extTimestamp_LTZ:
  20101. if (a_override.get_all_mask() & otl_all_date2str) {
  20102. aftype = otl_var_char;
  20103. aelem_size = otl_date_str_size;
  20104. } else
  20105. aftype = otl_var_ltz_timestamp;
  20106. break;
  20107. #else
  20108. case extDate:
  20109. if (a_override.get_all_mask() & otl_all_date2str) {
  20110. aftype = otl_var_char;
  20111. aelem_size = otl_date_str_size;
  20112. } else
  20113. aftype = otl_var_timestamp;
  20114. break;
  20115. #endif
  20116. #if defined(OTL_ORA_SDO_GEOMETRY)
  20117. case otl_unsupported_type:
  20118. if(strcmp(desc.name_type, "SDO_GEOMETRY") == 0) {
  20119. aftype = otl_var_sdo_geometry;
  20120. aelem_size = max_long_size;
  20121. }
  20122. break;
  20123. #endif
  20124. }
  20125. } else {
  20126. aftype = a_override.get_col_type(ndx);
  20127. switch (aftype) {
  20128. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  20129. case otl_var_nchar:
  20130. #endif
  20131. case otl_var_char:
  20132. aelem_size = a_override.get_col_size(ndx);
  20133. break;
  20134. case otl_var_raw:
  20135. aelem_size = a_override.get_col_size(ndx);
  20136. break;
  20137. case otl_var_double:
  20138. aelem_size = sizeof(double);
  20139. break;
  20140. case otl_var_float:
  20141. aelem_size = sizeof(float);
  20142. break;
  20143. case otl_var_int:
  20144. aelem_size = sizeof(int);
  20145. break;
  20146. #if defined(OTL_BIGINT) && defined(OTL_ORA11G_R2)
  20147. case otl_var_bigint:
  20148. aelem_size = sizeof(OTL_BIGINT);
  20149. break;
  20150. #endif
  20151. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  20152. case otl_var_ubigint:
  20153. aelem_size = sizeof(OTL_UBIGINT);
  20154. break;
  20155. #endif
  20156. case otl_var_unsigned_int:
  20157. aelem_size = sizeof(unsigned);
  20158. break;
  20159. case otl_var_short:
  20160. aelem_size = sizeof(short);
  20161. break;
  20162. case otl_var_long_int:
  20163. aelem_size = sizeof(long);
  20164. break;
  20165. default:
  20166. aelem_size = a_override.get_col_size(ndx);
  20167. break;
  20168. }
  20169. }
  20170. desc.otl_var_dbtype = aftype;
  20171. }
  20172. private:
  20173. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  20174. public:
  20175. otl_var(const otl_var &) = delete;
  20176. otl_var &operator=(const otl_var &) = delete;
  20177. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  20178. otl_var(otl_var &&) = delete;
  20179. otl_var &operator=(otl_var &&) = delete;
  20180. #endif
  20181. private:
  20182. #else
  20183. otl_var(const otl_var &)
  20184. : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr),
  20185. ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr),
  20186. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20187. timestamp(nullptr),
  20188. #endif
  20189. cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0),
  20190. real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0),
  20191. cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1),
  20192. otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter),
  20193. lob_stream_mode(false),
  20194. #if defined(OTL_UNICODE)
  20195. unicode_var_len(0),
  20196. #endif
  20197. csid(0),
  20198. #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8)
  20199. csfrm(SQLCS_IMPLICIT),
  20200. #endif
  20201. read_blob_amt(0), total_read_blob_amt(0),
  20202. charz_flag(false), select_stm_flag(false) {
  20203. }
  20204. otl_var &operator=(const otl_var &) { return *this; }
  20205. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  20206. otl_var(otl_var &&)
  20207. : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr),
  20208. ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr),
  20209. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20210. timestamp(nullptr),
  20211. #endif
  20212. cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0),
  20213. real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0),
  20214. cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1),
  20215. otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter),
  20216. lob_stream_mode(false),
  20217. #if defined(OTL_UNICODE)
  20218. unicode_var_len(0),
  20219. #endif
  20220. csid(0),
  20221. #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8)
  20222. csfrm(SQLCS_IMPLICIT),
  20223. #endif
  20224. read_blob_amt(0), total_read_blob_amt(0),
  20225. charz_flag(false), select_stm_flag(false) {
  20226. }
  20227. otl_var &operator=(otl_var &&) { return *this; }
  20228. #endif
  20229. #endif
  20230. };
  20231. class otl_sel;
  20232. class otl_refcur_base_cursor;
  20233. class otl_refcur_stream;
  20234. class otl_ref_cursor;
  20235. class otl_ref_select_stream;
  20236. #if defined(OTL_ORA_SUBSCRIBE)
  20237. class otl_subscriber;
  20238. #endif
  20239. class otl_cur : public otl_cur0 {
  20240. private:
  20241. #if defined(OTL_ORA_SUBSCRIBE)
  20242. friend class otl_subscriber;
  20243. #endif
  20244. friend class otl_sel;
  20245. friend class otl_refcur_base_cursor;
  20246. friend class otl_refcur_stream;
  20247. friend class otl_ref_cursor;
  20248. friend class otl_ref_select_stream;
  20249. OCIStmt *cda; // Statement handle
  20250. OCIError *errhp; // Error handle
  20251. bool extern_cda;
  20252. int status;
  20253. int eof_status;
  20254. otl_conn *db;
  20255. int straight_select;
  20256. int pos_nbr;
  20257. int commit_on_success;
  20258. int last_param_data_token;
  20259. int last_sql_param_data_status;
  20260. int sql_param_data_count;
  20261. bool canceled;
  20262. int direct_exec_flag;
  20263. int parse_only_flag;
  20264. int stm_executed;
  20265. bool batch_error_mode_;
  20266. OCIError *errhndl_;
  20267. OCIError *errhp2_;
  20268. public:
  20269. OTL_NODISCARD int get_number_of_errors_in_batch(int &rc) {
  20270. rc = 1;
  20271. ub4 num_errs = 0;
  20272. sword oci_rc = OCIAttrGet(cda, OCI_HTYPE_STMT, &num_errs, nullptr,
  20273. OCI_ATTR_NUM_DML_ERRORS, errhp);
  20274. if (oci_rc != OCI_SUCCESS) {
  20275. rc = 0;
  20276. return 0;
  20277. } else
  20278. return OTL_SCAST(int, num_errs);
  20279. }
  20280. OTL_NODISCARD int get_error(const int ndx, int &dml_row_offset, otl_exc &exception_struct) {
  20281. sword rc = OCI_SUCCESS;
  20282. dml_row_offset = -1;
  20283. exception_struct.code = 0;
  20284. exception_struct.msg[0] = 0;
  20285. ub4 row_offset = 0;
  20286. sb4 errcode = 0;
  20287. if (errhp2_ == nullptr) {
  20288. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20289. void *temp_errhp2 = &errhp2_;
  20290. #endif
  20291. rc = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()),
  20292. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20293. OTL_RCAST(dvoid **, temp_errhp2),
  20294. #else
  20295. OTL_RCAST(dvoid **, &errhp2_),
  20296. #endif
  20297. OCI_HTYPE_ERROR, 0, nullptr);
  20298. if (rc != OCI_SUCCESS)
  20299. return 0;
  20300. }
  20301. if (errhndl_ == nullptr) {
  20302. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20303. void *temp_errhndl = &errhndl_;
  20304. #endif
  20305. rc = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()),
  20306. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20307. OTL_RCAST(dvoid **, temp_errhndl),
  20308. #else
  20309. OTL_RCAST(dvoid **, &errhndl_),
  20310. #endif
  20311. OCI_HTYPE_ERROR, 0, nullptr);
  20312. if (rc != OCI_SUCCESS)
  20313. return 0;
  20314. }
  20315. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20316. void *temp_errhndl = &errhndl_;
  20317. #endif
  20318. rc = OCIParamGet(errhp, OCI_HTYPE_ERROR, errhp2_,
  20319. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20320. OTL_RCAST(dvoid **, temp_errhndl),
  20321. #else
  20322. OTL_RCAST(dvoid **, &errhndl_),
  20323. #endif
  20324. OTL_SCAST(ub4, ndx));
  20325. if (rc != OCI_SUCCESS)
  20326. return 0;
  20327. rc = OCIAttrGet(errhndl_, OCI_HTYPE_ERROR, &row_offset, nullptr,
  20328. OCI_ATTR_DML_ROW_OFFSET, errhp2_);
  20329. if (rc != OCI_SUCCESS)
  20330. return 0;
  20331. dml_row_offset = OTL_SCAST(int, row_offset);
  20332. rc = OCIErrorGet(OTL_RCAST(dvoid *, errhndl_), OTL_SCAST(ub4, 1), nullptr,
  20333. &errcode, OTL_RCAST(text *, exception_struct.msg),
  20334. OTL_SCAST(ub4, sizeof(exception_struct.msg)),
  20335. OCI_HTYPE_ERROR);
  20336. if (rc != OCI_SUCCESS) {
  20337. exception_struct.code = 0;
  20338. exception_struct.msg[0] = 0;
  20339. return 0;
  20340. }
  20341. exception_struct.code = errcode;
  20342. return 1;
  20343. }
  20344. void set_batch_error_mode(const bool batch_error_mode = false) {
  20345. batch_error_mode_ = batch_error_mode;
  20346. }
  20347. void set_canceled(const bool acanceld) { canceled = acanceld; }
  20348. void reset_last_param_data_token() { last_param_data_token = 0; }
  20349. void reset_last_sql_param_data_status() { last_sql_param_data_status = 0; }
  20350. void reset_sql_param_data_count() { sql_param_data_count = 0; }
  20351. otl_cur()
  20352. : cda(nullptr), errhp(nullptr), extern_cda(false), status(0),
  20353. eof_status(0), db(nullptr), straight_select(1), pos_nbr(0),
  20354. commit_on_success(0), last_param_data_token(0),
  20355. last_sql_param_data_status(0), sql_param_data_count(0), canceled(false),
  20356. direct_exec_flag(0), parse_only_flag(0), stm_executed(0),
  20357. batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {}
  20358. virtual ~otl_cur() {}
  20359. void set_direct_exec(const int flag) { direct_exec_flag = flag; }
  20360. void set_parse_only(const int flag) { parse_only_flag = flag; }
  20361. ub4 rpc(void) {
  20362. sb4 arpc;
  20363. status = OCIAttrGet(OTL_RCAST(dvoid *, cda), OTL_SCAST(ub4, OCI_HTYPE_STMT),
  20364. OTL_RCAST(dvoid *, &arpc), nullptr,
  20365. OTL_SCAST(ub4, OCI_ATTR_ROW_COUNT), errhp);
  20366. if (status)
  20367. return 0;
  20368. return OTL_SCAST(ub4, arpc);
  20369. }
  20370. OTL_NODISCARD int open(otl_conn &connect, otl_var *var = nullptr) {
  20371. db = &connect;
  20372. commit_on_success = db->get_auto_commit();
  20373. if (var != nullptr) {
  20374. extern_cda = true;
  20375. cda = var->get_cda();
  20376. status = OCI_SUCCESS;
  20377. } else {
  20378. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20379. void *temp_cda = &cda;
  20380. #endif
  20381. status = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()),
  20382. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20383. OTL_RCAST(dvoid **, temp_cda),
  20384. #else
  20385. OTL_RCAST(dvoid **, &cda),
  20386. #endif
  20387. OCI_HTYPE_STMT, 0, nullptr);
  20388. if (status)
  20389. return 0;
  20390. }
  20391. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20392. void *temp_errhp = &errhp;
  20393. #endif
  20394. status = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()),
  20395. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20396. OTL_RCAST(dvoid **, temp_errhp),
  20397. #else
  20398. OTL_RCAST(dvoid **, &errhp),
  20399. #endif
  20400. OCI_HTYPE_ERROR, 0, nullptr);
  20401. if (status)
  20402. return 0;
  20403. straight_select = 1;
  20404. pos_nbr = 0;
  20405. return 1;
  20406. }
  20407. OTL_NODISCARD int close(const char
  20408. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  20409. force_handle_free
  20410. #endif
  20411. = 'N') {
  20412. if (!extern_cda) {
  20413. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  20414. if (force_handle_free == 'Y')
  20415. status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT);
  20416. else
  20417. status = OCIStmtRelease(cda, errhp, nullptr, 0, OCI_DEFAULT);
  20418. #else
  20419. status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT);
  20420. #endif
  20421. }
  20422. status = OCIHandleFree(OTL_RCAST(dvoid *, errhp), OCI_HTYPE_ERROR);
  20423. cda = nullptr;
  20424. errhp = nullptr;
  20425. if (errhp2_ != nullptr) {
  20426. status = OCIHandleFree(OTL_RCAST(dvoid *, errhp2_), OCI_HTYPE_ERROR);
  20427. errhp2_ = nullptr;
  20428. }
  20429. if (errhndl_ != nullptr) {
  20430. status = OCIHandleFree(OTL_RCAST(dvoid *, errhndl_), OCI_HTYPE_ERROR);
  20431. errhndl_ = nullptr;
  20432. }
  20433. commit_on_success = 0;
  20434. return 1;
  20435. }
  20436. OTL_NODISCARD int parse(const char *stm_text,
  20437. const int /*external_direct_flag*/) {
  20438. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  20439. if (cda != nullptr) {
  20440. status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT);
  20441. cda = nullptr;
  20442. if (status)
  20443. return 0;
  20444. }
  20445. status = OCIStmtPrepare2(db->get_svchp(), &cda, errhp,
  20446. OTL_RCAST(text *, OTL_CCAST(char *, stm_text)),
  20447. OTL_SCAST(ub4, strlen(stm_text)), nullptr, 0,
  20448. OTL_SCAST(ub4, OCI_NTV_SYNTAX),
  20449. OTL_SCAST(ub4, OCI_DEFAULT));
  20450. #else
  20451. status = OCIStmtPrepare(
  20452. cda, errhp, OTL_RCAST(text *, OTL_CCAST(char *, stm_text)),
  20453. OTL_SCAST(ub4, strlen(stm_text)), OTL_SCAST(ub4, OCI_NTV_SYNTAX),
  20454. OTL_SCAST(ub4, OCI_DEFAULT));
  20455. #endif
  20456. if (status)
  20457. return 0;
  20458. if (direct_exec_flag && parse_only_flag) {
  20459. #if !defined(OCI_PARSE_ONLY)
  20460. status = OCIStmtExecute(db->svchp, cda, errhp, OTL_SCAST(ub4, 1),
  20461. OTL_SCAST(ub4, 0), 0, 0, 0x100);
  20462. #else
  20463. status =
  20464. OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, 0),
  20465. OTL_SCAST(ub4, 0), nullptr, nullptr, OCI_PARSE_ONLY);
  20466. #endif
  20467. if (status)
  20468. return 0;
  20469. else
  20470. return 1;
  20471. } else if (direct_exec_flag && !parse_only_flag) {
  20472. ub4 mode;
  20473. if (commit_on_success)
  20474. mode = OCI_COMMIT_ON_SUCCESS;
  20475. else
  20476. mode = OCI_DEFAULT;
  20477. status = OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, 1),
  20478. OTL_SCAST(ub4, 0), nullptr, nullptr, mode);
  20479. stm_executed = 1;
  20480. if (status)
  20481. return 0;
  20482. else
  20483. return 1;
  20484. }
  20485. return 1;
  20486. }
  20487. OTL_NODISCARD int exec(const int iters, const int rowoff,
  20488. const otl_sql_exec_from_enum /*otl_sql_exec_from_class*/) {
  20489. if (parse_only_flag) {
  20490. parse_only_flag = 0;
  20491. return 1;
  20492. } else if (!stm_executed) {
  20493. ub4 mode;
  20494. if (commit_on_success)
  20495. mode = OCI_COMMIT_ON_SUCCESS;
  20496. else
  20497. mode = OCI_DEFAULT;
  20498. if (batch_error_mode_)
  20499. mode |= OCI_BATCH_ERRORS;
  20500. status =
  20501. OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, iters),
  20502. OTL_SCAST(ub4, rowoff), nullptr, nullptr, mode);
  20503. stm_executed = 0;
  20504. if (status != OCI_SUCCESS)
  20505. return 0;
  20506. return 1;
  20507. }
  20508. return 1;
  20509. }
  20510. OTL_NODISCARD long get_rpc() OTL_NO_THROW {
  20511. return OTL_SCAST(long,rpc());
  20512. }
  20513. OTL_NODISCARD int fetch(const otl_stream_buffer_size_type iters, int &eof_data) {
  20514. eof_data = 0;
  20515. #if defined(OTL_ORA9I) || defined(OTL_ORA10G) || defined(OTL_ORA10G_R2) || \
  20516. defined(OTL_ORA11G) || defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  20517. status = OCIStmtFetch2(
  20518. cda, errhp, OTL_SCAST(ub4, iters), OTL_SCAST(ub4, OCI_FETCH_NEXT),
  20519. OTL_SCAST(sb4, OCI_FETCH_NEXT), OTL_SCAST(ub4, OCI_DEFAULT));
  20520. #else
  20521. status = OCIStmtFetch(cda, errhp, OTL_SCAST(ub4, iters),
  20522. OTL_SCAST(ub4, OCI_FETCH_NEXT),
  20523. OTL_SCAST(ub4, OCI_DEFAULT));
  20524. #endif
  20525. eof_status = status;
  20526. if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO &&
  20527. status != OCI_NO_DATA)
  20528. return 0;
  20529. if (status == OCI_NO_DATA) {
  20530. eof_data = 1;
  20531. return 1;
  20532. }
  20533. return 1;
  20534. }
  20535. OTL_NODISCARD int tmpl_ftype2ora_ftype(const int ftype) {
  20536. switch (ftype) {
  20537. case otl_var_char:
  20538. return extCChar;
  20539. #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \
  20540. defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES)
  20541. case otl_var_double:
  20542. return extBDouble;
  20543. case otl_var_bdouble:
  20544. return extBDouble;
  20545. case otl_var_float:
  20546. return extBFloat;
  20547. case otl_var_bfloat:
  20548. return extBFloat;
  20549. #else
  20550. case otl_var_double:
  20551. return extFloat;
  20552. case otl_var_float:
  20553. return extFloat;
  20554. #endif
  20555. case otl_var_int:
  20556. return extInt;
  20557. case otl_var_unsigned_int:
  20558. return extUInt;
  20559. case otl_var_short:
  20560. return extInt;
  20561. case otl_var_long_int:
  20562. return extInt;
  20563. #if defined(OTL_BIGINT) && \
  20564. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  20565. !defined(OTL_BIGINT_TO_STR))
  20566. case otl_var_bigint:
  20567. return extInt;
  20568. #endif
  20569. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  20570. case otl_var_ubigint:
  20571. return extUInt;
  20572. #endif
  20573. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20574. case otl_var_timestamp:
  20575. return extTimestamp;
  20576. case otl_var_tz_timestamp:
  20577. return extTimestamp_TZ;
  20578. case otl_var_ltz_timestamp:
  20579. return extTimestamp_LTZ;
  20580. #else
  20581. case otl_var_timestamp:
  20582. return extDate;
  20583. #endif
  20584. case otl_var_varchar_long:
  20585. return extLongVarChar;
  20586. case otl_var_raw_long:
  20587. return extLongVarRaw;
  20588. case otl_var_raw:
  20589. return extRaw;
  20590. case otl_var_clob:
  20591. return SQLT_CLOB;
  20592. case otl_var_blob:
  20593. return SQLT_BLOB;
  20594. #if defined(OTL_ORA_SDO_GEOMETRY)
  20595. case otl_var_sdo_geometry:
  20596. return SQLT_NTY;
  20597. #endif
  20598. default:
  20599. return 0;
  20600. }
  20601. }
  20602. OTL_NODISCARD int bind(const char *name, otl_var &v, const int elem_size, const int ftype,
  20603. const int /*param_type*/, const int /*name_pos*/,
  20604. const int /*connection_type*/, const int apl_tab_flag) {
  20605. OCIBind *bindpp;
  20606. int db_ftype = 0;
  20607. #if defined(OTL_ORA_SDO_GEOMETRY)
  20608. if(ftype == otl_var_sdo_geometry){
  20609. if(v.sdoobj && v.array_size > 0 && !v.sdoobj[0]){
  20610. v.needFree = true;
  20611. for(int i = 0;i<v.array_size;i++){
  20612. #if defined(__clang__)
  20613. #pragma clang diagnostic push
  20614. #pragma clang diagnostic ignored "-Wold-style-cast"
  20615. #endif
  20616. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  20617. #pragma GCC diagnostic push
  20618. #pragma GCC diagnostic ignored "-Wold-style-cast"
  20619. #endif
  20620. status = OCIObjectNew(
  20621. db->get_envhp(), errhp, db->get_svchp(),
  20622. OTL_SCAST(ub2, OCI_TYPECODE_OBJECT),
  20623. v.oraOCIType,
  20624. nullptr,
  20625. OTL_SCAST(ub2, OCI_DURATION_SESSION), 1,
  20626. OTL_RCAST(dvoid **, &v.sdoobj[i]));
  20627. #if defined(__clang__)
  20628. #pragma clang diagnostic pop
  20629. #endif
  20630. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  20631. #pragma GCC diagnostic pop
  20632. #endif
  20633. if(status)return 0;
  20634. status = OCIObjectGetInd(db->get_envhp(),
  20635. errhp,
  20636. OTL_RCAST(dvoid *, v.sdoobj[i]),
  20637. OTL_RCAST(dvoid **, &v.sdoind[i]));
  20638. if(status)return 0;
  20639. }
  20640. }
  20641. status = OCIBindByName(
  20642. cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)),
  20643. OTL_SCAST(sb4, strlen(name)), nullptr,
  20644. OTL_SCAST(sb4, 0),
  20645. OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)),
  20646. OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr,
  20647. OTL_SCAST(ub4, 0), nullptr, OTL_SCAST(ub4, OCI_DEFAULT));
  20648. if(status)return 0;
  20649. status = OCIBindObject(bindpp, errhp, v.oraOCIType,
  20650. OTL_RCAST(dvoid **, v.sdoobj), nullptr,
  20651. OTL_RCAST(dvoid **, v.sdoind), nullptr);
  20652. if(status)return 0;
  20653. }else
  20654. #endif
  20655. if (ftype == otl_var_refcur) {
  20656. status = OCIBindByName(
  20657. cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)),
  20658. OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.get_cda_ptr()), 0,
  20659. SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr,
  20660. OTL_SCAST(ub4, OCI_DEFAULT));
  20661. } else if (ftype != otl_var_clob && ftype != otl_var_blob) {
  20662. int var_elem_size;
  20663. #if defined(OTL_UNICODE)
  20664. if (ftype == otl_var_char) {
  20665. var_elem_size = elem_size * OTL_SCAST(int, sizeof(OTL_WCHAR));
  20666. } else if (ftype == otl_var_varchar_long)
  20667. var_elem_size = elem_size;
  20668. else
  20669. var_elem_size = elem_size;
  20670. #else
  20671. if (ftype == otl_var_varchar_long)
  20672. var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4));
  20673. else
  20674. var_elem_size = elem_size;
  20675. #endif
  20676. db_ftype = tmpl_ftype2ora_ftype(ftype);
  20677. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  20678. if (ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp ||
  20679. ftype == otl_var_ltz_timestamp) {
  20680. if (!apl_tab_flag)
  20681. var_elem_size = sizeof(OCIDateTime *);
  20682. else if (db_ftype == extTimestamp)
  20683. db_ftype = extDate;
  20684. }
  20685. #endif
  20686. #if defined(OTL_UNICODE)
  20687. if (ftype == otl_var_char)
  20688. db_ftype = SQLT_VCS;
  20689. #endif
  20690. if (apl_tab_flag) {
  20691. if (ftype == otl_var_float || ftype == otl_var_double)
  20692. db_ftype = extFloat;
  20693. status = OCIBindByName(
  20694. cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)),
  20695. OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v),
  20696. OTL_SCAST(sb4,
  20697. ftype == otl_var_raw
  20698. ? OTL_SCAST(size_t, var_elem_size) + sizeof(short)
  20699. : OTL_SCAST(size_t, var_elem_size)),
  20700. OTL_SCAST(ub2, v.charz_flag ? extCharZ : db_ftype),
  20701. OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr,
  20702. OTL_SCAST(ub4, v.max_tab_len), OTL_RCAST(ub4 *, &v.cur_tab_len),
  20703. OTL_SCAST(ub4, OCI_DEFAULT));
  20704. } else {
  20705. status = OCIBindByName(
  20706. cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)),
  20707. OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v),
  20708. OTL_SCAST(sb4,
  20709. ftype == otl_var_raw
  20710. ? OTL_SCAST(size_t, var_elem_size) + sizeof(short)
  20711. : OTL_SCAST(size_t, var_elem_size)),
  20712. OTL_SCAST(ub2, db_ftype), OTL_RCAST(dvoid *, v.p_ind), nullptr,
  20713. nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT));
  20714. }
  20715. if (status)return 0;
  20716. #if defined(OTL_UNICODE)
  20717. if (ftype == otl_var_char || ftype == otl_var_varchar_long) {
  20718. if (ftype != otl_var_varchar_long) {
  20719. if (v.nls_flag)
  20720. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20721. else
  20722. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20723. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0,
  20724. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20725. if (status)
  20726. return 0;
  20727. }
  20728. v.csid = OTL_UNICODE_ID;
  20729. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csid, 0,
  20730. OCI_ATTR_CHARSET_ID, errhp);
  20731. if (status)return 0;
  20732. if (ftype == otl_var_varchar_long)
  20733. v.unicode_var_len = elem_size - OTL_SCAST(int, sizeof(sb4));
  20734. else {
  20735. #if defined(OTL_ORA_MAX_UNICODE_VARCHAR_SIZE)
  20736. if (var_elem_size > OTL_ORA_MAX_UNICODE_VARCHAR_SIZE)
  20737. v.unicode_var_len = OTL_ORA_MAX_UNICODE_VARCHAR_SIZE;
  20738. else
  20739. v.unicode_var_len = var_elem_size;
  20740. #else
  20741. v.unicode_var_len = var_elem_size;
  20742. #endif
  20743. }
  20744. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.unicode_var_len, 0,
  20745. OCI_ATTR_MAXDATA_SIZE, errhp);
  20746. if (status)return 0;
  20747. }
  20748. #endif
  20749. #if defined(OTL_ORA_UTF8)
  20750. if (ftype == otl_var_char) {
  20751. if (v.nls_flag)
  20752. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20753. else
  20754. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20755. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0,
  20756. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20757. if (status)return 0;
  20758. }
  20759. #endif
  20760. return 1;
  20761. } else {
  20762. status = OCIBindByName(
  20763. cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)),
  20764. OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v),
  20765. OTL_SCAST(sb4, -1), OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)),
  20766. OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr, 0, nullptr,
  20767. OTL_SCAST(ub4, OCI_DEFAULT));
  20768. if (status)
  20769. return 0;
  20770. #if defined(OTL_UNICODE)
  20771. if (ftype == otl_var_clob) {
  20772. v.csid = OTL_UNICODE_ID;
  20773. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csid, 0,
  20774. OCI_ATTR_CHARSET_ID, errhp);
  20775. if (status)
  20776. return 0;
  20777. if (v.nls_flag)
  20778. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20779. else
  20780. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20781. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0,
  20782. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20783. if (status)
  20784. return 0;
  20785. }
  20786. #endif
  20787. #if defined(OTL_ORA_UTF8)
  20788. if (ftype == otl_var_clob) {
  20789. if (v.nls_flag)
  20790. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20791. else
  20792. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20793. status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0,
  20794. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20795. if (status)
  20796. return 0;
  20797. }
  20798. #endif
  20799. return 1;
  20800. }
  20801. if (status)
  20802. return 0;
  20803. return 1;
  20804. }
  20805. OTL_NODISCARD int bind(const int column_num, otl_var &v, const int elem_size,
  20806. const int ftype, const int /*param_type*/) {
  20807. OCIDefine *defnp;
  20808. int db_ftype = 0;
  20809. #if defined(OTL_ORA_SDO_GEOMETRY)
  20810. if(ftype == otl_var_sdo_geometry){
  20811. v.needFree = false;
  20812. status = OCIDefineByPos(cda, &defnp, errhp, OTL_SCAST(ub4, column_num),
  20813. OTL_RCAST(dvoid *, v.sdoobj), OTL_SCAST(sb4, 0),
  20814. OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)),
  20815. OTL_RCAST(dvoid *, v.p_ind),
  20816. OTL_RCAST(ub2 *, v.p_rlen),
  20817. OTL_RCAST(ub2 *, v.p_rcode), OTL_SCAST(ub4, OCI_DEFAULT));
  20818. if(status)
  20819. return 0;
  20820. status = OCIDefineObject(defnp,
  20821. errhp,
  20822. v.oraOCIType,
  20823. OTL_RCAST(dvoid **, v.sdoobj),
  20824. nullptr,
  20825. OTL_RCAST(dvoid **, v.sdoind),
  20826. nullptr
  20827. );
  20828. if(status)
  20829. return 0;
  20830. else
  20831. return 1;
  20832. }else
  20833. #endif
  20834. if (ftype != otl_var_clob && ftype != otl_var_blob) {
  20835. int var_elem_size;
  20836. #if defined(OTL_UNICODE)
  20837. if (ftype == otl_var_char)
  20838. var_elem_size = elem_size * OTL_SCAST(int, sizeof(OTL_WCHAR));
  20839. else if (ftype == otl_var_varchar_long)
  20840. var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4));
  20841. else
  20842. var_elem_size = elem_size;
  20843. #elif defined(OTL_ORA_UTF8)
  20844. if (ftype == otl_var_char && v.select_stm_flag)
  20845. var_elem_size =
  20846. elem_size * OTL_UTF8_BYTES_PER_CHAR; // 3 bytes per UTF8 char
  20847. else if (ftype == otl_var_varchar_long)
  20848. var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4));
  20849. else
  20850. var_elem_size = elem_size;
  20851. #else
  20852. if (ftype == otl_var_varchar_long)
  20853. var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4));
  20854. else
  20855. var_elem_size = elem_size;
  20856. #endif
  20857. db_ftype = tmpl_ftype2ora_ftype(ftype);
  20858. #if defined(OTL_UNICODE)
  20859. if (ftype == otl_var_char)
  20860. db_ftype = SQLT_VCS;
  20861. #endif
  20862. status = OCIDefineByPos(
  20863. cda, &defnp, errhp, OTL_SCAST(ub4, column_num),
  20864. OTL_RCAST(dvoid *, v.p_v),
  20865. OTL_SCAST(sb4, ftype == otl_var_raw
  20866. ? OTL_SCAST(size_t, var_elem_size) + sizeof(short)
  20867. : OTL_SCAST(size_t, var_elem_size)),
  20868. OTL_SCAST(ub2, db_ftype), OTL_RCAST(dvoid *, v.p_ind),
  20869. OTL_RCAST(ub2 *, v.p_rlen), OTL_RCAST(ub2 *, v.p_rcode), OCI_DEFAULT);
  20870. if (status)
  20871. return 0;
  20872. #if defined(OTL_ORA_UTF8)
  20873. if (ftype == otl_var_char || ftype == otl_var_varchar_long) {
  20874. if (v.nls_flag)
  20875. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20876. else
  20877. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20878. status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE,
  20879. OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0),
  20880. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20881. if (status)
  20882. return 0;
  20883. }
  20884. #endif
  20885. #if defined(OTL_UNICODE)
  20886. if (ftype == otl_var_char || ftype == otl_var_varchar_long) {
  20887. if (v.nls_flag)
  20888. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20889. else
  20890. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20891. status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE,
  20892. OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0),
  20893. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20894. if (status)
  20895. return 0;
  20896. v.csid = OTL_UNICODE_ID;
  20897. status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, &v.csid, 0,
  20898. OCI_ATTR_CHARSET_ID, errhp);
  20899. if (status)
  20900. return 0;
  20901. }
  20902. #endif
  20903. return 1;
  20904. } else {
  20905. status = OCIDefineByPos(cda, &defnp, errhp, OTL_SCAST(ub4, column_num),
  20906. OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, -1),
  20907. OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)),
  20908. OTL_RCAST(dvoid *, v.p_ind),
  20909. OTL_RCAST(ub2 *, v.p_rlen),
  20910. OTL_RCAST(ub2 *, v.p_rcode), OCI_DEFAULT);
  20911. if (status)
  20912. return 0;
  20913. #if defined(OTL_UNICODE)
  20914. if (ftype == otl_var_char || ftype == otl_var_varchar_long) {
  20915. v.csid = OTL_UNICODE_ID;
  20916. status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, &v.csid, 0,
  20917. OCI_ATTR_CHARSET_ID, errhp);
  20918. if (status)
  20919. return 0;
  20920. }
  20921. #endif
  20922. #if defined(OTL_ORA_UTF8)
  20923. if (ftype == otl_var_clob) {
  20924. if (v.nls_flag)
  20925. v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR);
  20926. else
  20927. v.csfrm = OTL_SCAST(ub1, db->char_set_);
  20928. status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE,
  20929. OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0),
  20930. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp);
  20931. if (status)
  20932. return 0;
  20933. }
  20934. #endif
  20935. return 1;
  20936. }
  20937. }
  20938. void set_select_type(const int select_type) { straight_select = select_type; }
  20939. OTL_NODISCARD int describe_column(otl_column_desc &col, const int column_num,
  20940. int &eof_desc) {
  20941. OCIParam *pard;
  20942. ub2 dtype;
  20943. ub2 dbsize;
  20944. sb2 prec;
  20945. #if defined(OTL_ORA8_8I_DESC_COLUMN_SCALE)
  20946. ub1 scale;
  20947. #else
  20948. sb2 scale;
  20949. #endif
  20950. ub1 nullok;
  20951. text *col_name;
  20952. ub4 col_name_len;
  20953. ub4 pos_num;
  20954. #ifdef OTL_ORA_SDO_GEOMETRY
  20955. text *col_type_name;
  20956. ub4 col_type_name_len;
  20957. #endif // OTL_ORA_SDO_GEOMETRY
  20958. eof_desc = 0;
  20959. if (straight_select && pos_nbr == 0) {
  20960. status = OCIStmtExecute(db->get_svchp(), cda, errhp, 0, 0, nullptr,
  20961. nullptr, OCI_DESCRIBE_ONLY);
  20962. if (status != OCI_SUCCESS)
  20963. return 0;
  20964. status = OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub4 *, &pos_num),
  20965. nullptr, OTL_SCAST(ub4, OCI_ATTR_PARAM_COUNT), errhp);
  20966. if (status != OCI_SUCCESS)
  20967. return 0;
  20968. pos_nbr = OTL_SCAST(int, pos_num);
  20969. }
  20970. if (!straight_select && pos_nbr == 0) {
  20971. status = OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub4 *, &pos_num),
  20972. nullptr, OTL_SCAST(ub4, OCI_ATTR_PARAM_COUNT), errhp);
  20973. if (status != OCI_SUCCESS)
  20974. return 0;
  20975. pos_nbr = OTL_SCAST(int, pos_num);
  20976. }
  20977. if (column_num < 1 || column_num > pos_nbr) {
  20978. eof_desc = 1;
  20979. return 0;
  20980. }
  20981. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20982. void *temp_pard = &pard;
  20983. #endif
  20984. status = OCIParamGet(cda, OCI_HTYPE_STMT, errhp,
  20985. #if defined(__GNUC__) && (__GNUC__ >= 4)
  20986. OTL_RCAST(void **, temp_pard),
  20987. #else
  20988. OTL_RCAST(void **, &pard),
  20989. #endif
  20990. OTL_SCAST(ub4, column_num));
  20991. if (status != OCI_SUCCESS && status != OCI_NO_DATA)
  20992. return 0;
  20993. if (status == OCI_NO_DATA) {
  20994. eof_desc = 1;
  20995. return 1;
  20996. }
  20997. status = OCIAttrGet(
  20998. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  20999. OTL_RCAST(dvoid *, &dtype), nullptr, OTL_SCAST(ub4, OCI_ATTR_DATA_TYPE),
  21000. OTL_RCAST(OCIError *, errhp));
  21001. if (status != OCI_SUCCESS)
  21002. return 0;
  21003. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  21004. #if !defined(OTL_ORA8I)
  21005. ub1 charset_form;
  21006. status = OCIAttrGet(
  21007. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21008. OTL_RCAST(dvoid *, &charset_form), nullptr,
  21009. OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), OTL_RCAST(OCIError *, errhp));
  21010. if (status != OCI_SUCCESS)
  21011. return 0;
  21012. col.charset_form = OTL_SCAST(int, charset_form);
  21013. ub2 char_size;
  21014. status = OCIAttrGet(
  21015. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21016. OTL_RCAST(dvoid *, &char_size), nullptr,
  21017. OTL_SCAST(ub4, OCI_ATTR_CHAR_SIZE), OTL_RCAST(OCIError *, errhp));
  21018. if (status != OCI_SUCCESS)
  21019. return 0;
  21020. col.char_size = OTL_SCAST(int, char_size);
  21021. #else
  21022. col.char_size = 0;
  21023. #endif
  21024. #endif
  21025. col.dbtype = dtype;
  21026. #if defined(__GNUC__) && (__GNUC__ >= 4)
  21027. void *temp_col_name = &col_name;
  21028. #endif
  21029. status =
  21030. OCIAttrGet(OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21031. #if defined(__GNUC__) && (__GNUC__ >= 4)
  21032. OTL_RCAST(dvoid **, temp_col_name),
  21033. #else
  21034. OTL_RCAST(dvoid **, &col_name),
  21035. #endif
  21036. OTL_RCAST(ub4 *, &col_name_len),
  21037. OTL_SCAST(ub4, OCI_ATTR_NAME), OTL_RCAST(OCIError *, errhp));
  21038. if (status != OCI_SUCCESS)
  21039. return 0;
  21040. col.set_name(OTL_RCAST(char *, col_name), OTL_SCAST(int, col_name_len));
  21041. status = OCIAttrGet(
  21042. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21043. OTL_RCAST(dvoid *, &dbsize),
  21044. #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT)
  21045. nullptr,
  21046. #else
  21047. OTL_RCAST(ub4 *, 0),
  21048. #endif
  21049. OTL_SCAST(ub4, OCI_ATTR_DATA_SIZE), OTL_RCAST(OCIError *, errhp));
  21050. if (status != OCI_SUCCESS)
  21051. return 0;
  21052. col.dbsize = dbsize;
  21053. status = OCIAttrGet(
  21054. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21055. OTL_RCAST(dvoid *, &prec), nullptr, OTL_SCAST(ub4, OCI_ATTR_PRECISION),
  21056. OTL_RCAST(OCIError *, errhp));
  21057. if (status != OCI_SUCCESS)
  21058. return 0;
  21059. col.prec = prec;
  21060. status = OCIAttrGet(
  21061. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21062. OTL_RCAST(dvoid *, &scale), nullptr, OTL_SCAST(ub4, OCI_ATTR_SCALE),
  21063. OTL_RCAST(OCIError *, errhp));
  21064. if (status != OCI_SUCCESS)
  21065. return 0;
  21066. col.scale = scale;
  21067. status = OCIAttrGet(
  21068. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21069. OTL_RCAST(dvoid *, &nullok), nullptr, OTL_SCAST(ub4, OCI_ATTR_IS_NULL),
  21070. OTL_RCAST(OCIError *, errhp));
  21071. if (status != OCI_SUCCESS)
  21072. return 0;
  21073. col.nullok = nullok;
  21074. #ifdef OTL_ORA_SDO_GEOMETRY
  21075. #if defined(__GNUC__) && (__GNUC__ >= 4)
  21076. void *temp_col_type_name = &col_type_name;
  21077. #endif
  21078. if(col.dbtype == SQLT_NTY){
  21079. status=OCIAttrGet(OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21080. #if defined(__GNUC__) && (__GNUC__ >= 4)
  21081. OTL_RCAST(dvoid **, temp_col_type_name),
  21082. #else
  21083. OTL_RCAST(dvoid **, &col_type_name),
  21084. #endif
  21085. OTL_RCAST(ub4 *, &col_type_name_len),
  21086. OTL_SCAST(ub4, OCI_ATTR_TYPE_NAME), OTL_RCAST(OCIError *, errhp));
  21087. if(status != OCI_SUCCESS)
  21088. return 0;
  21089. col.set_name_type(OTL_RCAST(char *, col_type_name), OTL_SCAST(int, col_type_name_len));
  21090. OCIRef *typeRef = nullptr;
  21091. void* temp_ptr=OTL_RCAST(void*, &typeRef);
  21092. status = OCIAttrGet(
  21093. OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM),
  21094. temp_ptr, nullptr, OTL_SCAST(ub4, OCI_ATTR_REF_TDO),
  21095. OTL_RCAST(OCIError *, errhp));
  21096. if(status != OCI_SUCCESS)
  21097. return 0;
  21098. #if defined(__clang__)
  21099. #pragma clang diagnostic push
  21100. #pragma clang diagnostic ignored "-Wold-style-cast"
  21101. #endif
  21102. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  21103. #pragma GCC diagnostic push
  21104. #pragma GCC diagnostic ignored "-Wold-style-cast"
  21105. #endif
  21106. void* temp_ptr3=OTL_RCAST(void*,&col.colOCIType);
  21107. status = OCIObjectPin(db->get_envhp(),
  21108. db->get_errhp(),
  21109. typeRef,
  21110. nullptr,
  21111. OCI_PIN_ANY,
  21112. OCI_DURATION_SESSION,
  21113. OCI_LOCK_NONE,
  21114. (void**)temp_ptr3);
  21115. #if defined(__clang__)
  21116. #pragma clang diagnostic pop
  21117. #endif
  21118. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407)
  21119. #pragma GCC diagnostic pop
  21120. #endif
  21121. if(status != OCI_SUCCESS)
  21122. return 0;
  21123. }
  21124. #endif
  21125. return 1;
  21126. }
  21127. void error(otl_exc &exception_struct) {
  21128. sb4 errcode;
  21129. size_t len;
  21130. OTL_STRCPY_S(OTL_RCAST(char *, exception_struct.msg),
  21131. sizeof(exception_struct.msg), "123456789");
  21132. OCIErrorGet(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, 1), nullptr, &errcode,
  21133. OTL_RCAST(text *, exception_struct.msg),
  21134. OTL_SCAST(ub4, sizeof(exception_struct.msg)), OCI_HTYPE_ERROR);
  21135. exception_struct.code = errcode;
  21136. len = strlen(OTL_RCAST(char *, exception_struct.msg));
  21137. exception_struct.msg[len] = 0;
  21138. #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET)
  21139. ub2 error_offset;
  21140. if (OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub2 *, &error_offset), 0,
  21141. OTL_SCAST(ub4, OCI_ATTR_PARSE_ERROR_OFFSET),
  21142. errhp) == OCI_SUCCESS)
  21143. exception_struct.error_offset = OTL_SCAST(int, error_offset);
  21144. #endif
  21145. }
  21146. private:
  21147. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  21148. public:
  21149. otl_cur(const otl_cur &) = delete;
  21150. otl_cur &operator=(const otl_cur &) = delete;
  21151. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21152. otl_cur(otl_cur &&) = delete;
  21153. otl_cur &operator=(otl_cur &&) = delete;
  21154. #endif
  21155. private:
  21156. #else
  21157. otl_cur(const otl_cur &)
  21158. : otl_cur0(), cda(nullptr), errhp(nullptr), extern_cda(false), status(0),
  21159. eof_status(0), db(nullptr), straight_select(1), pos_nbr(0),
  21160. commit_on_success(0), last_param_data_token(0),
  21161. last_sql_param_data_status(0), sql_param_data_count(0), canceled(false),
  21162. direct_exec_flag(0), parse_only_flag(0), stm_executed(0),
  21163. batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {}
  21164. otl_cur &operator=(const otl_cur &) { return *this; }
  21165. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21166. otl_cur(otl_cur &&)
  21167. : otl_cur0(), cda(nullptr), errhp(nullptr), extern_cda(false), status(0),
  21168. eof_status(0), db(nullptr), straight_select(1), pos_nbr(0),
  21169. commit_on_success(0), last_param_data_token(0),
  21170. last_sql_param_data_status(0), sql_param_data_count(0), canceled(false),
  21171. direct_exec_flag(0), parse_only_flag(0), stm_executed(0),
  21172. batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {}
  21173. otl_cur &operator=(otl_cur &&) { return *this; }
  21174. #endif
  21175. #endif
  21176. };
  21177. class otl_ref_cursor;
  21178. class otl_sel {
  21179. private:
  21180. friend class otl_ref_cursor;
  21181. int implicit_cursor;
  21182. public:
  21183. OTL_NODISCARD int get_implicit_cursor() const {
  21184. return implicit_cursor;
  21185. }
  21186. void set_arr_size(const int input_arr_size, int &out_array_size,
  21187. int &out_prefetch_array_size) {
  21188. out_array_size = input_arr_size;
  21189. out_prefetch_array_size = 0;
  21190. }
  21191. void set_prefetch_size(const int /*aprefetch_array_size*/) {}
  21192. OTL_NODISCARD int close_select(otl_cur & /*cur*/) {
  21193. return 1;
  21194. }
  21195. otl_sel() : implicit_cursor(0) {}
  21196. virtual ~otl_sel() {}
  21197. void set_select_type(const int /*atype*/) { implicit_cursor = 0; }
  21198. void init(const int /*array_size*/) {}
  21199. OTL_NODISCARD int first(otl_cur &cur, int &cur_row, int &cur_size, int &row_count,
  21200. int &eof_data, const int array_size) {
  21201. int rc;
  21202. eof_data = 0;
  21203. cur_row = -1;
  21204. cur.commit_on_success = 0;
  21205. rc = cur.exec(0, 0, otl_sql_exec_from_select_cursor_class);
  21206. if (rc == 0)
  21207. return 0;
  21208. rc =
  21209. cur.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data);
  21210. if (rc == 0)
  21211. return 0;
  21212. row_count = OTL_SCAST(int, cur.rpc());
  21213. cur_size = row_count;
  21214. if (cur_size != 0)
  21215. cur_row = 0;
  21216. return 1;
  21217. }
  21218. OTL_NODISCARD int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count,
  21219. int &eof_data, const int array_size) {
  21220. int rc;
  21221. if (cur_row < cur_size - 1) {
  21222. ++cur_row;
  21223. return 1;
  21224. } else {
  21225. if (eof_data) {
  21226. cur_row = -1;
  21227. cur_size = 0;
  21228. return 1;
  21229. }
  21230. cur.commit_on_success = 0;
  21231. rc = cur.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size),
  21232. eof_data);
  21233. if (rc == 0)
  21234. return 0;
  21235. int temp_rpc = OTL_SCAST(int, cur.rpc());
  21236. cur_size = temp_rpc - row_count;
  21237. row_count = temp_rpc;
  21238. if (cur_size != 0)
  21239. cur_row = 0;
  21240. return 1;
  21241. }
  21242. }
  21243. private:
  21244. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  21245. public:
  21246. otl_sel(const otl_sel &) = delete;
  21247. otl_sel &operator=(const otl_sel &) = delete;
  21248. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21249. otl_sel(otl_sel &&) = delete;
  21250. otl_sel &operator=(otl_sel &&) = delete;
  21251. #endif
  21252. private:
  21253. #else
  21254. otl_sel(const otl_sel &) : implicit_cursor(0) {}
  21255. otl_sel &operator=(const otl_sel &) { return *this; }
  21256. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21257. otl_sel(otl_sel &&) : implicit_cursor(0) {}
  21258. otl_sel &operator=(otl_sel &&) { return *this; }
  21259. #endif
  21260. #endif
  21261. };
  21262. typedef otl_tmpl_connect<otl_exc, otl_conn, otl_cur> otl_ora8_connect;
  21263. typedef otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> otl_cursor;
  21264. template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
  21265. OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
  21266. class otl_tmpl_lob_stream : public otl_lob_stream_generic {
  21267. public:
  21268. typedef otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
  21269. otl_exception;
  21270. typedef otl_tmpl_variable<TVariableStruct> *p_bind_var;
  21271. typedef otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct> *
  21272. p_connect;
  21273. typedef otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct,
  21274. TVariableStruct> *p_cursor;
  21275. private:
  21276. p_bind_var bind_var;
  21277. p_connect connect;
  21278. p_cursor cursor;
  21279. otl_long_string *temp_buf;
  21280. char *temp_char_buf;
  21281. public:
  21282. void setInitialReadOffset(const int initial_offset) {
  21283. if (lob_len == 0)
  21284. lob_len = len();
  21285. if ((initial_offset - 1) >= lob_len) {
  21286. eof_flag = 1;
  21287. return;
  21288. }
  21289. offset = initial_offset + 1;
  21290. if (bind_var)
  21291. bind_var->get_var_struct().set_total_read_blob_amt(initial_offset + 1);
  21292. }
  21293. void init(void *avar, void *aconnect, void *acursor, int andx, int amode,
  21294. const int alob_is_null = 0) OTL_NO_THROW {
  21295. connect = OTL_RCAST(p_connect, aconnect);
  21296. bind_var = OTL_RCAST(p_bind_var, avar);
  21297. cursor = OTL_RCAST(p_cursor, acursor);
  21298. mode = amode;
  21299. retcode = 0;
  21300. lob_is_null = alob_is_null;
  21301. ndx = andx;
  21302. offset = 0;
  21303. if (amode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode))
  21304. lob_len = 2147483647;
  21305. else
  21306. lob_len = 0;
  21307. eof_flag = 0;
  21308. in_destructor = 0;
  21309. if (bind_var)
  21310. bind_var->get_var_struct().set_lob_stream_flag();
  21311. }
  21312. void set_len(const int new_len = 0) OTL_NO_THROW { lob_len = new_len; }
  21313. otl_tmpl_lob_stream() OTL_NO_THROW : otl_lob_stream_generic(true),
  21314. bind_var(nullptr),
  21315. connect(nullptr),
  21316. cursor(nullptr),
  21317. temp_buf(nullptr),
  21318. temp_char_buf(nullptr) {
  21319. init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode));
  21320. }
  21321. virtual ~otl_tmpl_lob_stream()
  21322. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  21323. OTL_THROWS_OTL_EXCEPTION
  21324. #else
  21325. OTL_NO_THROW
  21326. #endif
  21327. {
  21328. in_destructor = 1;
  21329. if (temp_buf) {
  21330. delete temp_buf;
  21331. temp_buf = nullptr;
  21332. }
  21333. if (temp_char_buf) {
  21334. delete[] temp_char_buf;
  21335. temp_char_buf = nullptr;
  21336. }
  21337. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  21338. try {
  21339. close();
  21340. }
  21341. catch (OTL_CONST_EXCEPTION otl_exception &) {
  21342. }
  21343. #else
  21344. close();
  21345. #endif
  21346. }
  21347. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  21348. otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s)
  21349. OTL_THROWS_OTL_EXCEPTION {
  21350. otl_long_string temp_s(s.data(), OTL_SCAST(int, s.length()),
  21351. OTL_SCAST(int, s.length()));
  21352. (*this) << temp_s;
  21353. return *this;
  21354. }
  21355. #endif
  21356. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  21357. defined(OTL_USER_DEFINED_STRING_CLASS_ON)) && \
  21358. !defined(OTL_UNICODE)
  21359. otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s)
  21360. OTL_THROWS_OTL_EXCEPTION {
  21361. otl_long_string temp_s(s.c_str(), OTL_SCAST(int, s.length()),
  21362. OTL_SCAST(int, s.length()));
  21363. (*this) << temp_s;
  21364. return *this;
  21365. }
  21366. void setStringBuffer(const int chunk_size) {
  21367. delete[] temp_char_buf;
  21368. temp_char_buf = nullptr;
  21369. delete temp_buf;
  21370. temp_buf = nullptr;
  21371. temp_char_buf = new char[OTL_SCAST(size_t,chunk_size + 1)];
  21372. temp_buf = new otl_long_string(temp_char_buf, chunk_size);
  21373. }
  21374. otl_lob_stream_generic &
  21375. operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION {
  21376. const int TEMP_BUF_SIZE = 4096;
  21377. if (!temp_char_buf)
  21378. temp_char_buf = new char[TEMP_BUF_SIZE];
  21379. if (!temp_buf)
  21380. temp_buf = new otl_long_string(temp_char_buf, TEMP_BUF_SIZE - 1);
  21381. int iters = 0;
  21382. while (!this->eof()) {
  21383. ++iters;
  21384. (*this) >> (*temp_buf);
  21385. temp_char_buf[temp_buf->len()] = 0;
  21386. if (iters > 1) {
  21387. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  21388. !defined(OTL_USER_DEFINED_STRING_CLASS_ON))
  21389. s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()));
  21390. #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE))
  21391. s.append(temp_char_buf, temp_buf->len());
  21392. #elif defined(OTL_ACE)
  21393. s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()));
  21394. #endif
  21395. } else
  21396. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  21397. !defined(OTL_USER_DEFINED_STRING_CLASS_ON))
  21398. s.assign(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()));
  21399. #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE))
  21400. s.assign(temp_char_buf, temp_buf->len());
  21401. #elif defined(OTL_ACE)
  21402. s.set(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()), 1);
  21403. #endif
  21404. }
  21405. return *this;
  21406. }
  21407. #endif
  21408. otl_lob_stream_generic &operator<<(const otl_long_string &s)
  21409. OTL_THROWS_OTL_EXCEPTION {
  21410. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  21411. if (bind_var && bind_var->get_ftype() == otl_var_blob)
  21412. in_unicode_mode = false;
  21413. if (s.get_unicode_flag() != in_unicode_mode) {
  21414. OTL_THROW((OTL_TMPL_EXCEPTION(
  21415. otl_error_msg_37, otl_error_code_37,
  21416. "otl_lob_stream_generic::operator<<(const otl_long_string&)")));
  21417. }
  21418. if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) {
  21419. const char *stm = nullptr;
  21420. char var_info[256];
  21421. var_info[0] = 0;
  21422. if (cursor != nullptr) {
  21423. if (cursor->get_stm_label())
  21424. stm = cursor->get_stm_label();
  21425. else
  21426. stm = cursor->get_stm_text();
  21427. }
  21428. if (bind_var != nullptr) {
  21429. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  21430. otl_var_long_string, var_info, sizeof(var_info));
  21431. }
  21432. char *vinfo = nullptr;
  21433. if (var_info[0] != 0)
  21434. vinfo = &var_info[0];
  21435. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  21436. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>(
  21437. otl_error_msg_9, otl_error_code_9, stm, vinfo)));
  21438. }
  21439. if (offset == 0)
  21440. offset = 1;
  21441. if ((offset - 1) + s.len() > lob_len) {
  21442. char var_info[256];
  21443. if (bind_var != nullptr)
  21444. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  21445. otl_var_long_string, var_info, sizeof(var_info));
  21446. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  21447. char err_msg[1024];
  21448. char temp_num[64];
  21449. OTL_STRCPY_S(err_msg, sizeof(err_msg), otl_error_msg_7);
  21450. OTL_STRCAT_S(err_msg, sizeof(err_msg), ", trying to store ");
  21451. otl_itoa(s.len(), temp_num);
  21452. OTL_STRCAT_S(err_msg, sizeof(err_msg), temp_num);
  21453. #if defined(OTL_UNICODE)
  21454. OTL_STRCAT_S(err_msg, sizeof(err_msg), " Unicode characters at offset ");
  21455. #else
  21456. OTL_STRCAT_S(err_msg, sizeof(err_msg), " bytes at offset ");
  21457. #endif
  21458. otl_itoa(offset, temp_num);
  21459. OTL_STRCAT_S(err_msg, sizeof(err_msg), temp_num);
  21460. OTL_STRCAT_S(err_msg, sizeof(err_msg), ". New length: ");
  21461. otl_itoa((offset - 1) + s.len(), temp_num);
  21462. OTL_STRCAT_S(err_msg, sizeof(err_msg), temp_num);
  21463. OTL_STRCAT_S(err_msg, sizeof(err_msg),
  21464. " would be bigger than length of lob: ");
  21465. otl_itoa(lob_len, temp_num);
  21466. OTL_STRCAT_S(err_msg, sizeof(err_msg), temp_num);
  21467. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>(
  21468. err_msg, otl_error_code_7,
  21469. cursor->get_stm_label() ? cursor->get_stm_label()
  21470. : cursor->get_stm_text(),
  21471. var_info)));
  21472. }
  21473. if (s.is_last_piece())
  21474. lob_len = (offset + s.len() - 1);
  21475. if (bind_var != nullptr)
  21476. retcode = bind_var->get_var_struct().write_blob(
  21477. s, lob_len, offset, cursor->get_cursor_struct());
  21478. if (retcode) {
  21479. if ((offset - 1) == lob_len)
  21480. close();
  21481. return *this;
  21482. }
  21483. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  21484. if(connect)
  21485. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
  21486. (connect->get_connect_struct(), cursor->get_stm_label()
  21487. ? cursor->get_stm_label()
  21488. : cursor->get_stm_text())));
  21489. else
  21490. return *this;
  21491. }
  21492. otl_lob_stream_generic &
  21493. operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION {
  21494. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  21495. if (bind_var && bind_var->get_ftype() == otl_var_blob)
  21496. in_unicode_mode = false;
  21497. if (s.get_unicode_flag() != in_unicode_mode) {
  21498. OTL_THROW((OTL_TMPL_EXCEPTION(
  21499. otl_error_msg_37, otl_error_code_37,
  21500. "otl_lob_stream_generic::operator>>(otl_long_string&)")));
  21501. }
  21502. if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  21503. const char *stm = nullptr;
  21504. char var_info[256];
  21505. var_info[0] = 0;
  21506. if (cursor != nullptr) {
  21507. if (cursor->get_stm_label())
  21508. stm = cursor->get_stm_label();
  21509. else
  21510. stm = cursor->get_stm_text();
  21511. }
  21512. if (bind_var != nullptr) {
  21513. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  21514. otl_var_long_string, var_info, sizeof(var_info));
  21515. }
  21516. char *vinfo = nullptr;
  21517. if (var_info[0] != 0)
  21518. vinfo = &var_info[0];
  21519. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  21520. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>(
  21521. otl_error_msg_10, otl_error_code_10, stm, vinfo)));
  21522. }
  21523. if (offset == 0 && lob_len == 0)
  21524. lob_len = len();
  21525. if (lob_len == 0 || (offset - 1) == lob_len) {
  21526. s.set_len(0);
  21527. eof_flag = 1;
  21528. return *this;
  21529. }
  21530. if (offset == 0)
  21531. offset = 1;
  21532. if (bind_var != nullptr)
  21533. retcode = bind_var->get_var_struct().read_blob(s, ndx, offset, lob_len);
  21534. if ((offset - 1) == lob_len)
  21535. eof_flag = 1;
  21536. if (retcode) {
  21537. if (eof()) {
  21538. close();
  21539. eof_flag = 1;
  21540. }
  21541. return *this;
  21542. }
  21543. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  21544. if(connect)
  21545. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
  21546. (connect->get_connect_struct(), cursor->get_stm_label()
  21547. ? cursor->get_stm_label()
  21548. : cursor->get_stm_text())));
  21549. else
  21550. return *this;
  21551. }
  21552. OTL_NODISCARD int eof(void) OTL_NO_THROW {
  21553. if (lob_is_null)
  21554. return 1;
  21555. return eof_flag;
  21556. }
  21557. OTL_NODISCARD bool is_initialized(void) OTL_THROWS_OTL_EXCEPTION {
  21558. if (cursor == nullptr || connect == nullptr || bind_var == nullptr ||
  21559. lob_is_null)
  21560. return false;
  21561. int is_init = 0;
  21562. retcode = bind_var->get_var_struct().is_blob_initialized(ndx, is_init);
  21563. if (retcode)
  21564. return is_init != 0;
  21565. OTL_UNCAUGHT_EXCEPTION_RETURN(false);
  21566. OTL_THROW((OTL_TMPL_EXCEPTION(connect->get_connect_struct(),
  21567. cursor->get_stm_label() ? cursor->get_stm_label()
  21568. : cursor->get_stm_text())));
  21569. }
  21570. OTL_NODISCARD int len(void) OTL_THROWS_OTL_EXCEPTION {
  21571. if (cursor == nullptr || connect == nullptr || bind_var == nullptr ||
  21572. lob_is_null)
  21573. return 0;
  21574. int alen;
  21575. retcode = bind_var->get_var_struct().get_blob_len(ndx, alen);
  21576. if (retcode)
  21577. return alen;
  21578. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  21579. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>(
  21580. connect->get_connect_struct(), cursor->get_stm_label()
  21581. ? cursor->get_stm_label()
  21582. : cursor->get_stm_text())));
  21583. }
  21584. void close(bool dont_throw_size_doesnt_match_exception =
  21585. false) OTL_THROWS_OTL_EXCEPTION {
  21586. if (in_destructor) {
  21587. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  21588. if(bind_var){
  21589. bind_var->get_var_struct().set_lob_stream_flag(0);
  21590. bind_var->set_not_null(0);
  21591. }
  21592. }
  21593. return;
  21594. }
  21595. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode))
  21596. return;
  21597. if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) {
  21598. if(bind_var){
  21599. if (offset < lob_len - 1)
  21600. (void)bind_var->get_var_struct().close_lob();
  21601. bind_var->get_var_struct().close_temporary_lob();
  21602. bind_var->get_var_struct().set_lob_stream_flag(0);
  21603. bind_var->set_not_null(0);
  21604. init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode));
  21605. }
  21606. } else {
  21607. // write mode
  21608. if (!(offset == 0 && lob_len == 0) && (offset - 1) != lob_len &&
  21609. !dont_throw_size_doesnt_match_exception) {
  21610. (void)bind_var->get_var_struct().close_lob();
  21611. char var_info[256];
  21612. char msg_buf[1024];
  21613. OTL_STRCPY_S(msg_buf, sizeof(msg_buf), otl_error_msg_8);
  21614. otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(),
  21615. otl_var_long_string, var_info, sizeof(var_info));
  21616. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21617. OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
  21618. TCursorStruct>(msg_buf, otl_error_code_8,
  21619. cursor->get_stm_label()
  21620. ? cursor->get_stm_label()
  21621. : cursor->get_stm_text(),
  21622. var_info)));
  21623. }
  21624. if(bind_var){
  21625. bind_var->get_var_struct().set_lob_stream_flag(0);
  21626. bind_var->set_not_null(0);
  21627. }
  21628. }
  21629. }
  21630. private:
  21631. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  21632. public:
  21633. otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) = delete;
  21634. otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) = delete;
  21635. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21636. otl_tmpl_lob_stream(otl_tmpl_lob_stream &&) = delete;
  21637. otl_tmpl_lob_stream &operator=(otl_tmpl_lob_stream &&) = delete;
  21638. #endif
  21639. private:
  21640. #else
  21641. otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) OTL_NO_THROW
  21642. : otl_lob_stream_generic(true),
  21643. bind_var(nullptr),
  21644. connect(nullptr),
  21645. cursor(nullptr),
  21646. temp_buf(nullptr),
  21647. temp_char_buf(nullptr) {}
  21648. otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) { return *this; }
  21649. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  21650. otl_tmpl_lob_stream(otl_tmpl_lob_stream &&) OTL_NO_THROW
  21651. : otl_lob_stream_generic(true),
  21652. bind_var(nullptr),
  21653. connect(nullptr),
  21654. cursor(nullptr),
  21655. temp_buf(nullptr),
  21656. temp_char_buf(nullptr) {}
  21657. otl_tmpl_lob_stream &operator=(otl_tmpl_lob_stream &&) { return *this; }
  21658. #endif
  21659. #endif
  21660. };
  21661. typedef otl_tmpl_lob_stream<otl_exc, otl_conn, otl_cur, otl_var> otl_lob_stream;
  21662. typedef otl_tmpl_exception<otl_exc, otl_conn, otl_cur> otl_exception;
  21663. typedef otl_tmpl_inout_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_time0>
  21664. otl_ora8_inout_stream;
  21665. typedef otl_tmpl_select_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_sel,
  21666. otl_time0> otl_select_stream;
  21667. typedef otl_tmpl_ext_hv_decl<otl_var, otl_time0, otl_exc, otl_conn, otl_cur>
  21668. otl_ext_hv_decl;
  21669. const int otl_no_stream_type = 0;
  21670. const int otl_inout_stream_type = 1;
  21671. const int otl_refcur_stream_type = 2;
  21672. const int otl_select_stream_type = 3;
  21673. const int otl_constant_sql_type = 4;
  21674. const int otl_mixed_refcur_stream_type = 5;
  21675. class otl_connect : public otl_ora8_connect {
  21676. protected:
  21677. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  21678. defined(OTL_UNICODE_STRING_TYPE)) && \
  21679. defined(OTL_STREAM_POOLING_ON)
  21680. otl_stream_pool sc;
  21681. bool pool_enabled_;
  21682. #endif
  21683. public:
  21684. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  21685. void set_lob_prefetch_size(const int prefetch_size =
  21686. 0) OTL_THROWS_OTL_EXCEPTION {
  21687. if (!connected)
  21688. return;
  21689. retcode = connect_struct.set_lob_prefetch_size(prefetch_size);
  21690. if (!retcode) {
  21691. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21692. OTL_THROW((otl_exception(connect_struct)));
  21693. }
  21694. }
  21695. #endif
  21696. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  21697. defined(OTL_UNICODE_STRING_TYPE)) && \
  21698. defined(OTL_STREAM_POOLING_ON)
  21699. otl_stream_pool &get_sc() { return sc; }
  21700. void set_stream_pool_size(const int max_size = otl_max_default_pool_size) {
  21701. sc.init(max_size);
  21702. }
  21703. void stream_pool_enable() { pool_enabled_ = true; }
  21704. void stream_pool_disable() { pool_enabled_ = false; }
  21705. OTL_NODISCARD bool get_stream_pool_enabled_flag() const { return pool_enabled_; }
  21706. #endif
  21707. public:
  21708. long direct_exec(const char *sqlstm,
  21709. const int exception_enabled = 1) OTL_THROWS_OTL_EXCEPTION {
  21710. return otl_cursor::direct_exec(*this, sqlstm, exception_enabled);
  21711. }
  21712. void syntax_check(const char *sqlstm) OTL_THROWS_OTL_EXCEPTION {
  21713. otl_cursor::syntax_check(*this, sqlstm);
  21714. }
  21715. otl_connect() OTL_NO_THROW : otl_ora8_connect(),
  21716. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  21717. defined(OTL_UNICODE_STRING_TYPE)) && \
  21718. defined(OTL_STREAM_POOLING_ON)
  21719. sc(),
  21720. pool_enabled_(true),
  21721. #endif
  21722. cmd_(nullptr) {
  21723. }
  21724. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21725. void set_connect_mode(bool threaded_mode = false) {
  21726. connect_struct.set_threaded_mode(threaded_mode);
  21727. }
  21728. #endif
  21729. #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8)
  21730. void set_character_set(const int char_set =
  21731. SQLCS_IMPLICIT) OTL_THROWS_OTL_EXCEPTION {
  21732. connect_struct.set_char_set(char_set);
  21733. }
  21734. #endif
  21735. otl_connect(const char *connect_str, const int aauto_commit = 0
  21736. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21737. ,
  21738. bool threaded_mode = false
  21739. #endif
  21740. )
  21741. OTL_THROWS_OTL_EXCEPTION:
  21742. otl_ora8_connect(),
  21743. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  21744. defined(OTL_UNICODE_STRING_TYPE)) && \
  21745. defined(OTL_STREAM_POOLING_ON)
  21746. sc(), pool_enabled_(true),
  21747. #endif
  21748. cmd_(nullptr) {
  21749. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21750. set_connect_mode(threaded_mode);
  21751. #endif
  21752. rlogon(connect_str, aauto_commit);
  21753. }
  21754. virtual ~otl_connect()
  21755. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  21756. OTL_THROWS_OTL_EXCEPTION
  21757. #else
  21758. OTL_NO_THROW
  21759. #endif
  21760. {
  21761. if (cmd_) {
  21762. delete[] cmd_;
  21763. cmd_ = nullptr;
  21764. }
  21765. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  21766. try {
  21767. #endif
  21768. logoff();
  21769. #if defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  21770. }
  21771. catch (OTL_CONST_EXCEPTION otl_exception &) {
  21772. }
  21773. #endif
  21774. }
  21775. OTL_NODISCARD const char *getCmd(void) const { return cmd_; }
  21776. otl_connect &operator<<(const char *cmd) {
  21777. if (!connected) {
  21778. this->rlogon(cmd);
  21779. } else {
  21780. otl_cursor::direct_exec(*this, cmd);
  21781. }
  21782. return *this;
  21783. }
  21784. otl_connect &operator<<=(const char *cmd) {
  21785. if (cmd_) {
  21786. delete[] cmd_;
  21787. cmd_ = nullptr;
  21788. }
  21789. size_t cmd_len = strlen(cmd);
  21790. cmd_ = new char[cmd_len + 1];
  21791. OTL_STRCPY_S(cmd_, cmd_len + 1, cmd);
  21792. return *this;
  21793. }
  21794. OTL_NODISCARD static int otl_terminate(void) OTL_THROWS_OTL_EXCEPTION {
  21795. #if defined(OTL_ORA8) && !defined(OTL_ORA8I) && !defined(OTL_ORA9I)
  21796. return 1;
  21797. #else
  21798. return OCITerminate(OCI_DEFAULT) == OCI_SUCCESS;
  21799. #endif
  21800. }
  21801. void cancel(void) OTL_THROWS_OTL_EXCEPTION {
  21802. if (!connected)
  21803. return;
  21804. retcode = connect_struct.cancel();
  21805. if (!retcode) {
  21806. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21807. OTL_THROW((otl_exception(connect_struct)));
  21808. }
  21809. }
  21810. #if defined(OTL_ORA10G_R2)
  21811. void commit_nowait(void) OTL_THROWS_OTL_EXCEPTION {
  21812. if (!connected)
  21813. return;
  21814. retcode = connect_struct.commit_nowait();
  21815. if (!retcode) {
  21816. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21817. OTL_THROW((otl_exception(connect_struct)));
  21818. }
  21819. }
  21820. #endif
  21821. #if defined(OTL_ORA8I) || defined(OTL_ORA9I)
  21822. void change_password(const char *user_name, const char *old_password,
  21823. const char *new_password) OTL_THROWS_OTL_EXCEPTION {
  21824. retcode =
  21825. connect_struct.change_password(user_name, old_password, new_password);
  21826. if (!retcode) {
  21827. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21828. OTL_THROW((otl_exception(connect_struct)));
  21829. }
  21830. }
  21831. #endif
  21832. void auto_commit_off(void) OTL_THROWS_OTL_EXCEPTION {
  21833. otl_ora8_connect::auto_commit_off();
  21834. }
  21835. void auto_commit_on(void) OTL_THROWS_OTL_EXCEPTION {
  21836. otl_ora8_connect::auto_commit_on();
  21837. }
  21838. void rlogon(OCIEnv *envhp, OCISvcCtx *svchp) OTL_THROWS_OTL_EXCEPTION {
  21839. if (this->connected) {
  21840. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  21841. }
  21842. if (cmd_) {
  21843. delete[] cmd_;
  21844. cmd_ = nullptr;
  21845. }
  21846. connected = 0;
  21847. long_max_size = otl_short_int_max;
  21848. retcode = connect_struct.ext_logon(envhp, svchp, 0);
  21849. if (retcode)
  21850. connected = 1;
  21851. else {
  21852. connected = 0;
  21853. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21854. OTL_THROW((otl_exception(connect_struct)));
  21855. }
  21856. }
  21857. void rlogon(const char *connect_str, const int aauto_commit = 0,
  21858. const char *xa_server_external_name = nullptr,
  21859. const char *xa_server_internal_name = nullptr
  21860. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21861. ,
  21862. bool threaded_mode = false
  21863. #endif
  21864. ) OTL_THROWS_OTL_EXCEPTION {
  21865. const char* c=connect_str;
  21866. while(*c){
  21867. if(*c=='@')
  21868. break;
  21869. ++c;
  21870. }
  21871. if(*c=='@' && *(c+1)==0){
  21872. OTL_THROW((otl_exception(otl_error_msg_44, otl_error_code_44)));
  21873. }
  21874. if (this->connected) {
  21875. OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30)));
  21876. }
  21877. if (cmd_) {
  21878. delete[] cmd_;
  21879. cmd_ = nullptr;
  21880. }
  21881. if (xa_server_external_name != nullptr &&
  21882. xa_server_internal_name != nullptr) {
  21883. connect_struct.set_xa_server_external_name(xa_server_external_name);
  21884. connect_struct.set_xa_server_internal_name(xa_server_internal_name);
  21885. }
  21886. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21887. set_connect_mode(threaded_mode);
  21888. #endif
  21889. otl_ora8_connect::rlogon(connect_str, aauto_commit);
  21890. if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) {
  21891. otl_exception ex(connect_struct);
  21892. if (ex.code != 0) {
  21893. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21894. OTL_THROW((ex));
  21895. }
  21896. }
  21897. }
  21898. void logoff(void) OTL_THROWS_OTL_EXCEPTION {
  21899. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  21900. defined(OTL_STREAM_POOLING_ON)
  21901. if (connected)
  21902. sc.init(sc.get_max_size());
  21903. #endif
  21904. if (!connected) {
  21905. (void)connect_struct.session_end();
  21906. (void)connect_struct.server_detach();
  21907. } else {
  21908. #if defined(OTL_ROLLS_BACK_BEFORE_LOGOFF)
  21909. otl_ora8_connect::rollback();
  21910. #endif
  21911. OTL_TRACE_FUNC(0x1, "otl_connect", "logoff", "")
  21912. if (connect_struct.get_extern_lda())
  21913. (void)connect_struct.logoff();
  21914. else {
  21915. session_end();
  21916. server_detach();
  21917. }
  21918. connected = 0;
  21919. }
  21920. }
  21921. void server_attach(const char *tnsname = nullptr,
  21922. const char *xa_server_external_name = nullptr,
  21923. const char *xa_server_internal_name = nullptr
  21924. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21925. ,
  21926. bool threaded_mode = false
  21927. #endif
  21928. ) OTL_THROWS_OTL_EXCEPTION {
  21929. if (cmd_) {
  21930. delete[] cmd_;
  21931. cmd_ = nullptr;
  21932. }
  21933. if (xa_server_external_name != nullptr &&
  21934. xa_server_internal_name != nullptr) {
  21935. connect_struct.set_xa_server_external_name(xa_server_external_name);
  21936. connect_struct.set_xa_server_internal_name(xa_server_internal_name);
  21937. }
  21938. connected = 0;
  21939. long_max_size = otl_short_int_max;
  21940. #if defined(OTL_ORA_OCI_ENV_CREATE)
  21941. set_connect_mode(threaded_mode);
  21942. #endif
  21943. retcode = connect_struct.server_attach(tnsname);
  21944. if (!retcode) {
  21945. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21946. OTL_THROW((otl_exception(connect_struct)));
  21947. }
  21948. }
  21949. void server_detach(void) OTL_THROWS_OTL_EXCEPTION {
  21950. retcode = connect_struct.server_detach();
  21951. if (!retcode) {
  21952. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21953. OTL_THROW((otl_exception(connect_struct)));
  21954. }
  21955. }
  21956. void session_begin(
  21957. const char *username, const char *password, const int auto_commit = 0,
  21958. const int session_mode = OCI_DEFAULT
  21959. // OCI_SYSDBA -- in this mode, the user is authenticated for SYSDBA
  21960. // access.
  21961. // OCI_SYSOPER -- in this mode, the user is authenticated
  21962. // for SYSOPER access.
  21963. ) OTL_THROWS_OTL_EXCEPTION {
  21964. if (cmd_) {
  21965. delete[] cmd_;
  21966. cmd_ = nullptr;
  21967. }
  21968. retcode = connect_struct.session_begin(username, password, auto_commit,
  21969. session_mode);
  21970. if (retcode)
  21971. connected = 1;
  21972. else {
  21973. connected = 0;
  21974. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21975. OTL_THROW((otl_exception(connect_struct)));
  21976. }
  21977. if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) {
  21978. otl_exception ex(connect_struct);
  21979. if (ex.code != 0) {
  21980. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21981. OTL_THROW((ex));
  21982. }
  21983. }
  21984. }
  21985. void session_reopen(const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION {
  21986. if (connect_struct.get_session_begin_count() == 0) {
  21987. connected = 0;
  21988. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21989. OTL_THROW((otl_exception(otl_error_msg_11, otl_error_code_11)));
  21990. }
  21991. retcode = connect_struct.session_begin(auto_commit);
  21992. if (retcode)
  21993. connected = 1;
  21994. else {
  21995. connected = 0;
  21996. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  21997. OTL_THROW((otl_exception(connect_struct)));
  21998. }
  21999. if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) {
  22000. otl_exception ex(connect_struct);
  22001. if (ex.code != 0) {
  22002. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  22003. OTL_THROW((ex));
  22004. }
  22005. }
  22006. }
  22007. void session_end(void) OTL_THROWS_OTL_EXCEPTION {
  22008. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  22009. defined(OTL_STREAM_POOLING_ON)
  22010. if (connected)
  22011. sc.init(sc.get_max_size());
  22012. #endif
  22013. connected = 0;
  22014. retcode = connect_struct.session_end();
  22015. if (!retcode) {
  22016. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  22017. OTL_THROW((otl_exception(connect_struct)));
  22018. }
  22019. }
  22020. private:
  22021. char *cmd_;
  22022. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  22023. public:
  22024. otl_connect &operator=(const otl_connect &) = delete;
  22025. otl_connect(const otl_connect &) = delete;
  22026. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  22027. otl_connect &operator=(otl_connect &&) = delete;
  22028. otl_connect(otl_connect &&) = delete;
  22029. #endif
  22030. private:
  22031. #else
  22032. otl_connect &operator=(const otl_connect &) { return *this; }
  22033. otl_connect(const otl_connect &)
  22034. : otl_ora8_connect(),
  22035. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  22036. defined(OTL_UNICODE_STRING_TYPE)) && \
  22037. defined(OTL_STREAM_POOLING_ON)
  22038. sc(), pool_enabled_(true),
  22039. #endif
  22040. cmd_(nullptr) {
  22041. }
  22042. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  22043. otl_connect &operator=(otl_connect &&) { return *this; }
  22044. otl_connect(otl_connect &&)
  22045. : otl_ora8_connect(),
  22046. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  22047. defined(OTL_UNICODE_STRING_TYPE)) && \
  22048. defined(OTL_STREAM_POOLING_ON)
  22049. sc(), pool_enabled_(true),
  22050. #endif
  22051. cmd_(nullptr) {
  22052. }
  22053. #endif
  22054. #endif
  22055. };
  22056. typedef otl_tmpl_variable<otl_var> otl_generic_variable;
  22057. typedef otl_generic_variable *otl_p_generic_variable;
  22058. class otl_refcur_base_cursor
  22059. : public otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> {
  22060. protected:
  22061. int cur_row;
  22062. int cur_size;
  22063. int row_count;
  22064. int array_size;
  22065. public:
  22066. otl_refcur_base_cursor(otl_connect &db, otl_var *var,
  22067. const char *master_plsql_block,
  22068. const otl_stream_buffer_size_type arr_size = 1)
  22069. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(db, var),
  22070. cur_row(-1), cur_size(0), row_count(0), array_size(arr_size) {
  22071. size_t len = strlen(master_plsql_block) + 1;
  22072. stm_text = new char[len];
  22073. OTL_STRCPY_S(stm_text, len, master_plsql_block);
  22074. }
  22075. otl_refcur_base_cursor()
  22076. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  22077. cur_size(0), row_count(0), array_size(0) {}
  22078. virtual ~otl_refcur_base_cursor() {
  22079. delete[] stm_text;
  22080. stm_text = nullptr;
  22081. }
  22082. void open(otl_connect &db, otl_var *var, const char *master_plsql_block,
  22083. const otl_stream_buffer_size_type arr_size = 1) {
  22084. cur_row = -1;
  22085. row_count = 0;
  22086. cur_size = 0;
  22087. array_size = arr_size;
  22088. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::open(db, var);
  22089. size_t len = strlen(master_plsql_block) + 1;
  22090. stm_text = new char[len];
  22091. OTL_STRCPY_S(stm_text, len, master_plsql_block);
  22092. }
  22093. void close(const char = 'N') {
  22094. delete[] stm_text;
  22095. stm_text = nullptr;
  22096. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::close();
  22097. }
  22098. OTL_NODISCARD int first(void) {
  22099. int rc;
  22100. cur_row = -1;
  22101. rc = cursor_struct.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size),
  22102. eof_data);
  22103. if (rc == 0) {
  22104. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  22105. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  22106. }
  22107. row_count = OTL_SCAST(int, cursor_struct.rpc());
  22108. cur_size = row_count;
  22109. if (cur_size != 0)
  22110. cur_row = 0;
  22111. return cur_size != 0;
  22112. }
  22113. OTL_NODISCARD int next(void) {
  22114. int rc;
  22115. if (cur_row < 0)
  22116. return first();
  22117. if (cur_row < cur_size - 1)
  22118. ++cur_row;
  22119. else {
  22120. if (otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::eof()) {
  22121. cur_row = -1;
  22122. return 0;
  22123. }
  22124. rc = cursor_struct.fetch(
  22125. OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data);
  22126. if (rc == 0) {
  22127. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  22128. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  22129. }
  22130. cur_size = OTL_SCAST(int, cursor_struct.rpc()) - row_count;
  22131. row_count = OTL_SCAST(int, cursor_struct.rpc());
  22132. if (cur_size != 0)
  22133. cur_row = 0;
  22134. }
  22135. return cur_size != 0;
  22136. }
  22137. void bind_col(const int column_num, otl_generic_variable &v) {
  22138. if (!connected)
  22139. return;
  22140. v.set_pos(column_num);
  22141. otl_refcur_base_cursor::bind(column_num, v);
  22142. }
  22143. OTL_NODISCARD int describe_select(otl_column_desc *desc, int &desc_len) {
  22144. int i;
  22145. desc_len = 0;
  22146. cursor_struct.straight_select = 0;
  22147. for (i = 1; describe_column(desc[i - 1], i); ++i)
  22148. ++desc_len;
  22149. return 1;
  22150. }
  22151. private:
  22152. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  22153. public:
  22154. otl_refcur_base_cursor(const otl_refcur_base_cursor &) = delete;
  22155. otl_refcur_base_cursor &operator=(const otl_refcur_base_cursor &) = delete;
  22156. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  22157. otl_refcur_base_cursor(otl_refcur_base_cursor &&) = delete;
  22158. otl_refcur_base_cursor &operator=(otl_refcur_base_cursor &&) = delete;
  22159. #endif
  22160. private:
  22161. #else
  22162. otl_refcur_base_cursor(const otl_refcur_base_cursor &)
  22163. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  22164. cur_size(0), row_count(0), array_size(0) {}
  22165. otl_refcur_base_cursor &operator=(const otl_refcur_base_cursor &) {
  22166. return *this;
  22167. }
  22168. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  22169. otl_refcur_base_cursor(otl_refcur_base_cursor &&)
  22170. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  22171. cur_size(0), row_count(0), array_size(0) {}
  22172. otl_refcur_base_cursor &operator=(otl_refcur_base_cursor &&) { return *this; }
  22173. #endif
  22174. #endif
  22175. };
  22176. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  22177. #define OTL_ORA_COMMON_READ_STREAM otl_read_stream_interface
  22178. #define OTL_ORA_REFCUR_COMMON_READ_STREAM otl_read_stream_interface
  22179. class otl_read_stream_interface {
  22180. public:
  22181. virtual ~otl_read_stream_interface() OTL_THROWS_OTL_EXCEPTION {}
  22182. OTL_NODISCARD virtual int is_null(void) OTL_NO_THROW = 0;
  22183. virtual void rewind(void) OTL_THROWS_OTL_EXCEPTION = 0;
  22184. OTL_NODISCARD virtual int eof(void) OTL_THROWS_OTL_EXCEPTION = 0;
  22185. virtual void skip_to_end_of_row(void) OTL_THROWS_OTL_EXCEPTION = 0;
  22186. virtual void skip_to_next_var(void) OTL_THROWS_OTL_EXCEPTION = 0;
  22187. OTL_NODISCARD virtual otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW = 0;
  22188. OTL_NODISCARD virtual otl_var_desc *describe_next_out_var(void) OTL_NO_THROW = 0;
  22189. virtual otl_read_stream_interface &
  22190. operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION = 0;
  22191. #if !defined(OTL_UNICODE)
  22192. virtual otl_read_stream_interface &
  22193. operator>>(char &c) OTL_THROWS_OTL_EXCEPTION = 0;
  22194. #endif
  22195. virtual otl_read_stream_interface &
  22196. operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION = 0;
  22197. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  22198. virtual otl_read_stream_interface &
  22199. operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION = 0;
  22200. #endif
  22201. #if defined(OTL_UNICODE_STRING_TYPE)
  22202. virtual otl_read_stream_interface &
  22203. operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION = 0;
  22204. #endif
  22205. #if !defined(OTL_UNICODE)
  22206. virtual otl_read_stream_interface &
  22207. operator>>(char *s) OTL_THROWS_OTL_EXCEPTION = 0;
  22208. #endif
  22209. #if defined(OTL_UNICODE)
  22210. virtual otl_read_stream_interface &
  22211. operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION = 0;
  22212. #endif
  22213. virtual otl_read_stream_interface &
  22214. operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION = 0;
  22215. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  22216. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  22217. virtual otl_read_stream_interface &
  22218. operator>>(OTL_NUMERIC_TYPE_1 &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22219. #endif
  22220. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  22221. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  22222. virtual otl_read_stream_interface &
  22223. operator>>(OTL_NUMERIC_TYPE_2 &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22224. #endif
  22225. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  22226. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  22227. virtual otl_read_stream_interface &
  22228. operator>>(OTL_NUMERIC_TYPE_3 &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22229. #endif
  22230. #if defined(OTL_BIGINT) && \
  22231. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  22232. !defined(OTL_BIGINT_TO_STR))
  22233. virtual otl_read_stream_interface &
  22234. operator>>(OTL_BIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22235. #endif
  22236. #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \
  22237. defined(OTL_BIGINT_TO_STR)
  22238. virtual otl_read_stream_interface &
  22239. operator>>(OTL_BIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22240. #endif
  22241. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  22242. virtual otl_read_stream_interface &
  22243. operator>>(OTL_UBIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22244. #endif
  22245. virtual otl_read_stream_interface &
  22246. operator>>(int &n) OTL_THROWS_OTL_EXCEPTION = 0;
  22247. virtual otl_read_stream_interface &
  22248. operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION = 0;
  22249. virtual otl_read_stream_interface &
  22250. operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION = 0;
  22251. virtual otl_read_stream_interface &
  22252. operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION = 0;
  22253. virtual otl_read_stream_interface &
  22254. operator>>(float &f) OTL_THROWS_OTL_EXCEPTION = 0;
  22255. virtual otl_read_stream_interface &
  22256. operator>>(double &d) OTL_THROWS_OTL_EXCEPTION = 0;
  22257. virtual otl_read_stream_interface &
  22258. operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION = 0;
  22259. virtual otl_read_stream_interface &
  22260. operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION = 0;
  22261. virtual otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW = 0;
  22262. };
  22263. #else
  22264. #define OTL_ORA_COMMON_READ_STREAM otl_stream
  22265. #define OTL_ORA_REFCUR_COMMON_READ_STREAM otl_refcur_stream
  22266. #endif
  22267. class otl_refcur_stream :
  22268. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  22269. public otl_read_stream_interface,
  22270. #endif
  22271. public otl_refcur_base_cursor {
  22272. protected:
  22273. int delay_next;
  22274. int same_sl_flag;
  22275. otl_select_struct_override override_;
  22276. otl_var_desc *ov;
  22277. int ov_len;
  22278. int next_ov_ndx;
  22279. void inc_next_ov(void) {
  22280. if (ov_len == 0)
  22281. return;
  22282. if (next_ov_ndx < ov_len - 1)
  22283. ++next_ov_ndx;
  22284. else
  22285. next_ov_ndx = 0;
  22286. }
  22287. public:
  22288. void skip_to_end_of_row() OTL_THROWS_OTL_EXCEPTION {
  22289. check_if_executed();
  22290. if (eof())
  22291. return;
  22292. while (cur_col < sl_len - 1) {
  22293. ++cur_col;
  22294. null_fetched = sl[cur_col].is_null(this->cur_row);
  22295. }
  22296. ret_code = this->next();
  22297. cur_col = 0;
  22298. if (!eof())
  22299. cur_col = -1;
  22300. }
  22301. void skip_to_next_var() {
  22302. check_if_executed();
  22303. if (eof_intern())
  22304. return;
  22305. get_next();
  22306. look_ahead();
  22307. }
  22308. OTL_NODISCARD bool good() const { return get_connected() == 1; }
  22309. OTL_NODISCARD bool get_lob_stream_flag() const { return true; }
  22310. OTL_NODISCARD int get_adb_max_long_size() const { return this->adb->get_max_long_size(); }
  22311. void set_column_type(const int column_ndx, const int col_type,
  22312. const int col_size = 0) OTL_NO_THROW {
  22313. override_.add_override(column_ndx, col_type, col_size);
  22314. }
  22315. void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW {
  22316. override_.set_all_column_types(mask);
  22317. }
  22318. void cleanup(void) {
  22319. int i;
  22320. delete[] sl;
  22321. delete[] ov;
  22322. for (i = 0; i < vl_len; ++i)
  22323. delete vl[i];
  22324. delete[] vl;
  22325. delete[] sl_desc;
  22326. }
  22327. otl_refcur_stream() OTL_NO_THROW : otl_refcur_base_cursor(),
  22328. delay_next(0),
  22329. same_sl_flag(0),
  22330. override_(),
  22331. ov(nullptr),
  22332. ov_len(0),
  22333. next_ov_ndx(0),
  22334. sl_desc(nullptr),
  22335. sl_len(),
  22336. sl(nullptr),
  22337. null_fetched(0),
  22338. ret_code(0),
  22339. cur_col(0),
  22340. cur_in(0),
  22341. executed(0),
  22342. var_info() {
  22343. init();
  22344. }
  22345. otl_refcur_stream(const otl_stream_buffer_size_type arr_size,
  22346. const char *master_plsql_block, otl_var *var,
  22347. otl_connect &db)
  22348. OTL_THROWS_OTL_EXCEPTION:
  22349. otl_refcur_base_cursor(db, var, master_plsql_block, arr_size), delay_next(0),
  22350. same_sl_flag(0), override_(), ov(nullptr), ov_len(0), next_ov_ndx(0),
  22351. sl_desc(nullptr), sl_len(), sl(nullptr), null_fetched(0), ret_code(0),
  22352. cur_col(0), cur_in(0), executed(0), var_info() {
  22353. init();
  22354. try {
  22355. rewind();
  22356. null_fetched = 0;
  22357. }
  22358. catch (OTL_CONST_EXCEPTION otl_exception &) {
  22359. cleanup();
  22360. throw;
  22361. }
  22362. }
  22363. virtual ~otl_refcur_stream() OTL_THROWS_OTL_EXCEPTION {
  22364. cleanup();
  22365. close();
  22366. }
  22367. OTL_NODISCARD int is_null(void) OTL_NO_THROW { return null_fetched; }
  22368. OTL_NODISCARD int eof(void)
  22369. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  22370. OTL_THROWS_OTL_EXCEPTION
  22371. #else
  22372. OTL_THROWS_OTL_EXCEPTION
  22373. #endif
  22374. {
  22375. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  22376. if (cur_col == sl_len - 1) {
  22377. get_next();
  22378. cur_col = -1;
  22379. } else {
  22380. if (delay_next) {
  22381. look_ahead();
  22382. delay_next = 0;
  22383. }
  22384. }
  22385. return !ret_code;
  22386. #else
  22387. if (delay_next) {
  22388. look_ahead();
  22389. delay_next = 0;
  22390. }
  22391. return !ret_code;
  22392. #endif
  22393. }
  22394. OTL_NODISCARD int eof_intern(void) { return !ret_code; }
  22395. void check_if_executed(void) {}
  22396. void open(otl_connect &db, otl_var *var, const char *master_plsql_block,
  22397. const otl_stream_buffer_size_type arr_size =
  22398. 1) OTL_THROWS_OTL_EXCEPTION {
  22399. otl_refcur_base_cursor::open(db, var, master_plsql_block, arr_size);
  22400. get_select_list();
  22401. rewind();
  22402. delete[] ov;
  22403. ov = new otl_var_desc[OTL_SCAST(size_t,sl_len)];
  22404. ov_len = sl_len;
  22405. for (int i = 0; i < sl_len; ++i) {
  22406. sl[i].copy_var_desc(ov[i]);
  22407. if (sl_desc != nullptr){
  22408. ov[i].copy_name(sl_desc[i].name);
  22409. ov[i].set_param_type(1);
  22410. }
  22411. }
  22412. }
  22413. void close(const char = 'N') OTL_THROWS_OTL_EXCEPTION {
  22414. override_.reset();
  22415. otl_refcur_base_cursor::close();
  22416. }
  22417. otl_refcur_stream &operator>>(otl_time0 &t) OTL_THROWS_OTL_EXCEPTION {
  22418. check_if_executed();
  22419. if (eof_intern())
  22420. return *this;
  22421. get_next();
  22422. if (check_type(otl_var_timestamp) && !eof_intern()) {
  22423. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  22424. void *tm = OTL_RCAST(void *, sl[cur_col].val(this->cur_row));
  22425. int rc = sl[cur_col].get_var_struct().read_dt(&t, tm, sizeof(otl_time0));
  22426. if (rc == 0) {
  22427. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  22428. OTL_THROW((otl_exception(adb->get_connect_struct(),
  22429. stm_label ? stm_label : stm_text)));
  22430. }
  22431. #else
  22432. otl_time0 *tm = OTL_RCAST(otl_time0 *, sl[cur_col].val(cur_row));
  22433. memcpy(OTL_RCAST(void *, &t), tm, otl_oracle_date_size);
  22434. #endif
  22435. look_ahead();
  22436. }
  22437. inc_next_ov();
  22438. return *this;
  22439. }
  22440. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  22441. // already declared
  22442. #else
  22443. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22444. operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION {
  22445. otl_time0 tmp;
  22446. (*this) >> tmp;
  22447. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  22448. if ((*this).is_null())
  22449. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  22450. else {
  22451. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  22452. (OTL_SCAST(int, tmp.year) - 100);
  22453. s.month = tmp.month;
  22454. s.day = tmp.day;
  22455. s.hour = tmp.hour - 1;
  22456. s.minute = tmp.minute - 1;
  22457. s.second = tmp.second - 1;
  22458. }
  22459. #else
  22460. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  22461. (OTL_SCAST(int, tmp.year) - 100);
  22462. s.month = tmp.month;
  22463. s.day = tmp.day;
  22464. s.hour = tmp.hour - 1;
  22465. s.minute = tmp.minute - 1;
  22466. s.second = tmp.second - 1;
  22467. #endif
  22468. inc_next_ov();
  22469. return *this;
  22470. }
  22471. #endif
  22472. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22473. operator>>(char &c) OTL_THROWS_OTL_EXCEPTION {
  22474. check_if_executed();
  22475. if (eof_intern())
  22476. return *this;
  22477. get_next();
  22478. if (check_type(otl_var_char) && !eof_intern()) {
  22479. c = *OTL_RCAST(char *, sl[cur_col].val(cur_row));
  22480. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  22481. if ((*this).is_null())
  22482. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  22483. #endif
  22484. look_ahead();
  22485. }
  22486. inc_next_ov();
  22487. return *this;
  22488. }
  22489. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22490. operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION {
  22491. check_if_executed();
  22492. if (eof_intern())
  22493. return *this;
  22494. get_next();
  22495. if (check_type(otl_var_char) && !eof_intern()) {
  22496. c = *OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  22497. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  22498. if ((*this).is_null())
  22499. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  22500. #endif
  22501. look_ahead();
  22502. }
  22503. inc_next_ov();
  22504. return *this;
  22505. }
  22506. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  22507. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22508. operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION {
  22509. check_if_executed();
  22510. if (eof_intern())
  22511. return *this;
  22512. get_next();
  22513. switch (sl[cur_col].get_ftype()) {
  22514. case otl_var_char:
  22515. if (!eof_intern()) {
  22516. #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL)
  22517. if ((*this).is_null()) {
  22518. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s);
  22519. } else
  22520. #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22521. if ((*this).is_null())
  22522. s = OTL_DEFAULT_STRING_NULL_TO_VAL;
  22523. else
  22524. #endif
  22525. #if defined(OTL_ACE)
  22526. s.set(OTL_RCAST(char *, sl[cur_col].val(cur_row)), 1);
  22527. #else
  22528. s = OTL_RCAST(char *, sl[cur_col].val(cur_row));
  22529. #endif
  22530. look_ahead();
  22531. }
  22532. break;
  22533. #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE)
  22534. case otl_var_varchar_long:
  22535. case otl_var_raw_long:
  22536. if (!eof_intern()) {
  22537. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  22538. int len = sl[cur_col].get_len(cur_row);
  22539. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  22540. !defined(USER_DEFINED_STRING_CLASS))
  22541. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len));
  22542. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  22543. s.assign(OTL_RCAST(char *, c), len);
  22544. #elif defined(OTL_ACE)
  22545. s.set(OTL_RCAST(char *, c), len, 1);
  22546. #endif
  22547. look_ahead();
  22548. }
  22549. break;
  22550. case otl_var_blob:
  22551. case otl_var_clob:
  22552. if (!eof_intern()) {
  22553. int len = 0;
  22554. int max_long_sz = this->adb->get_max_long_size();
  22555. otl_auto_array_ptr<unsigned char> loc_ptr(max_long_sz);
  22556. unsigned char *temp_buf = loc_ptr.get_ptr();
  22557. int rc = sl[cur_col].get_var_struct().get_blob(cur_row, temp_buf,
  22558. max_long_sz, len);
  22559. if (rc == 0) {
  22560. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  22561. OTL_THROW((otl_exception(adb->get_connect_struct(),
  22562. stm_label ? stm_label : stm_text)));
  22563. }
  22564. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  22565. !defined(USER_DEFINED_STRING_CLASS))
  22566. s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len));
  22567. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  22568. s.assign(OTL_RCAST(char *, temp_buf), len);
  22569. #elif defined(OTL_ACE)
  22570. s.set(OTL_RCAST(char *, temp_buf), len, 1);
  22571. #endif
  22572. look_ahead();
  22573. }
  22574. break;
  22575. #endif
  22576. default:
  22577. (void)check_type(otl_var_char);
  22578. } // switch
  22579. inc_next_ov();
  22580. return *this;
  22581. }
  22582. #endif
  22583. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22584. operator>>(char *s) OTL_THROWS_OTL_EXCEPTION {
  22585. check_if_executed();
  22586. if (eof_intern())
  22587. return *this;
  22588. get_next();
  22589. if (check_type(otl_var_char) && !eof_intern()) {
  22590. otl_strcpy(OTL_RCAST(unsigned char *, s),
  22591. OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row)));
  22592. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22593. if ((*this).is_null())
  22594. otl_strcpy(
  22595. OTL_RCAST(unsigned char *, s),
  22596. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  22597. #endif
  22598. look_ahead();
  22599. }
  22600. inc_next_ov();
  22601. return *this;
  22602. }
  22603. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  22604. template<const size_t N>
  22605. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22606. operator>>(std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
  22607. check_if_executed();
  22608. if (eof_intern())
  22609. return *this;
  22610. get_next();
  22611. if (check_type(otl_var_char) && !eof_intern()) {
  22612. if(N<sl[cur_col].get_len(cur_row))
  22613. OTL_THROW((otl_exception(otl_error_msg_45,
  22614. otl_error_code_45,
  22615. this->get_stm_text(),
  22616. this->describe_next_out_var()->name)));
  22617. otl_strcpy(OTL_RCAST(unsigned char *, s),
  22618. OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row)));
  22619. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22620. if ((*this).is_null())
  22621. otl_strcpy(
  22622. OTL_RCAST(unsigned char *, s.data()),
  22623. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  22624. #endif
  22625. look_ahead();
  22626. }
  22627. inc_next_ov();
  22628. return *this;
  22629. }
  22630. #endif
  22631. #if defined(OTL_UNICODE_STRING_TYPE)
  22632. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22633. operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION {
  22634. check_if_executed();
  22635. if (eof_intern())
  22636. return *this;
  22637. get_next();
  22638. if (check_type(otl_var_char) && !eof_intern()) {
  22639. #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR)
  22640. OTL_UNICODE_CHAR_TYPE *temp_s =
  22641. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(cur_row));
  22642. OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s);
  22643. #else
  22644. OTL_UNICODE_CHAR_TYPE *temp_s =
  22645. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(cur_row));
  22646. s.assign(temp_s + 1, *temp_s);
  22647. #endif
  22648. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22649. if ((*this).is_null())
  22650. s = OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *,
  22651. OTL_DEFAULT_STRING_NULL_TO_VAL);
  22652. #endif
  22653. look_ahead();
  22654. }
  22655. inc_next_ov();
  22656. return *this;
  22657. }
  22658. #endif
  22659. #if defined(OTL_UNICODE)
  22660. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22661. operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION {
  22662. check_if_executed();
  22663. if (eof_intern())
  22664. return *this;
  22665. get_next();
  22666. if (check_type(otl_var_char) && !eof_intern()) {
  22667. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  22668. OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)),
  22669. sl[cur_col].get_len(cur_row));
  22670. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22671. if ((*this).is_null())
  22672. otl_strcpy(
  22673. OTL_RCAST(unsigned char *, s),
  22674. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  22675. #endif
  22676. look_ahead();
  22677. }
  22678. inc_next_ov();
  22679. return *this;
  22680. }
  22681. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  22682. template<const size_t N>
  22683. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22684. operator>>(std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
  22685. check_if_executed();
  22686. if (eof_intern())
  22687. return *this;
  22688. get_next();
  22689. if (check_type(otl_var_char) && !eof_intern()) {
  22690. if(N<sl[cur_col].get_len(cur_row))
  22691. OTL_THROW((otl_exception(otl_error_msg_46,
  22692. otl_error_code_46,
  22693. this->get_stm_text(),
  22694. this->describe_next_out_var()->name)));
  22695. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  22696. OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)),
  22697. sl[cur_col].get_len(cur_row));
  22698. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22699. if ((*this).is_null())
  22700. otl_strcpy(
  22701. OTL_RCAST(unsigned char *, s.data()),
  22702. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  22703. #endif
  22704. look_ahead();
  22705. }
  22706. inc_next_ov();
  22707. return *this;
  22708. }
  22709. #endif
  22710. #endif
  22711. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22712. operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION {
  22713. check_if_executed();
  22714. if (eof_intern())
  22715. return *this;
  22716. get_next();
  22717. if (check_type(otl_var_char) && !eof_intern()) {
  22718. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  22719. OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)),
  22720. sl[cur_col].get_len(cur_row));
  22721. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  22722. if ((*this).is_null())
  22723. otl_strcpy(
  22724. OTL_RCAST(unsigned char *, s),
  22725. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  22726. #endif
  22727. look_ahead();
  22728. }
  22729. inc_next_ov();
  22730. return *this;
  22731. }
  22732. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22733. operator>>(int &n) OTL_THROWS_OTL_EXCEPTION {
  22734. check_if_executed();
  22735. if (eof_intern())
  22736. return *this;
  22737. get_next();
  22738. if (!eof_intern()) {
  22739. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22740. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22741. sl[cur_col].val(cur_row), n);
  22742. #else
  22743. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22744. sl[cur_col].val(cur_row), n);
  22745. #endif
  22746. if (!match_found) {
  22747. if (check_type(otl_var_double, otl_var_int))
  22748. n = OTL_PCONV(int, double, sl[cur_col].val(cur_row));
  22749. }
  22750. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22751. if ((*this).is_null())
  22752. n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22753. #endif
  22754. look_ahead();
  22755. }
  22756. inc_next_ov();
  22757. return *this;
  22758. }
  22759. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  22760. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  22761. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22762. operator>>(OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION {
  22763. check_if_executed();
  22764. if (eof_intern())
  22765. return *this;
  22766. get_next();
  22767. if (!eof_intern()) {
  22768. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22769. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22770. sl[cur_col].val(cur_row), n);
  22771. #else
  22772. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22773. sl[cur_col].val(cur_row), n);
  22774. #endif
  22775. if (!match_found) {
  22776. if (check_type(otl_var_double, otl_var_int))
  22777. n = OTL_PCONV(OTL_NUMERIC_TYPE_1, double, sl[cur_col].val(cur_row));
  22778. }
  22779. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22780. if ((*this).is_null())
  22781. n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22782. #endif
  22783. look_ahead();
  22784. }
  22785. inc_next_ov();
  22786. return *this;
  22787. }
  22788. #endif
  22789. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  22790. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  22791. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22792. operator>>(OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION {
  22793. check_if_executed();
  22794. if (eof_intern())
  22795. return *this;
  22796. get_next();
  22797. if (!eof_intern()) {
  22798. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22799. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22800. sl[cur_col].val(cur_row), n);
  22801. #else
  22802. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22803. sl[cur_col].val(cur_row), n);
  22804. #endif
  22805. if (!match_found) {
  22806. if (check_type(otl_var_double, otl_var_int))
  22807. n = OTL_PCONV(OTL_NUMERIC_TYPE_2, double, sl[cur_col].val(cur_row));
  22808. }
  22809. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22810. if ((*this).is_null())
  22811. n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22812. #endif
  22813. look_ahead();
  22814. }
  22815. inc_next_ov();
  22816. return *this;
  22817. }
  22818. #endif
  22819. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  22820. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  22821. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22822. operator>>(OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION {
  22823. check_if_executed();
  22824. if (eof_intern())
  22825. return *this;
  22826. get_next();
  22827. if (!eof_intern()) {
  22828. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22829. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22830. sl[cur_col].val(cur_row), n);
  22831. #else
  22832. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22833. sl[cur_col].val(cur_row), n);
  22834. #endif
  22835. if (!match_found) {
  22836. if (check_type(otl_var_double, otl_var_int))
  22837. n = OTL_PCONV(OTL_NUMERIC_TYPE_3, double, sl[cur_col].val(cur_row));
  22838. }
  22839. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22840. if ((*this).is_null())
  22841. n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22842. #endif
  22843. look_ahead();
  22844. }
  22845. inc_next_ov();
  22846. return *this;
  22847. }
  22848. #endif
  22849. #if defined(OTL_BIGINT) && \
  22850. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  22851. !defined(OTL_BIGINT_TO_STR))
  22852. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22853. operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  22854. check_if_executed();
  22855. if (eof_intern())
  22856. return *this;
  22857. get_next();
  22858. if (!eof_intern()) {
  22859. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22860. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22861. sl[cur_col].val(cur_row), n);
  22862. #else
  22863. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22864. sl[cur_col].val(cur_row), n);
  22865. #endif
  22866. if (!match_found) {
  22867. if (check_type(otl_var_double, otl_var_int))
  22868. n = OTL_PCONV(OTL_BIGINT, double, sl[cur_col].val(cur_row));
  22869. }
  22870. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22871. if ((*this).is_null())
  22872. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22873. #endif
  22874. look_ahead();
  22875. }
  22876. inc_next_ov();
  22877. return *this;
  22878. }
  22879. #endif
  22880. #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \
  22881. defined(OTL_BIGINT_TO_STR)
  22882. otl_refcur_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  22883. char temp_val[otl_bigint_str_size];
  22884. (*this) >> temp_val;
  22885. if (this->is_null()) {
  22886. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22887. if (this->is_null())
  22888. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22889. #endif
  22890. return *this;
  22891. }
  22892. OTL_STR_TO_BIGINT(temp_val, n)
  22893. return *this;
  22894. }
  22895. #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG)
  22896. otl_refcur_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  22897. long temp_val;
  22898. (*this) >> temp_val;
  22899. if (this->is_null()) {
  22900. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22901. if (this->is_null())
  22902. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22903. #endif
  22904. return *this;
  22905. }
  22906. n = OTL_SCAST(OTL_BIGINT, temp_val);
  22907. return *this;
  22908. }
  22909. #endif
  22910. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  22911. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22912. operator>>(OTL_UBIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  22913. check_if_executed();
  22914. if (eof_intern())
  22915. return *this;
  22916. get_next();
  22917. if (!eof_intern()) {
  22918. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22919. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22920. sl[cur_col].val(cur_row), n);
  22921. #else
  22922. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22923. sl[cur_col].val(cur_row), n);
  22924. #endif
  22925. if (!match_found) {
  22926. if (check_type(otl_var_double, otl_var_int))
  22927. n = OTL_PCONV(OTL_UBIGINT, double, sl[cur_col].val(cur_row));
  22928. }
  22929. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22930. if ((*this).is_null())
  22931. n = OTL_SCAST(OTL_UBIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22932. #endif
  22933. look_ahead();
  22934. }
  22935. inc_next_ov();
  22936. return *this;
  22937. }
  22938. #endif
  22939. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22940. operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION {
  22941. check_if_executed();
  22942. if (eof_intern())
  22943. return *this;
  22944. get_next();
  22945. if (!eof_intern()) {
  22946. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22947. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22948. sl[cur_col].val(cur_row), u);
  22949. #else
  22950. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22951. sl[cur_col].val(cur_row), u);
  22952. #endif
  22953. if (!match_found) {
  22954. if (check_type(otl_var_double, otl_var_unsigned_int))
  22955. u = OTL_PCONV(unsigned, double, sl[cur_col].val(cur_row));
  22956. }
  22957. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22958. if ((*this).is_null())
  22959. u = OTL_SCAST(unsigned int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22960. #endif
  22961. look_ahead();
  22962. }
  22963. inc_next_ov();
  22964. return *this;
  22965. }
  22966. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22967. operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION {
  22968. check_if_executed();
  22969. if (eof_intern())
  22970. return *this;
  22971. get_next();
  22972. if (!eof_intern()) {
  22973. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  22974. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  22975. sl[cur_col].val(cur_row), sh);
  22976. #else
  22977. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  22978. sl[cur_col].val(cur_row), sh);
  22979. #endif
  22980. if (!match_found) {
  22981. if (check_type(otl_var_double, otl_var_short))
  22982. sh = OTL_PCONV(short, double, sl[cur_col].val(cur_row));
  22983. }
  22984. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  22985. if ((*this).is_null())
  22986. sh = OTL_SCAST(short int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  22987. #endif
  22988. look_ahead();
  22989. }
  22990. inc_next_ov();
  22991. return *this;
  22992. }
  22993. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  22994. operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION {
  22995. check_if_executed();
  22996. if (eof_intern())
  22997. return *this;
  22998. get_next();
  22999. if (!eof_intern()) {
  23000. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  23001. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  23002. sl[cur_col].val(cur_row), l);
  23003. #else
  23004. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  23005. sl[cur_col].val(cur_row), l);
  23006. #endif
  23007. if (!match_found) {
  23008. if (check_type(otl_var_double, otl_var_long_int))
  23009. l = OTL_PCONV(long int, double, sl[cur_col].val(cur_row));
  23010. }
  23011. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  23012. if ((*this).is_null())
  23013. l = OTL_SCAST(long int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  23014. #endif
  23015. look_ahead();
  23016. }
  23017. inc_next_ov();
  23018. return *this;
  23019. }
  23020. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  23021. operator>>(float &f) OTL_THROWS_OTL_EXCEPTION {
  23022. check_if_executed();
  23023. if (eof_intern())
  23024. return *this;
  23025. get_next();
  23026. if (!eof_intern()) {
  23027. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  23028. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  23029. sl[cur_col].val(cur_row), f);
  23030. #else
  23031. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  23032. sl[cur_col].val(cur_row), f);
  23033. #endif
  23034. if (!match_found) {
  23035. if (check_type(otl_var_double, otl_var_float))
  23036. f = OTL_PCONV(float, double, sl[cur_col].val(cur_row));
  23037. }
  23038. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  23039. if ((*this).is_null())
  23040. f = OTL_SCAST(float, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  23041. #endif
  23042. look_ahead();
  23043. }
  23044. inc_next_ov();
  23045. return *this;
  23046. }
  23047. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  23048. operator>>(double &d) OTL_THROWS_OTL_EXCEPTION {
  23049. check_if_executed();
  23050. if (eof_intern())
  23051. return *this;
  23052. get_next();
  23053. if (!eof_intern()) {
  23054. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  23055. int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(),
  23056. sl[cur_col].val(cur_row), d);
  23057. #else
  23058. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(),
  23059. sl[cur_col].val(cur_row), d);
  23060. #endif
  23061. if (!match_found) {
  23062. if (check_type(otl_var_double, otl_var_double))
  23063. d = *OTL_RCAST(double *, sl[cur_col].val(cur_row));
  23064. }
  23065. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  23066. if ((*this).is_null())
  23067. d = OTL_SCAST(double, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  23068. #endif
  23069. look_ahead();
  23070. }
  23071. inc_next_ov();
  23072. return *this;
  23073. }
  23074. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  23075. operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION {
  23076. check_if_executed();
  23077. if (eof_intern())
  23078. return *this;
  23079. get_next();
  23080. if (!eof_intern()) {
  23081. switch (sl[cur_col].get_ftype()) {
  23082. case otl_var_raw_long:
  23083. case otl_var_varchar_long: {
  23084. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  23085. if (!s.get_unicode_flag() && in_unicode_mode &&
  23086. sl[cur_col].get_ftype() == otl_var_varchar_long) {
  23087. OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37,
  23088. this->stm_label ? this->stm_label
  23089. : this->stm_text)));
  23090. } else if (s.get_unicode_flag() &&
  23091. sl[cur_col].get_ftype() == otl_var_raw_long) {
  23092. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  23093. this->stm_label ? this->stm_label
  23094. : this->stm_text)));
  23095. }
  23096. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  23097. int len = sl[cur_col].get_len(cur_row);
  23098. if (len > s.get_buf_size())
  23099. len = s.get_buf_size();
  23100. otl_memcpy(s.v, c, len, sl[cur_col].get_ftype());
  23101. if (sl[cur_col].get_ftype() == otl_var_varchar_long)
  23102. s.null_terminate_string(len);
  23103. s.set_len(len);
  23104. look_ahead();
  23105. } break;
  23106. case otl_var_blob:
  23107. case otl_var_clob: {
  23108. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  23109. if (!s.get_unicode_flag() && in_unicode_mode &&
  23110. sl[cur_col].get_ftype() == otl_var_clob) {
  23111. OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37,
  23112. this->stm_label ? this->stm_label
  23113. : this->stm_text)));
  23114. } else if (s.get_unicode_flag() &&
  23115. sl[cur_col].get_ftype() == otl_var_blob) {
  23116. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  23117. this->stm_label ? this->stm_label
  23118. : this->stm_text)));
  23119. }
  23120. int len;
  23121. int rc = sl[cur_col].get_var_struct().get_blob(cur_row, s.v,
  23122. s.get_buf_size(), len);
  23123. if (rc == 0) {
  23124. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  23125. OTL_THROW((otl_exception(adb->get_connect_struct(),
  23126. stm_label ? stm_label : stm_text)));
  23127. }
  23128. s.set_len(len);
  23129. if (sl[cur_col].get_ftype() == otl_var_clob)
  23130. s.null_terminate_string(len);
  23131. look_ahead();
  23132. } break;
  23133. case otl_var_raw: {
  23134. if (s.get_unicode_flag()) {
  23135. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  23136. this->stm_label ? this->stm_label
  23137. : this->stm_text)));
  23138. }
  23139. unsigned char *c =
  23140. OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row));
  23141. int len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c));
  23142. otl_memcpy(s.v, c + sizeof(short int), len2, sl[cur_col].get_ftype());
  23143. s.set_len(len2);
  23144. look_ahead();
  23145. } break;
  23146. }
  23147. }
  23148. inc_next_ov();
  23149. return *this;
  23150. }
  23151. OTL_ORA_REFCUR_COMMON_READ_STREAM &
  23152. operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION {
  23153. check_if_executed();
  23154. if (eof_intern())
  23155. return *this;
  23156. get_next();
  23157. if ((sl[cur_col].get_ftype() == otl_var_blob ||
  23158. sl[cur_col].get_ftype() == otl_var_clob) &&
  23159. !eof_intern()) {
  23160. s.init(&sl[cur_col], adb, OTL_SCAST(otl_refcur_base_cursor *, this),
  23161. cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null());
  23162. delay_next = 1;
  23163. }
  23164. inc_next_ov();
  23165. return *this;
  23166. }
  23167. otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW {
  23168. desc_len = 0;
  23169. if (ov == nullptr)
  23170. return nullptr;
  23171. desc_len = ov_len;
  23172. return ov;
  23173. }
  23174. otl_var_desc *describe_next_out_var(void) OTL_NO_THROW {
  23175. if (ov == nullptr)
  23176. return nullptr;
  23177. return &ov[next_ov_ndx];
  23178. }
  23179. int select_list_len(void) OTL_NO_THROW { return sl_len; }
  23180. int column_ftype(int ndx = 0) OTL_NO_THROW { return sl[ndx].get_ftype(); }
  23181. int column_size(int ndx = 0) OTL_NO_THROW { return sl[ndx].get_elem_size(); }
  23182. otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW {
  23183. desc_len = 0;
  23184. desc_len = sl_len;
  23185. return sl_desc;
  23186. }
  23187. protected:
  23188. otl_column_desc *sl_desc;
  23189. int sl_len;
  23190. otl_generic_variable *sl;
  23191. int null_fetched;
  23192. int ret_code;
  23193. int cur_col;
  23194. int cur_in;
  23195. int executed;
  23196. char var_info[256];
  23197. void init(void) {
  23198. ov = nullptr;
  23199. ov_len = 0;
  23200. next_ov_ndx = 0;
  23201. same_sl_flag = 0;
  23202. sl = nullptr;
  23203. sl_len = 0;
  23204. null_fetched = 0;
  23205. ret_code = 0;
  23206. sl_desc = nullptr;
  23207. executed = 0;
  23208. cur_in = 0;
  23209. cur_col = -1;
  23210. executed = 1;
  23211. stm_text = nullptr;
  23212. delay_next = 0;
  23213. }
  23214. void get_next(void) {
  23215. if (cur_col < sl_len - 1) {
  23216. ++cur_col;
  23217. null_fetched = sl[cur_col].is_null(cur_row);
  23218. } else {
  23219. ret_code = next();
  23220. cur_col = 0;
  23221. }
  23222. }
  23223. OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) {
  23224. int out_type_code;
  23225. if (actual_data_type != 0)
  23226. out_type_code = actual_data_type;
  23227. else
  23228. out_type_code = type_code;
  23229. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  23230. out_type_code, var_info, sizeof(var_info));
  23231. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  23232. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  23233. stm_label ? stm_label : stm_text, var_info)));
  23234. }
  23235. OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) {
  23236. switch (sl[cur_col].get_ftype()) {
  23237. case otl_var_timestamp:
  23238. case otl_var_tz_timestamp:
  23239. case otl_var_ltz_timestamp:
  23240. if (type_code == otl_var_timestamp)
  23241. return 1;
  23242. break;
  23243. default:
  23244. #if defined(OTL_CHECK_OUT_TYPE_FUNC)
  23245. if ((sl[cur_col].get_ftype() == type_code) ||
  23246. OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code))
  23247. return 1;
  23248. break;
  23249. #else
  23250. if (sl[cur_col].get_ftype() == type_code)
  23251. return 1;
  23252. break;
  23253. #endif
  23254. }
  23255. return check_type_throw(type_code, actual_data_type);
  23256. }
  23257. void look_ahead(void) {
  23258. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  23259. #else
  23260. if (cur_col == sl_len - 1) {
  23261. ret_code = next();
  23262. cur_col = -1;
  23263. }
  23264. #endif
  23265. }
  23266. void get_select_list(void) {
  23267. int i, j;
  23268. otl_auto_array_ptr<otl_column_desc> loc_ptr(otl_var_list_size);
  23269. otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr();
  23270. int sld_tmp_len = 0;
  23271. int ftype, elem_size;
  23272. sld_tmp_len = 0;
  23273. cursor_struct.straight_select = 0;
  23274. for (i = 1; describe_column(sl_desc_tmp[i - 1], i); ++i) {
  23275. ++sld_tmp_len;
  23276. if (sld_tmp_len == loc_ptr.get_arr_size()) {
  23277. loc_ptr.double_size();
  23278. sl_desc_tmp = loc_ptr.get_ptr();
  23279. }
  23280. }
  23281. sl_len = sld_tmp_len;
  23282. if (sl) {
  23283. delete[] sl;
  23284. sl = nullptr;
  23285. }
  23286. sl = new otl_generic_variable[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  23287. int max_long_size = this->adb->get_max_long_size();
  23288. for (j = 0; j < sl_len; ++j) {
  23289. otl_generic_variable::map_ftype(
  23290. sl_desc_tmp[j], max_long_size, ftype, elem_size, override_, j + 1,
  23291. this->adb->get_connect_struct().get_connection_type());
  23292. sl[j].copy_pos(j + 1);
  23293. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  23294. if (sl_desc_tmp[j].charset_form == 2)
  23295. sl[j].get_var_struct().nls_flag = true;
  23296. #endif
  23297. sl[j].init(true, ftype, elem_size,
  23298. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  23299. &adb->get_connect_struct());
  23300. }
  23301. if (sl_desc) {
  23302. delete[] sl_desc;
  23303. sl_desc = nullptr;
  23304. }
  23305. sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  23306. for (i = 0; i < sl_len; ++i)
  23307. sl_desc[i] = sl_desc_tmp[i];
  23308. for (i = 0; i < sl_len; ++i)
  23309. bind_col(i + 1, sl[i]);
  23310. }
  23311. private:
  23312. void rewind(void) OTL_THROWS_OTL_EXCEPTION {
  23313. ret_code = first();
  23314. null_fetched = 0;
  23315. cur_col = -1;
  23316. cur_in = 0;
  23317. executed = 1;
  23318. delay_next = 0;
  23319. }
  23320. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  23321. public:
  23322. otl_refcur_stream &operator=(const otl_refcur_stream &) = delete;
  23323. otl_refcur_stream(const otl_refcur_stream &) = delete;
  23324. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23325. otl_refcur_stream &operator=(otl_refcur_stream &&) = delete;
  23326. otl_refcur_stream(otl_refcur_stream &&) = delete;
  23327. #endif
  23328. private:
  23329. #else
  23330. otl_refcur_stream &operator=(const otl_refcur_stream &) { return *this; }
  23331. otl_refcur_stream(const otl_refcur_stream &)
  23332. :
  23333. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  23334. otl_read_stream_interface(),
  23335. #endif
  23336. otl_refcur_base_cursor(), delay_next(0), same_sl_flag(0), override_(),
  23337. ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(),
  23338. sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0),
  23339. executed(0), var_info() {
  23340. }
  23341. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23342. otl_refcur_stream &operator=(otl_refcur_stream &&) { return *this; }
  23343. otl_refcur_stream(otl_refcur_stream &&)
  23344. :
  23345. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  23346. otl_read_stream_interface(),
  23347. #endif
  23348. otl_refcur_base_cursor(), delay_next(0), same_sl_flag(0), override_(),
  23349. ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(),
  23350. sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0),
  23351. executed(0), var_info() {
  23352. }
  23353. #endif
  23354. #endif
  23355. };
  23356. class otl_inout_stream : public otl_ora8_inout_stream {
  23357. public:
  23358. otl_inout_stream(otl_stream_buffer_size_type arr_size, const char *sqlstm,
  23359. otl_connect &db, void *master_stream_ptr,
  23360. const bool alob_stream_mode = false,
  23361. const char *sqlstm_label = nullptr)
  23362. : otl_ora8_inout_stream(arr_size, sqlstm, db, master_stream_ptr,
  23363. alob_stream_mode, sqlstm_label),
  23364. adb2(&db) {}
  23365. otl_inout_stream &operator>>(otl_refcur_stream &str) {
  23366. if (eof())
  23367. return *this;
  23368. if (check_in_type(otl_var_refcur, 1)) {
  23369. if (str.get_connected())
  23370. str.close();
  23371. str.open(*adb2, &(in_vl[cur_in_x]->get_var_struct()), stm_text,
  23372. OTL_SCAST(/*const*/ otl_stream_buffer_size_type,
  23373. in_vl[cur_in_x]->get_var_struct().array_size));
  23374. null_fetched = 0;
  23375. }
  23376. get_in_next();
  23377. return *this;
  23378. }
  23379. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  23380. otl_inout_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) {
  23381. otl_ora8_inout_stream::operator<<(s);
  23382. return *this;
  23383. }
  23384. #endif
  23385. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  23386. otl_inout_stream &operator>>(OTL_STRING_CONTAINER &s) {
  23387. otl_ora8_inout_stream::operator>>(s);
  23388. return *this;
  23389. }
  23390. otl_inout_stream &operator<<(const OTL_STRING_CONTAINER &s) {
  23391. otl_ora8_inout_stream::operator<<(s);
  23392. return *this;
  23393. }
  23394. #endif
  23395. otl_inout_stream &operator<<(const otl_null &n) {
  23396. otl_ora8_inout_stream::operator<<(n);
  23397. return *this;
  23398. }
  23399. #if defined(OTL_PL_TAB) && defined(OTL_STL)
  23400. otl_inout_stream &operator>>(otl_pl_vec_generic &tab) {
  23401. otl_ora8_inout_stream::operator>>(tab);
  23402. return *this;
  23403. }
  23404. otl_inout_stream &operator<<(otl_pl_vec_generic &tab) {
  23405. otl_ora8_inout_stream::operator<<(tab);
  23406. return *this;
  23407. }
  23408. #endif
  23409. otl_inout_stream &operator>>(otl_pl_tab_generic &tab) {
  23410. otl_ora8_inout_stream::operator>>(tab);
  23411. return *this;
  23412. }
  23413. otl_inout_stream &operator<<(otl_pl_tab_generic &tab) {
  23414. otl_ora8_inout_stream::operator<<(tab);
  23415. return *this;
  23416. }
  23417. otl_inout_stream &operator>>(otl_time0 &s) {
  23418. otl_ora8_inout_stream::operator>>(s);
  23419. return *this;
  23420. }
  23421. otl_inout_stream &operator<<(const otl_time0 &s) {
  23422. otl_ora8_inout_stream::operator<<(s);
  23423. return *this;
  23424. }
  23425. otl_inout_stream &operator>>(char &c) {
  23426. otl_ora8_inout_stream::operator>>(c);
  23427. return *this;
  23428. }
  23429. otl_inout_stream &operator<<(const char c) {
  23430. otl_ora8_inout_stream::operator<<(c);
  23431. return *this;
  23432. }
  23433. otl_inout_stream &operator>>(unsigned char &c) {
  23434. otl_ora8_inout_stream::operator>>(c);
  23435. return *this;
  23436. }
  23437. #if defined(OTL_UNICODE_STRING_TYPE)
  23438. otl_inout_stream &operator>>(OTL_UNICODE_STRING_TYPE &s) {
  23439. otl_ora8_inout_stream::operator>>(s);
  23440. return *this;
  23441. }
  23442. otl_inout_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) {
  23443. otl_ora8_inout_stream::operator<<(s);
  23444. return *this;
  23445. }
  23446. #endif
  23447. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  23448. otl_inout_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) {
  23449. otl_ora8_inout_stream::operator<<(s);
  23450. return *this;
  23451. }
  23452. #endif
  23453. otl_inout_stream &operator<<(const unsigned char c) {
  23454. otl_ora8_inout_stream::operator<<(c);
  23455. return *this;
  23456. }
  23457. otl_inout_stream &operator>>(char *s) {
  23458. otl_ora8_inout_stream::operator>>(s);
  23459. return *this;
  23460. }
  23461. otl_inout_stream &operator<<(const char *s) {
  23462. otl_ora8_inout_stream::operator<<(s);
  23463. return *this;
  23464. }
  23465. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  23466. template<const size_t N>
  23467. otl_inout_stream &operator>>(std::array<char,N>& s) {
  23468. otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size()));
  23469. return *this;
  23470. }
  23471. template<const size_t N>
  23472. otl_inout_stream &operator<<(const std::array<char,N>& s) {
  23473. otl_ora8_inout_stream::operator<<(s);
  23474. return *this;
  23475. }
  23476. #endif
  23477. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  23478. template<const size_t N>
  23479. otl_inout_stream &operator>>(std::array<char16_t,N>& s) {
  23480. otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size()));
  23481. return *this;
  23482. }
  23483. template<const size_t N>
  23484. otl_inout_stream &operator<<(const std::array<char16_t,N>& s) {
  23485. otl_ora8_inout_stream::operator<<(s);
  23486. return *this;
  23487. }
  23488. #endif
  23489. otl_inout_stream &operator>>(unsigned char *s) {
  23490. otl_ora8_inout_stream::operator>>(s);
  23491. return *this;
  23492. }
  23493. otl_inout_stream &operator<<(const unsigned char *s) {
  23494. otl_ora8_inout_stream::operator<<(s);
  23495. return *this;
  23496. }
  23497. #if defined(OTL_BIGINT) && \
  23498. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  23499. !defined(OTL_BIGINT_TO_STR))
  23500. otl_inout_stream &operator>>(OTL_BIGINT &n) {
  23501. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23502. otl_ora8_inout_stream::operator>>(n);
  23503. #else
  23504. otl_ora8_inout_stream::operator>><OTL_BIGINT, otl_var_bigint>(n);
  23505. #endif
  23506. return *this;
  23507. }
  23508. #endif
  23509. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  23510. otl_inout_stream &operator>>(OTL_UBIGINT &n) {
  23511. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23512. otl_ora8_inout_stream::operator>>(n);
  23513. #else
  23514. otl_ora8_inout_stream::operator>><OTL_UBIGINT, otl_var_ubigint>(n);
  23515. #endif
  23516. return *this;
  23517. }
  23518. #endif
  23519. otl_inout_stream &operator>>(int &n) {
  23520. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23521. otl_ora8_inout_stream::operator>>(n);
  23522. #else
  23523. otl_ora8_inout_stream::operator>><int, otl_var_int>(n);
  23524. #endif
  23525. return *this;
  23526. }
  23527. #if defined(OTL_BIGINT) && \
  23528. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  23529. !defined(OTL_BIGINT_TO_STR))
  23530. otl_inout_stream &operator<<(const OTL_BIGINT n) {
  23531. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23532. otl_ora8_inout_stream::operator<<(n);
  23533. #else
  23534. otl_ora8_inout_stream::operator<<<OTL_BIGINT, otl_var_bigint>(n);
  23535. #endif
  23536. return *this;
  23537. }
  23538. #endif
  23539. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  23540. otl_inout_stream &operator<<(const OTL_UBIGINT n) {
  23541. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23542. otl_ora8_inout_stream::operator<<(n);
  23543. #else
  23544. otl_ora8_inout_stream::operator<<<OTL_UBIGINT, otl_var_ubigint>(n);
  23545. #endif
  23546. return *this;
  23547. }
  23548. #endif
  23549. otl_inout_stream &operator<<(const int n) {
  23550. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23551. otl_ora8_inout_stream::operator<<(n);
  23552. #else
  23553. otl_ora8_inout_stream::operator<<<int, otl_var_int>(n);
  23554. #endif
  23555. return *this;
  23556. }
  23557. otl_inout_stream &operator>>(float &n) {
  23558. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23559. otl_ora8_inout_stream::operator>>(n);
  23560. #else
  23561. otl_ora8_inout_stream::operator>><float, otl_var_float>(n);
  23562. #endif
  23563. return *this;
  23564. }
  23565. otl_inout_stream &operator<<(const float n) {
  23566. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23567. otl_ora8_inout_stream::operator<<(n);
  23568. #else
  23569. otl_ora8_inout_stream::operator<<<float, otl_var_float>(n);
  23570. #endif
  23571. return *this;
  23572. }
  23573. otl_inout_stream &operator>>(double &n) {
  23574. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23575. otl_ora8_inout_stream::operator>>(n);
  23576. #else
  23577. otl_ora8_inout_stream::operator>><double, otl_var_double>(n);
  23578. #endif
  23579. return *this;
  23580. }
  23581. otl_inout_stream &operator<<(const double n) {
  23582. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23583. otl_ora8_inout_stream::operator<<(n);
  23584. #else
  23585. otl_ora8_inout_stream::operator<<<double, otl_var_double>(n);
  23586. #endif
  23587. return *this;
  23588. }
  23589. otl_inout_stream &operator>>(short int &n) {
  23590. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23591. otl_ora8_inout_stream::operator>>(n);
  23592. #else
  23593. otl_ora8_inout_stream::operator>><short, otl_var_short>(n);
  23594. #endif
  23595. return *this;
  23596. }
  23597. otl_inout_stream &operator<<(const short int n) {
  23598. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23599. otl_ora8_inout_stream::operator<<(n);
  23600. #else
  23601. otl_ora8_inout_stream::operator<<<short, otl_var_short>(n);
  23602. #endif
  23603. return *this;
  23604. }
  23605. otl_inout_stream &operator>>(unsigned int &n) {
  23606. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23607. otl_ora8_inout_stream::operator>>(n);
  23608. #else
  23609. otl_ora8_inout_stream::operator>><unsigned, otl_var_unsigned_int>(n);
  23610. #endif
  23611. return *this;
  23612. }
  23613. otl_inout_stream &operator<<(const unsigned int n) {
  23614. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23615. otl_ora8_inout_stream::operator<<(n);
  23616. #else
  23617. otl_ora8_inout_stream::operator<<<unsigned, otl_var_unsigned_int>(n);
  23618. #endif
  23619. return *this;
  23620. }
  23621. otl_inout_stream &operator>>(long int &n) {
  23622. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23623. otl_ora8_inout_stream::operator>>(n);
  23624. #else
  23625. otl_ora8_inout_stream::operator>><long, otl_var_long_int>(n);
  23626. #endif
  23627. return *this;
  23628. }
  23629. otl_inout_stream &operator<<(const long int n) {
  23630. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  23631. otl_ora8_inout_stream::operator<<(n);
  23632. #else
  23633. otl_ora8_inout_stream::operator<<<long, otl_var_long_int>(n);
  23634. #endif
  23635. return *this;
  23636. }
  23637. otl_inout_stream &operator>>(otl_long_string &n) {
  23638. otl_ora8_inout_stream::operator>>(n);
  23639. return *this;
  23640. }
  23641. otl_inout_stream &operator<<(const otl_long_string &n) {
  23642. otl_ora8_inout_stream::operator<<(n);
  23643. return *this;
  23644. }
  23645. otl_inout_stream &operator>>(otl_lob_stream &n) {
  23646. otl_ora8_inout_stream::operator>>(n);
  23647. return *this;
  23648. }
  23649. otl_inout_stream &operator<<(otl_lob_stream &s) {
  23650. otl_ora8_inout_stream::operator<<(s);
  23651. return *this;
  23652. }
  23653. #if defined(OTL_ORA_SDO_GEOMETRY)
  23654. otl_inout_stream &operator >> (oci_spatial_geometry &n){
  23655. otl_ora8_inout_stream::operator >> (n);
  23656. return *this;
  23657. }
  23658. otl_inout_stream &operator<<(const oci_spatial_geometry &s){
  23659. otl_ora8_inout_stream::operator<< (s);
  23660. return *this;
  23661. }
  23662. #endif
  23663. protected:
  23664. otl_connect *adb2;
  23665. private:
  23666. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  23667. public:
  23668. otl_inout_stream(const otl_inout_stream &) = delete;
  23669. otl_inout_stream &operator=(const otl_inout_stream &) = delete;
  23670. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23671. otl_inout_stream(otl_inout_stream &&) = delete;
  23672. otl_inout_stream &operator=(otl_inout_stream &&) = delete;
  23673. #endif
  23674. private:
  23675. #else
  23676. otl_inout_stream(const otl_inout_stream &)
  23677. : otl_ora8_inout_stream(), adb2(nullptr) {}
  23678. otl_inout_stream &operator=(const otl_inout_stream &) { return *this; }
  23679. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23680. otl_inout_stream(otl_inout_stream &&)
  23681. : otl_ora8_inout_stream(), adb2(nullptr) {}
  23682. otl_inout_stream &operator=(otl_inout_stream &&) { return *this; }
  23683. #endif
  23684. #endif
  23685. };
  23686. // ============ OTL Reference Cursor Streams for Oracle 8 =================
  23687. class otl_cur;
  23688. class otl_ref_cursor
  23689. : public otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> {
  23690. protected:
  23691. friend class otl_cur;
  23692. int cur_row;
  23693. int cur_size;
  23694. int row_count;
  23695. int array_size;
  23696. otl_select_struct_override local_override;
  23697. public:
  23698. otl_ref_cursor(otl_connect &db, const char *cur_placeholder_name,
  23699. void *master_stream_ptr,
  23700. const otl_stream_buffer_size_type arr_size = 1)
  23701. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(db), cur_row(-1),
  23702. cur_size(0), row_count(0), array_size(arr_size), local_override(),
  23703. sel_cur(), rvl_len(otl_var_list_size),
  23704. rvl(new otl_p_generic_variable[OTL_SCAST(size_t,rvl_len)]), vl_cur_len(0),
  23705. cur_placeholder(), master_stream_ptr_(master_stream_ptr) {
  23706. int i;
  23707. local_override.reset();
  23708. for (i = 0; i < rvl_len; ++i)
  23709. rvl[i] = nullptr;
  23710. OTL_STRCPY_S(cur_placeholder, sizeof(cur_placeholder),
  23711. cur_placeholder_name);
  23712. }
  23713. otl_ref_cursor()
  23714. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  23715. cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(),
  23716. rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(),
  23717. master_stream_ptr_(nullptr) {
  23718. local_override.reset();
  23719. }
  23720. virtual ~otl_ref_cursor() {
  23721. delete[] rvl;
  23722. rvl = nullptr;
  23723. }
  23724. void open(otl_connect &db, const char *cur_placeholder_name,
  23725. const otl_stream_buffer_size_type arr_size = 1) {
  23726. int i;
  23727. local_override.reset();
  23728. cur_row = -1;
  23729. row_count = 0;
  23730. cur_size = 0;
  23731. array_size = arr_size;
  23732. rvl_len = otl_var_list_size;
  23733. vl_cur_len = 0;
  23734. rvl = new otl_p_generic_variable[OTL_SCAST(size_t,rvl_len)];
  23735. for (i = 0; i < rvl_len; ++i)
  23736. rvl[i] = nullptr;
  23737. OTL_STRCPY_S(cur_placeholder, sizeof(cur_placeholder),
  23738. cur_placeholder_name);
  23739. if (!sel_cur.get_connected())
  23740. sel_cur.open(db);
  23741. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::open(db);
  23742. }
  23743. void release_sel_cur(void) {
  23744. #if defined(OTL_ORA8_8I_REFCUR)
  23745. return;
  23746. #else
  23747. char tmp_buf[256];
  23748. OCIBind *bindpp;
  23749. int rc;
  23750. if (!sel_cur.get_connected())
  23751. return;
  23752. OTL_STRCPY_S(tmp_buf, sizeof(tmp_buf), "begin close ");
  23753. OTL_STRCAT_S(tmp_buf, sizeof(tmp_buf), cur_placeholder);
  23754. OTL_STRCAT_S(tmp_buf, sizeof(tmp_buf), "; end;");
  23755. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::parse(tmp_buf);
  23756. rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp,
  23757. OTL_RCAST(text *, cur_placeholder),
  23758. OTL_SCAST(sb4, strlen(cur_placeholder)),
  23759. OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda), 0,
  23760. SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr,
  23761. OTL_SCAST(ub4, OCI_DEFAULT));
  23762. if (rc != 0) {
  23763. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  23764. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  23765. }
  23766. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::exec(
  23767. 1, 0, otl_sql_exec_from_select_cursor_class);
  23768. #endif
  23769. }
  23770. void close(const char = 'N') {
  23771. local_override.reset();
  23772. delete[] rvl;
  23773. rvl = nullptr;
  23774. release_sel_cur();
  23775. sel_cur.close('Y');
  23776. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::close();
  23777. }
  23778. OTL_NODISCARD int first(void) {
  23779. int i, rc;
  23780. OCIBind *bindpp;
  23781. if (!sel_cur.get_connected()) {
  23782. sel_cur.open(*adb);
  23783. rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp,
  23784. OTL_RCAST(text *, cur_placeholder),
  23785. OTL_SCAST(sb4, strlen(cur_placeholder)),
  23786. OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda),
  23787. 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr,
  23788. OTL_SCAST(ub4, OCI_DEFAULT));
  23789. if (rc != 0) {
  23790. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  23791. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  23792. }
  23793. }
  23794. if (cur_row == -2)
  23795. ; // Special case -- calling describe_select() between parse() and first()
  23796. else {
  23797. // Executing the PLSQL master block
  23798. exec(1, 0, otl_sql_exec_from_select_cursor_class);
  23799. sel_cur.set_connected(1);
  23800. }
  23801. cur_row = -1;
  23802. for (i = 0; i < vl_cur_len; ++i)
  23803. sel_cur.bind(i + 1, *rvl[i]);
  23804. rc = sel_cur.get_cursor_struct().fetch(
  23805. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  23806. sel_cur.get_eof_data_ref());
  23807. if (rc == 0) {
  23808. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  23809. OTL_THROW((otl_exception(sel_cur.get_cursor_struct(),
  23810. stm_label ? stm_label : stm_text)));
  23811. }
  23812. row_count = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc());
  23813. OTL_TRACE_FIRST_FETCH
  23814. cur_size = row_count;
  23815. if (cur_size != 0)
  23816. cur_row = 0;
  23817. return cur_size != 0;
  23818. }
  23819. OTL_NODISCARD int next(void) {
  23820. int rc;
  23821. if (cur_row < 0)
  23822. return first();
  23823. if (cur_row < cur_size - 1)
  23824. ++cur_row;
  23825. else {
  23826. if (sel_cur.eof()) {
  23827. cur_row = -1;
  23828. return 0;
  23829. }
  23830. rc = sel_cur.get_cursor_struct().fetch(
  23831. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  23832. sel_cur.get_eof_data_ref());
  23833. if (rc == 0) {
  23834. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  23835. OTL_THROW((otl_exception(sel_cur.get_cursor_struct(),
  23836. stm_label ? stm_label : stm_text)));
  23837. }
  23838. cur_size = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc()) - row_count;
  23839. row_count = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc());
  23840. OTL_TRACE_NEXT_FETCH2
  23841. if (cur_size != 0)
  23842. cur_row = 0;
  23843. }
  23844. return cur_size != 0;
  23845. }
  23846. void bind(const int column_num, otl_generic_variable &v) {
  23847. if (!connected)
  23848. return;
  23849. ++vl_cur_len;
  23850. if (vl_cur_len == rvl_len) {
  23851. int temp_rvl_len = rvl_len * 2;
  23852. otl_p_generic_variable *temp_rvl =
  23853. new otl_p_generic_variable[OTL_SCAST(size_t,temp_rvl_len)];
  23854. int i;
  23855. for (i = 0; i < rvl_len; ++i)
  23856. temp_rvl[i] = rvl[i];
  23857. for (i = rvl_len + 1; i < temp_rvl_len; ++i)
  23858. temp_rvl[i] = nullptr;
  23859. delete[] rvl;
  23860. rvl = temp_rvl;
  23861. rvl_len = temp_rvl_len;
  23862. }
  23863. rvl[vl_cur_len - 1] = &v;
  23864. v.set_pos(column_num);
  23865. }
  23866. void bind(otl_generic_variable &v) {
  23867. if (v.get_pos())
  23868. bind(v.get_pos(), v);
  23869. else if (v.get_name())
  23870. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::bind(v);
  23871. }
  23872. void bind(const char *name, otl_generic_variable &v) {
  23873. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::bind(name, v);
  23874. }
  23875. OTL_NODISCARD int describe_select(otl_column_desc *desc, int &desc_len) {
  23876. int i, rc;
  23877. OCIBind *bindpp;
  23878. if (!sel_cur.get_connected()) {
  23879. sel_cur.open(*adb);
  23880. rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp,
  23881. OTL_RCAST(text *, cur_placeholder),
  23882. OTL_SCAST(sb4, strlen(cur_placeholder)),
  23883. OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda),
  23884. 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr,
  23885. OTL_SCAST(ub4, OCI_DEFAULT));
  23886. if (rc != 0) {
  23887. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  23888. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  23889. }
  23890. }
  23891. // Executing the PLSQL master block
  23892. exec(1, 0, otl_sql_exec_from_select_cursor_class);
  23893. sel_cur.set_connected(1);
  23894. cur_row = -2; // Special case -- describe_select() before first() or next()
  23895. desc_len = 0;
  23896. sel_cur.get_cursor_struct().straight_select = 0;
  23897. for (i = 1; sel_cur.describe_column(desc[i - 1], i); ++i)
  23898. ++desc_len;
  23899. return 1;
  23900. }
  23901. public:
  23902. otl_cursor sel_cur;
  23903. protected:
  23904. int rvl_len;
  23905. otl_p_generic_variable *rvl;
  23906. int vl_cur_len;
  23907. char cur_placeholder[64];
  23908. void *master_stream_ptr_;
  23909. private:
  23910. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  23911. public:
  23912. otl_ref_cursor(const otl_ref_cursor &) = delete;
  23913. otl_ref_cursor &operator=(const otl_ref_cursor &) = delete;
  23914. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23915. otl_ref_cursor(otl_ref_cursor &&) = delete;
  23916. otl_ref_cursor &operator=(otl_ref_cursor &&) = delete;
  23917. #endif
  23918. private:
  23919. #else
  23920. otl_ref_cursor(const otl_ref_cursor &)
  23921. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  23922. cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(),
  23923. rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(),
  23924. master_stream_ptr_(nullptr) {}
  23925. otl_ref_cursor &operator=(const otl_ref_cursor &) { return *this; }
  23926. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  23927. otl_ref_cursor(otl_ref_cursor &&)
  23928. : otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>(), cur_row(-1),
  23929. cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(),
  23930. rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(),
  23931. master_stream_ptr_(nullptr) {}
  23932. otl_ref_cursor &operator=(otl_ref_cursor &&) { return *this; }
  23933. #endif
  23934. #endif
  23935. };
  23936. class otl_ref_select_stream : public otl_ref_cursor {
  23937. protected:
  23938. otl_select_struct_override *override_;
  23939. int delay_next;
  23940. int same_sl_flag;
  23941. long _rfc;
  23942. public:
  23943. void skip_to_end_of_row() {
  23944. check_if_executed();
  23945. if (eof())
  23946. return;
  23947. while (cur_col < sl_len - 1) {
  23948. ++cur_col;
  23949. null_fetched = sl[cur_col].is_null(this->cur_row);
  23950. }
  23951. ret_code = this->next();
  23952. cur_col = 0;
  23953. if (!eof())
  23954. cur_col = -1;
  23955. ++_rfc;
  23956. }
  23957. void skip_to_next_var() {
  23958. check_if_executed();
  23959. if (eof_intern())
  23960. return;
  23961. get_next();
  23962. look_ahead();
  23963. }
  23964. OTL_NODISCARD int get_select_row_count() const {
  23965. return this->cur_row == -1 ? 0 : this->cur_size - this->cur_row;
  23966. }
  23967. OTL_NODISCARD int get_prefetched_row_count() const { return this->row_count; }
  23968. OTL_NODISCARD long get_rfc() const { return _rfc; }
  23969. void cleanup(void) {
  23970. int i;
  23971. delete[] sl;
  23972. for (i = 0; i < vl_len; ++i)
  23973. delete vl[i];
  23974. delete[] vl;
  23975. delete[] sl_desc;
  23976. }
  23977. otl_ref_select_stream(otl_select_struct_override *aoverride,
  23978. const otl_stream_buffer_size_type arr_size,
  23979. const char *sqlstm, const char *acur_placeholder,
  23980. otl_connect &db, const char *sqlstm_label = nullptr)
  23981. : otl_ref_cursor(db, acur_placeholder, aoverride->get_master_stream_ptr(),
  23982. arr_size),
  23983. override_(nullptr), delay_next(0), same_sl_flag(0), _rfc(0),
  23984. sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0), ret_code(0),
  23985. cur_col(0), cur_in(0), executed(0), var_info() {
  23986. if (sqlstm_label != nullptr) {
  23987. if (stm_label != nullptr) {
  23988. delete[] stm_label;
  23989. stm_label = nullptr;
  23990. }
  23991. size_t len = strlen(sqlstm_label) + 1;
  23992. stm_label = new char[len];
  23993. OTL_STRCPY_S(stm_label, len, sqlstm_label);
  23994. }
  23995. init();
  23996. override_ = aoverride;
  23997. {
  23998. size_t len = strlen(sqlstm) + 1;
  23999. stm_text = new char[len];
  24000. OTL_STRCPY_S(stm_text, len, sqlstm);
  24001. otl_select_struct_override *temp_local_override = &this->local_override;
  24002. otl_ext_hv_decl hvd(this->stm_text, 1, this->stm_label,
  24003. &temp_local_override, adb);
  24004. hvd.alloc_host_var_list(vl, vl_len, *adb);
  24005. if (temp_local_override != &this->local_override)
  24006. delete temp_local_override;
  24007. }
  24008. try {
  24009. parse();
  24010. if (vl_len == 0) {
  24011. rewind();
  24012. null_fetched = 0;
  24013. }
  24014. }
  24015. catch (OTL_CONST_EXCEPTION otl_exception &) {
  24016. cleanup();
  24017. throw;
  24018. }
  24019. }
  24020. virtual ~otl_ref_select_stream() OTL_THROWS_OTL_EXCEPTION {
  24021. cleanup();
  24022. close();
  24023. }
  24024. void rewind(void) {
  24025. OTL_TRACE_STREAM_EXECUTION
  24026. _rfc = 0;
  24027. get_select_list();
  24028. ret_code = first();
  24029. null_fetched = 0;
  24030. cur_col = -1;
  24031. cur_in = 0;
  24032. executed = 1;
  24033. delay_next = 0;
  24034. }
  24035. void clean(void) {
  24036. _rfc = 0;
  24037. null_fetched = 0;
  24038. cur_col = -1;
  24039. cur_in = 0;
  24040. executed = 0;
  24041. delay_next = 0;
  24042. }
  24043. OTL_NODISCARD int is_null(void) { return null_fetched; }
  24044. OTL_NODISCARD int eof(void) {
  24045. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  24046. if (cur_col == sl_len - 1) {
  24047. get_next();
  24048. cur_col = -1;
  24049. } else {
  24050. if (delay_next) {
  24051. look_ahead();
  24052. delay_next = 0;
  24053. }
  24054. }
  24055. return !ret_code;
  24056. #else
  24057. if (delay_next) {
  24058. look_ahead();
  24059. delay_next = 0;
  24060. }
  24061. return !ret_code;
  24062. #endif
  24063. }
  24064. OTL_NODISCARD int eof_intern(void) { return !ret_code; }
  24065. otl_ref_select_stream &operator>>(otl_time0 &t) {
  24066. check_if_executed();
  24067. if (eof_intern())
  24068. return *this;
  24069. get_next();
  24070. if (check_type(otl_var_timestamp) && !eof_intern()) {
  24071. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  24072. void *tm = OTL_RCAST(void *, sl[cur_col].val(this->cur_row));
  24073. int rc = sl[cur_col].get_var_struct().read_dt(&t, tm, sizeof(otl_time0));
  24074. if (rc == 0) {
  24075. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24076. OTL_THROW((otl_exception(adb->get_connect_struct(),
  24077. stm_label ? stm_label : stm_text)));
  24078. }
  24079. #else
  24080. otl_time0 *tm = OTL_RCAST(otl_time0 *, sl[cur_col].val(cur_row));
  24081. memcpy(OTL_RCAST(void *, &t), tm, otl_oracle_date_size);
  24082. #endif
  24083. look_ahead();
  24084. }
  24085. return *this;
  24086. }
  24087. otl_ref_select_stream &operator<<(const otl_time0 &t) {
  24088. check_in_var();
  24089. if (check_in_type(otl_var_timestamp, otl_oracle_date_size)) {
  24090. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  24091. void *tm = OTL_RCAST(void *, vl[cur_in]->val());
  24092. int rc = vl[cur_in]->get_var_struct().write_dt(tm, &t, sizeof(otl_time0));
  24093. if (rc == 0) {
  24094. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24095. OTL_THROW((otl_exception(adb->get_connect_struct(),
  24096. stm_label ? stm_label : stm_text)));
  24097. }
  24098. #else
  24099. otl_time0 *tm = OTL_RCAST(otl_time0 *, vl[cur_in]->val());
  24100. otl_time0 *tp = OTL_CCAST(otl_time0 *, &t);
  24101. *tm=*tp;
  24102. #endif
  24103. }
  24104. this->vl[cur_in]->set_not_null(0);
  24105. get_in_next();
  24106. return *this;
  24107. }
  24108. otl_ref_select_stream &operator<<(const otl_long_string &s) {
  24109. if (s.get_unicode_flag()) {
  24110. OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37,
  24111. this->stm_label ? this->stm_label : this->stm_text)));
  24112. }
  24113. check_in_var();
  24114. if (check_in_type(otl_var_raw, 1)) {
  24115. unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val());
  24116. int len = OTL_CCAST(otl_long_string *, &s)->len();
  24117. if (len > this->vl[cur_in]->actual_elem_size()) {
  24118. otl_var_info_var(this->vl[cur_in]->get_name(),
  24119. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  24120. sizeof(var_info));
  24121. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24122. OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5,
  24123. this->stm_label ? this->stm_label : this->stm_text,
  24124. var_info)));
  24125. }
  24126. this->vl[cur_in]->set_not_null(0);
  24127. otl_memcpy(c + sizeof(unsigned short), s.v, len,
  24128. this->vl[cur_in]->get_ftype());
  24129. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  24130. OTL_SCAST(unsigned short, len);
  24131. this->vl[cur_in]->set_len(len, 0);
  24132. }
  24133. get_in_next();
  24134. return *this;
  24135. }
  24136. otl_ref_select_stream &operator>>(char &c) {
  24137. check_if_executed();
  24138. if (eof_intern())
  24139. return *this;
  24140. get_next();
  24141. if (check_type(otl_var_char) && !eof_intern()) {
  24142. c = *OTL_RCAST(char *, sl[cur_col].val(cur_row));
  24143. look_ahead();
  24144. }
  24145. return *this;
  24146. }
  24147. otl_ref_select_stream &operator>>(unsigned char &c) {
  24148. check_if_executed();
  24149. if (eof_intern())
  24150. return *this;
  24151. get_next();
  24152. if (check_type(otl_var_char) && !eof_intern()) {
  24153. c = *OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  24154. look_ahead();
  24155. }
  24156. return *this;
  24157. }
  24158. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  24159. otl_ref_select_stream &operator>>(OTL_STRING_CONTAINER &s) {
  24160. check_if_executed();
  24161. if (eof_intern())
  24162. return *this;
  24163. get_next();
  24164. switch (sl[cur_col].get_ftype()) {
  24165. case otl_var_char:
  24166. if (!eof_intern()) {
  24167. #if defined(OTL_ACE)
  24168. s.set(OTL_RCAST(char *, sl[cur_col].val(cur_row)), 1);
  24169. #else
  24170. s = OTL_RCAST(char *, sl[cur_col].val(cur_row));
  24171. #endif
  24172. look_ahead();
  24173. }
  24174. break;
  24175. #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE)
  24176. case otl_var_varchar_long:
  24177. case otl_var_raw_long:
  24178. if (!eof_intern()) {
  24179. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  24180. int len = sl[cur_col].get_len(cur_row);
  24181. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  24182. !defined(USER_DEFINED_STRING_CLASS))
  24183. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len));
  24184. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  24185. s.assign(OTL_RCAST(char *, c), len);
  24186. #elif defined(OTL_ACE)
  24187. s.set(OTL_RCAST(char *, c), len, 1);
  24188. #endif
  24189. look_ahead();
  24190. }
  24191. break;
  24192. case otl_var_raw: {
  24193. if (!eof_intern()) {
  24194. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  24195. int len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c));
  24196. c += sizeof(short int);
  24197. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  24198. !defined(USER_DEFINED_STRING_CLASS))
  24199. s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len));
  24200. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  24201. s.assign(OTL_RCAST(char *, c), len);
  24202. #elif defined(OTL_ACE)
  24203. s.set(OTL_RCAST(char *, c), len, 1);
  24204. #endif
  24205. look_ahead();
  24206. }
  24207. } break;
  24208. case otl_var_blob:
  24209. case otl_var_clob:
  24210. if (!eof_intern()) {
  24211. int len = 0;
  24212. int max_long_sz = this->adb->get_max_long_size();
  24213. otl_auto_array_ptr<unsigned char> loc_ptr(max_long_sz);
  24214. unsigned char *temp_buf = loc_ptr.get_ptr();
  24215. int rc = sl[cur_col].get_var_struct().get_blob(cur_row, temp_buf,
  24216. max_long_sz, len);
  24217. if (rc == 0) {
  24218. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24219. OTL_THROW((otl_exception(adb->get_connect_struct(),
  24220. stm_label ? stm_label : stm_text)));
  24221. }
  24222. #if (defined(OTL_STL) && !defined(OTL_ACE) && \
  24223. !defined(USER_DEFINED_STRING_CLASS))
  24224. s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len));
  24225. #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE))
  24226. s.assign(OTL_RCAST(char *, temp_buf), len);
  24227. #elif defined(OTL_ACE)
  24228. s.set(OTL_RCAST(char *, temp_buf), len, 1);
  24229. #endif
  24230. look_ahead();
  24231. }
  24232. break;
  24233. #endif
  24234. default:
  24235. (void)check_type(otl_var_char);
  24236. } // switch
  24237. return *this;
  24238. }
  24239. #endif
  24240. otl_ref_select_stream &operator>>(char *s) {
  24241. check_if_executed();
  24242. if (eof_intern())
  24243. return *this;
  24244. get_next();
  24245. if (check_type(otl_var_char) && !eof_intern()) {
  24246. otl_strcpy(OTL_RCAST(unsigned char *, s),
  24247. OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row)));
  24248. look_ahead();
  24249. }
  24250. return *this;
  24251. }
  24252. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  24253. template<const size_t N>
  24254. otl_ref_select_stream &operator>>(std::array<char,N>& s) {
  24255. check_if_executed();
  24256. if (eof_intern())
  24257. return *this;
  24258. get_next();
  24259. if (check_type(otl_var_char) && !eof_intern()) {
  24260. if(OTL_SCAST(int,N)<sl[cur_col].get_len(cur_row)){
  24261. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  24262. const_STD_CHAR_ARRAY_code, var_info, sizeof(var_info));
  24263. OTL_THROW((otl_exception(otl_error_msg_45,
  24264. otl_error_code_45,
  24265. this->stm_label ? this->stm_label : this->stm_text,
  24266. var_info)));
  24267. }
  24268. otl_strcpy(OTL_RCAST(unsigned char*, s.data()),
  24269. OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row)));
  24270. look_ahead();
  24271. }
  24272. return *this;
  24273. }
  24274. template<const size_t N>
  24275. otl_ref_select_stream &operator<<(const std::array<char,N>& s){
  24276. (*this)<<s.data();
  24277. return *this;
  24278. }
  24279. #endif
  24280. #if defined(OTL_UNICODE_STRING_TYPE)
  24281. otl_ref_select_stream &operator>>(OTL_UNICODE_STRING_TYPE &s) {
  24282. check_if_executed();
  24283. if (eof_intern())
  24284. return *this;
  24285. get_next();
  24286. switch (sl[cur_col].get_ftype()) {
  24287. case otl_var_char:
  24288. if (!eof_intern()) {
  24289. #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR)
  24290. OTL_UNICODE_CHAR_TYPE *temp_s =
  24291. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  24292. OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s);
  24293. #else
  24294. OTL_UNICODE_CHAR_TYPE *temp_s =
  24295. OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  24296. s.assign(temp_s + 1, *temp_s);
  24297. #endif
  24298. look_ahead();
  24299. }
  24300. break;
  24301. case otl_var_varchar_long:
  24302. if (!eof_intern()) {
  24303. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row));
  24304. look_ahead();
  24305. }
  24306. break;
  24307. case otl_var_clob:
  24308. if (!eof_intern()) {
  24309. int len = 0;
  24310. int max_long_sz = this->adb->get_max_long_size();
  24311. otl_auto_array_ptr<unsigned short> loc_ptr(max_long_sz);
  24312. unsigned char *temp_buf = OTL_RCAST(unsigned char *, loc_ptr.get_ptr());
  24313. int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf,
  24314. max_long_sz, len);
  24315. if (rc == 0) {
  24316. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24317. OTL_THROW((otl_exception(this->adb->get_connect_struct(),
  24318. this->stm_label ? this->stm_label
  24319. : this->stm_text)));
  24320. }
  24321. s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, temp_buf);
  24322. look_ahead();
  24323. }
  24324. break;
  24325. default:
  24326. (void)check_type(otl_var_char);
  24327. }
  24328. return *this;
  24329. }
  24330. #endif
  24331. otl_ref_select_stream &operator>>(unsigned char *s) {
  24332. check_if_executed();
  24333. if (eof_intern())
  24334. return *this;
  24335. get_next();
  24336. if (check_type(otl_var_char) && !eof_intern()) {
  24337. otl_strcpy2(OTL_RCAST(unsigned char *, s),
  24338. OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)),
  24339. sl[cur_col].get_len(cur_row));
  24340. look_ahead();
  24341. }
  24342. return *this;
  24343. }
  24344. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  24345. template<const size_t N>
  24346. otl_ref_select_stream &operator>>(std::array<char16_t,N>& s) {
  24347. check_if_executed();
  24348. if (eof_intern())
  24349. return *this;
  24350. get_next();
  24351. if (check_type(otl_var_char) && !eof_intern()) {
  24352. if(OTL_SCAST(int,N)<sl[cur_col].get_len(cur_row)){
  24353. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  24354. const_STD_UNICODE_CHAR_ARRAY_code, var_info, sizeof(var_info));
  24355. OTL_THROW((otl_exception(otl_error_msg_46,
  24356. otl_error_code_46,
  24357. this->stm_label ? this->stm_label : this->stm_text,
  24358. var_info)));
  24359. }
  24360. otl_strcpy2(OTL_RCAST(unsigned char *, s.data()),
  24361. OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)),
  24362. sl[cur_col].get_len(cur_row));
  24363. look_ahead();
  24364. }
  24365. return *this;
  24366. }
  24367. #endif
  24368. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  24369. #if !defined(OTL_D7)
  24370. #define OTL_D7(T, T_type) \
  24371. otl_ref_select_stream &operator>>(T &n) { \
  24372. check_if_executed(); \
  24373. if (eof_intern()) \
  24374. return *this; \
  24375. get_next(); \
  24376. if (!eof_intern()) { \
  24377. int match_found = otl_numeric_convert_T<T, T_type>( \
  24378. sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); \
  24379. if (!match_found) \
  24380. strict_check_throw(T_type); \
  24381. look_ahead(); \
  24382. } \
  24383. return *this; \
  24384. }
  24385. #endif
  24386. #else
  24387. #if !defined(OTL_D7)
  24388. #define OTL_D7(T, T_type) \
  24389. otl_ref_select_stream &operator>>(T &n) { \
  24390. check_if_executed(); \
  24391. if (eof_intern()) \
  24392. return *this; \
  24393. get_next(); \
  24394. if (!eof_intern()) { \
  24395. int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), \
  24396. sl[cur_col].val(cur_row), n); \
  24397. if (!match_found) { \
  24398. if (check_type(otl_var_double, T_type)) \
  24399. n = OTL_PCONV(T, double, sl[cur_col].val(cur_row)); \
  24400. } \
  24401. look_ahead(); \
  24402. } \
  24403. return *this; \
  24404. }
  24405. #endif
  24406. #endif
  24407. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  24408. OTL_D7(int, otl_var_int)
  24409. OTL_D7(unsigned, otl_var_unsigned_int)
  24410. OTL_D7(long, otl_var_long_int)
  24411. OTL_D7(short, otl_var_short)
  24412. OTL_D7(float, otl_var_float)
  24413. OTL_D7(double, otl_var_double)
  24414. #if defined(OTL_BIGINT) && \
  24415. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  24416. !defined(OTL_BIGINT_TO_STR))
  24417. OTL_D7(OTL_BIGINT, otl_var_bigint)
  24418. #endif
  24419. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  24420. OTL_D7(OTL_UBIGINT, otl_var_ubigint)
  24421. #endif
  24422. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  24423. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \
  24424. !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS)
  24425. OTL_D7(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  24426. #endif
  24427. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  24428. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \
  24429. !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS)
  24430. OTL_D7(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  24431. #endif
  24432. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  24433. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \
  24434. !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS)
  24435. OTL_D7(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  24436. #endif
  24437. #else
  24438. template<OTL_TYPE_NAME T,const int T_type> OTL_D7(T,T_type)
  24439. #endif
  24440. otl_ref_select_stream &operator>>(otl_long_string &s) {
  24441. check_if_executed();
  24442. if (eof_intern())
  24443. return *this;
  24444. get_next();
  24445. switch (sl[cur_col].get_ftype()) {
  24446. case otl_var_varchar_long:
  24447. case otl_var_raw_long: {
  24448. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  24449. if (!s.get_unicode_flag() && in_unicode_mode &&
  24450. sl[cur_col].get_ftype() == otl_var_varchar_long) {
  24451. OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37,
  24452. this->stm_label ? this->stm_label : this->stm_text)));
  24453. } else if (s.get_unicode_flag() &&
  24454. sl[cur_col].get_ftype() == otl_var_raw_long) {
  24455. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  24456. this->stm_label ? this->stm_label : this->stm_text)));
  24457. }
  24458. if (!eof_intern()) {
  24459. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  24460. int len = sl[cur_col].get_len(cur_row);
  24461. if (len > s.get_buf_size())
  24462. len = s.get_buf_size();
  24463. otl_memcpy(s.v, c, len, sl[cur_col].get_ftype());
  24464. s.v[len] = 0;
  24465. s.set_len(len);
  24466. look_ahead();
  24467. }
  24468. } break;
  24469. case otl_var_raw: {
  24470. if (s.get_unicode_flag()) {
  24471. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  24472. this->stm_label ? this->stm_label : this->stm_text)));
  24473. }
  24474. if (!eof_intern()) {
  24475. unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row));
  24476. int len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c));
  24477. if (len > s.get_buf_size())
  24478. len = s.get_buf_size();
  24479. otl_memcpy(s.v, c + sizeof(short int), len, sl[cur_col].get_ftype());
  24480. s.set_len(len);
  24481. look_ahead();
  24482. }
  24483. } break;
  24484. case otl_var_blob:
  24485. case otl_var_clob: {
  24486. bool in_unicode_mode = sizeof(OTL_CHAR) > 1;
  24487. if (!s.get_unicode_flag() && in_unicode_mode &&
  24488. sl[cur_col].get_ftype() == otl_var_clob) {
  24489. OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37,
  24490. this->stm_label ? this->stm_label : this->stm_text)));
  24491. } else if (s.get_unicode_flag() &&
  24492. sl[cur_col].get_ftype() == otl_var_blob) {
  24493. OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38,
  24494. this->stm_label ? this->stm_label : this->stm_text)));
  24495. }
  24496. if (!eof_intern()) {
  24497. int len;
  24498. int rc = sl[cur_col].get_var_struct().get_blob(cur_row, s.v,
  24499. s.get_buf_size(), len);
  24500. if (rc == 0) {
  24501. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24502. OTL_THROW((otl_exception(adb->get_connect_struct(),
  24503. stm_label ? stm_label : stm_text)));
  24504. }
  24505. s.set_len(len);
  24506. if (sl[cur_col].get_ftype() == otl_var_clob)
  24507. s.null_terminate_string(len);
  24508. look_ahead();
  24509. }
  24510. } break;
  24511. }
  24512. return *this;
  24513. }
  24514. otl_ref_select_stream &operator>>(otl_lob_stream &s) {
  24515. check_if_executed();
  24516. if (eof_intern())
  24517. return *this;
  24518. get_next();
  24519. if ((sl[cur_col].get_ftype() == otl_var_blob ||
  24520. sl[cur_col].get_ftype() == otl_var_clob) &&
  24521. !eof_intern()) {
  24522. s.init(&sl[cur_col], adb, OTL_RCAST(otl_ref_cursor *, this), cur_row,
  24523. OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null());
  24524. delay_next = 1;
  24525. }
  24526. return *this;
  24527. }
  24528. #if defined(OTL_ORA_SDO_GEOMETRY)
  24529. otl_ref_select_stream &operator >> (oci_spatial_geometry &s){
  24530. check_if_executed();
  24531. if(eof_intern())
  24532. return *this;
  24533. get_next();
  24534. if(check_type(otl_var_sdo_geometry) && !eof_intern()){
  24535. (void)sl[cur_col].get_var_struct().read_geometry(s, cur_row);
  24536. look_ahead();
  24537. }
  24538. return *this;
  24539. }
  24540. #endif
  24541. otl_ref_select_stream &operator<<(const otl_null & /*n*/) {
  24542. check_in_var();
  24543. this->vl[cur_in]->set_null(0);
  24544. get_in_next();
  24545. return *this;
  24546. }
  24547. otl_ref_select_stream &operator<<(const char c) {
  24548. check_in_var();
  24549. if (check_in_type(otl_var_char, 1)) {
  24550. char *tmp = OTL_RCAST(char *, vl[cur_in]->val());
  24551. tmp[0] = c;
  24552. tmp[1] = 0;
  24553. }
  24554. this->vl[cur_in]->set_not_null(0);
  24555. get_in_next();
  24556. return *this;
  24557. }
  24558. otl_ref_select_stream &operator<<(const unsigned char c) {
  24559. check_in_var();
  24560. if (check_in_type(otl_var_char, 1)) {
  24561. unsigned char *tmp = OTL_RCAST(unsigned char *, vl[cur_in]->val());
  24562. tmp[0] = c;
  24563. tmp[1] = 0;
  24564. }
  24565. this->vl[cur_in]->set_not_null(0);
  24566. get_in_next();
  24567. return *this;
  24568. }
  24569. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  24570. otl_ref_select_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) {
  24571. check_in_var();
  24572. if (this->vl[cur_in]->get_ftype() == otl_var_raw) {
  24573. unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val());
  24574. int len = OTL_SCAST(int, s.length());
  24575. if (len > this->vl[cur_in]->actual_elem_size()) {
  24576. otl_var_info_var(this->vl[cur_in]->get_name(),
  24577. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  24578. sizeof(var_info));
  24579. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24580. OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5,
  24581. this->stm_label ? this->stm_label : this->stm_text,
  24582. var_info)));
  24583. }
  24584. this->vl[cur_in]->set_not_null(0);
  24585. otl_memcpy(c + sizeof(unsigned short),
  24586. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len,
  24587. this->vl[cur_in]->get_ftype());
  24588. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  24589. OTL_SCAST(unsigned short, len);
  24590. this->vl[cur_in]->set_len(len, 0);
  24591. } else if (this->vl[cur_in]->get_ftype() == otl_var_char) {
  24592. int overflow;
  24593. otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24594. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())),
  24595. overflow, vl[cur_in]->get_elem_size(),
  24596. OTL_SCAST(int, s.length()));
  24597. if (overflow) {
  24598. char temp_var_info[256];
  24599. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24600. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24601. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24602. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24603. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24604. stm_label ? stm_label : stm_text, temp_var_info,
  24605. OTL_RCAST(const void *, s.data()),
  24606. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24607. #else
  24608. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24609. stm_label ? stm_label : stm_text, temp_var_info)));
  24610. #endif
  24611. }
  24612. } else
  24613. (void)check_in_type_throw(otl_var_char);
  24614. this->vl[cur_in]->set_not_null(0);
  24615. get_in_next();
  24616. return *this;
  24617. }
  24618. #endif
  24619. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  24620. otl_ref_select_stream &operator<<(const OTL_STRING_CONTAINER &s) {
  24621. check_in_var();
  24622. if (this->vl[cur_in]->get_ftype() == otl_var_raw) {
  24623. unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val());
  24624. int len = OTL_SCAST(int, s.length());
  24625. if (len > this->vl[cur_in]->actual_elem_size()) {
  24626. otl_var_info_var(this->vl[cur_in]->get_name(),
  24627. this->vl[cur_in]->get_ftype(), otl_var_raw, var_info,
  24628. sizeof(var_info));
  24629. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24630. OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5,
  24631. this->stm_label ? this->stm_label : this->stm_text,
  24632. var_info)));
  24633. }
  24634. this->vl[cur_in]->set_not_null(0);
  24635. otl_memcpy(c + sizeof(unsigned short),
  24636. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len,
  24637. this->vl[cur_in]->get_ftype());
  24638. *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) =
  24639. OTL_SCAST(unsigned short, len);
  24640. this->vl[cur_in]->set_len(len, 0);
  24641. } else if (this->vl[cur_in]->get_ftype() == otl_var_char) {
  24642. int overflow;
  24643. otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24644. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())),
  24645. overflow, vl[cur_in]->get_elem_size(),
  24646. OTL_SCAST(int, s.length()));
  24647. if (overflow) {
  24648. char temp_var_info[256];
  24649. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24650. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24651. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24652. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24653. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24654. stm_label ? stm_label : stm_text, temp_var_info,
  24655. OTL_RCAST(const void *, s.c_str()),
  24656. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24657. #else
  24658. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24659. stm_label ? stm_label : stm_text, temp_var_info)));
  24660. #endif
  24661. }
  24662. } else
  24663. (void)check_in_type_throw(otl_var_char);
  24664. this->vl[cur_in]->set_not_null(0);
  24665. get_in_next();
  24666. return *this;
  24667. }
  24668. #endif
  24669. #if defined(OTL_UNICODE_STRING_TYPE)
  24670. otl_ref_select_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) {
  24671. check_in_var();
  24672. if (check_in_type(otl_var_char, 1)) {
  24673. int overflow;
  24674. #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE)
  24675. otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24676. OTL_RCAST(unsigned char *,
  24677. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *,
  24678. s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())),
  24679. #else
  24680. otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24681. OTL_RCAST(unsigned char *,
  24682. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())),
  24683. #endif
  24684. overflow, vl[cur_in]->get_elem_size(),
  24685. OTL_SCAST(int, s.length()));
  24686. if (overflow) {
  24687. char temp_var_info[256];
  24688. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24689. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24690. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24691. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24692. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24693. stm_label ? stm_label : stm_text, temp_var_info,
  24694. OTL_RCAST(const void *, s.c_str()),
  24695. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24696. #else
  24697. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24698. stm_label ? stm_label : stm_text, temp_var_info)));
  24699. #endif
  24700. }
  24701. }
  24702. this->vl[cur_in]->set_not_null(0);
  24703. get_in_next();
  24704. return *this;
  24705. }
  24706. #endif
  24707. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  24708. otl_ref_select_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) {
  24709. check_in_var();
  24710. if (check_in_type(otl_var_char, 1)) {
  24711. int overflow;
  24712. otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24713. OTL_RCAST(unsigned char *,
  24714. OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())),
  24715. overflow, vl[cur_in]->get_elem_size(),
  24716. OTL_SCAST(int, s.length()));
  24717. if (overflow) {
  24718. char temp_var_info[256];
  24719. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24720. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24721. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24722. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24723. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24724. stm_label ? stm_label : stm_text, temp_var_info,
  24725. OTL_RCAST(const void *, s.data()),
  24726. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24727. #else
  24728. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24729. stm_label ? stm_label : stm_text, temp_var_info)));
  24730. #endif
  24731. }
  24732. }
  24733. this->vl[cur_in]->set_not_null(0);
  24734. get_in_next();
  24735. return *this;
  24736. }
  24737. #endif
  24738. otl_ref_select_stream &operator<<(const char *s) {
  24739. check_in_var();
  24740. if (check_in_type(otl_var_char, 1)) {
  24741. int overflow;
  24742. otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24743. OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow,
  24744. vl[cur_in]->get_elem_size());
  24745. if (overflow) {
  24746. char temp_var_info[256];
  24747. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24748. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24749. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24750. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24751. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24752. stm_label ? stm_label : stm_text, temp_var_info,
  24753. OTL_RCAST(const void *, s),
  24754. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24755. #else
  24756. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24757. stm_label ? stm_label : stm_text, temp_var_info)));
  24758. #endif
  24759. }
  24760. }
  24761. this->vl[cur_in]->set_not_null(0);
  24762. get_in_next();
  24763. return *this;
  24764. }
  24765. otl_ref_select_stream &operator<<(const unsigned char *s) {
  24766. check_in_var();
  24767. if (check_in_type(otl_var_char, 1)) {
  24768. int overflow;
  24769. otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()),
  24770. OTL_CCAST(unsigned char *, s), overflow,
  24771. vl[cur_in]->get_elem_size());
  24772. if (overflow) {
  24773. char temp_var_info[256];
  24774. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24775. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24776. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24777. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24778. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24779. stm_label ? stm_label : stm_text, temp_var_info,
  24780. OTL_RCAST(const void *, s),
  24781. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24782. #else
  24783. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24784. stm_label ? stm_label : stm_text, temp_var_info)));
  24785. #endif
  24786. }
  24787. }
  24788. this->vl[cur_in]->set_not_null(0);
  24789. get_in_next();
  24790. return *this;
  24791. }
  24792. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
  24793. template<const size_t N>
  24794. otl_ref_select_stream &operator<<(const std::array<char16_t,N>& s){
  24795. (*this)<<OTL_RCAST(unsigned char*,OTL_CCAST(char16_t*,s.data()));
  24796. return *this;
  24797. }
  24798. #endif
  24799. #if defined(OTL_ORA_SDO_GEOMETRY)
  24800. otl_ref_select_stream &operator << (const oci_spatial_geometry &s){
  24801. check_in_var();
  24802. if(check_in_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){
  24803. int rc = this->vl[cur_in]->get_var_struct().write_geometry(s, cur_in);
  24804. if(rc == 0){
  24805. char temp_var_info[256];
  24806. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(),
  24807. otl_var_char, temp_var_info, sizeof(temp_var_info));
  24808. OTL_UNCAUGHT_EXCEPTION_RETURN(*this);
  24809. #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW)
  24810. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24811. stm_label ? stm_label : stm_text, temp_var_info,
  24812. OTL_RCAST(const void *, s),
  24813. OTL_SCAST(int, vl[cur_in]->get_elem_size()))));
  24814. #else
  24815. OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4,
  24816. stm_label ? stm_label : stm_text, temp_var_info)));
  24817. #endif
  24818. }
  24819. }
  24820. get_in_next();
  24821. return *this;
  24822. }
  24823. #endif
  24824. #if !defined(OTL_D8)
  24825. #define OTL_D8(T, T_type) \
  24826. otl_ref_select_stream &operator<<(const T n) { \
  24827. check_in_var(); \
  24828. if (check_in_type(T_type, sizeof(T))) { \
  24829. *OTL_RCAST(T *, vl[cur_in]->val()) = n; \
  24830. } \
  24831. this->vl[cur_in]->set_not_null(0); \
  24832. get_in_next(); \
  24833. return *this; \
  24834. }
  24835. #endif
  24836. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  24837. OTL_D8(int, otl_var_int)
  24838. OTL_D8(unsigned, otl_var_unsigned_int)
  24839. OTL_D8(long, otl_var_long_int)
  24840. OTL_D8(short, otl_var_short)
  24841. OTL_D8(float, otl_var_float)
  24842. OTL_D8(double, otl_var_double)
  24843. #if defined(OTL_BIGINT) && \
  24844. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  24845. !defined(OTL_BIGINT_TO_STR))
  24846. OTL_D8(OTL_BIGINT, otl_var_bigint)
  24847. #endif
  24848. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  24849. OTL_D8(OTL_UBIGINT, otl_var_ubigint)
  24850. #endif
  24851. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  24852. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  24853. OTL_D8(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1)
  24854. #endif
  24855. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  24856. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  24857. OTL_D8(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2)
  24858. #endif
  24859. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  24860. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  24861. OTL_D8(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3)
  24862. #endif
  24863. #else
  24864. template <OTL_TYPE_NAME T, const int T_type>
  24865. OTL_D8(T, T_type)
  24866. #endif
  24867. OTL_NODISCARD int select_list_len(void) const { return sl_len; }
  24868. OTL_NODISCARD int column_ftype(int ndx = 0) const { return sl[ndx].get_ftype(); }
  24869. OTL_NODISCARD int column_size(int ndx = 0) const { return sl[ndx].get_elem_size(); }
  24870. OTL_NODISCARD int get_sl_len() const { return sl_len; }
  24871. OTL_NODISCARD otl_generic_variable *get_sl() const { return sl; }
  24872. OTL_NODISCARD otl_column_desc *get_sl_desc() const { return sl_desc; }
  24873. protected:
  24874. otl_column_desc *sl_desc;
  24875. int sl_len;
  24876. otl_generic_variable *sl;
  24877. int null_fetched;
  24878. int ret_code;
  24879. int cur_col;
  24880. int cur_in;
  24881. int executed;
  24882. char var_info[256];
  24883. void init(void) {
  24884. same_sl_flag = 0;
  24885. sl = nullptr;
  24886. sl_len = 0;
  24887. null_fetched = 0;
  24888. ret_code = 0;
  24889. sl_desc = nullptr;
  24890. executed = 0;
  24891. cur_in = 0;
  24892. stm_text = nullptr;
  24893. }
  24894. void get_next(void) {
  24895. if (cur_col < sl_len - 1) {
  24896. ++cur_col;
  24897. null_fetched = sl[cur_col].is_null(cur_row);
  24898. } else {
  24899. ret_code = next();
  24900. cur_col = 0;
  24901. }
  24902. }
  24903. OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) {
  24904. int out_type_code;
  24905. if (actual_data_type != 0)
  24906. out_type_code = actual_data_type;
  24907. else
  24908. out_type_code = type_code;
  24909. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(),
  24910. out_type_code, var_info, sizeof(var_info));
  24911. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  24912. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  24913. stm_label ? stm_label : stm_text, var_info)));
  24914. }
  24915. OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) {
  24916. switch (sl[cur_col].get_ftype()) {
  24917. case otl_var_timestamp:
  24918. case otl_var_tz_timestamp:
  24919. case otl_var_ltz_timestamp:
  24920. if (type_code == otl_var_timestamp)
  24921. return 1;
  24922. break;
  24923. default:
  24924. #if defined(OTL_CHECK_OUT_TYPE_FUNC)
  24925. if ((sl[cur_col].get_ftype() == type_code) ||
  24926. OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code))
  24927. return 1;
  24928. break;
  24929. #else
  24930. if (sl[cur_col].get_ftype() == type_code)
  24931. return 1;
  24932. break;
  24933. #endif
  24934. }
  24935. return check_type_throw(type_code, actual_data_type);
  24936. }
  24937. void look_ahead(void) {
  24938. if (cur_col == sl_len - 1) {
  24939. #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH)
  24940. #else
  24941. ret_code = next();
  24942. cur_col = -1;
  24943. #endif
  24944. ++_rfc;
  24945. }
  24946. }
  24947. void get_select_list(void) {
  24948. int i, j, rc;
  24949. otl_auto_array_ptr<otl_column_desc> loc_ptr(otl_var_list_size);
  24950. otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr();
  24951. int sld_tmp_len = 0;
  24952. int ftype, elem_size;
  24953. OCIBind *bindpp;
  24954. if (!sel_cur.get_connected()) {
  24955. sel_cur.open(*adb);
  24956. rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp,
  24957. OTL_RCAST(text *, cur_placeholder),
  24958. OTL_SCAST(sb4, strlen(cur_placeholder)),
  24959. OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda),
  24960. 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr,
  24961. OTL_SCAST(ub4, OCI_DEFAULT));
  24962. if (rc != 0) {
  24963. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  24964. OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text)));
  24965. }
  24966. }
  24967. for (i = 0; i < vl_len; ++i)
  24968. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::bind(*vl[i]);
  24969. // Executing the PLSQL master block
  24970. otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::exec(
  24971. 1, 0, otl_sql_exec_from_select_cursor_class);
  24972. sel_cur.set_connected(1);
  24973. cur_row = -2;
  24974. if (same_sl_flag && sl) {
  24975. // assuming that ref.cur's select list is the same as
  24976. // in previous executions of the master block.
  24977. for (i = 0; i < sl_len; ++i)
  24978. sel_cur.bind(sl[i]);
  24979. return;
  24980. } else {
  24981. sld_tmp_len = 0;
  24982. sel_cur.get_cursor_struct().straight_select = 0;
  24983. for (i = 1; sel_cur.describe_column(sl_desc_tmp[i - 1], i); ++i) {
  24984. ++sld_tmp_len;
  24985. if (sld_tmp_len == loc_ptr.get_arr_size()) {
  24986. loc_ptr.double_size();
  24987. sl_desc_tmp = loc_ptr.get_ptr();
  24988. }
  24989. }
  24990. sl_len = sld_tmp_len;
  24991. if (sl) {
  24992. delete[] sl;
  24993. sl = nullptr;
  24994. }
  24995. sl = new otl_generic_variable[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  24996. int max_long_size = this->adb->get_max_long_size();
  24997. for (j = 0; j < sl_len; ++j) {
  24998. otl_generic_variable::map_ftype(
  24999. sl_desc_tmp[j], max_long_size, ftype, elem_size,
  25000. this->local_override.getLen() > 0 ? this->local_override
  25001. : *override_,
  25002. j + 1, this->adb->get_connect_struct().get_connection_type());
  25003. sl[j].copy_pos(j + 1);
  25004. #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8)
  25005. if (sl_desc_tmp[j].charset_form == 2)
  25006. sl[j].get_var_struct().nls_flag = true;
  25007. #endif
  25008. sl[j].init(true, ftype, elem_size,
  25009. OTL_SCAST(otl_stream_buffer_size_type, array_size),
  25010. &adb->get_connect_struct()
  25011. #if defined(OTL_ORA_SDO_GEOMETRY)
  25012. , 0, sl_desc_tmp[j].colOCIType
  25013. #endif
  25014. );
  25015. }
  25016. if (sl_desc) {
  25017. delete[] sl_desc;
  25018. sl_desc = nullptr;
  25019. }
  25020. sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)];
  25021. for (i = 0; i < sl_len; ++i)
  25022. sl_desc[i] = sl_desc_tmp[i];
  25023. for (i = 0; i < sl_len; ++i)
  25024. sel_cur.bind(sl[i]);
  25025. #if defined(OTL_ORA_STREAM_POOL_ASSUMES_SAME_REF_CUR_STRUCT_ON_REUSE)
  25026. same_sl_flag = 1;
  25027. #endif
  25028. }
  25029. }
  25030. void get_in_next(void) {
  25031. if (cur_in == vl_len - 1)
  25032. rewind();
  25033. else {
  25034. ++cur_in;
  25035. executed = 0;
  25036. }
  25037. }
  25038. OTL_NODISCARD int check_in_type_throw(int type_code) {
  25039. otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), type_code,
  25040. var_info, sizeof(var_info));
  25041. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  25042. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  25043. stm_label ? stm_label : stm_text, var_info)));
  25044. }
  25045. OTL_NODISCARD int check_in_type(int type_code, int tsize) {
  25046. switch (vl[cur_in]->get_ftype()) {
  25047. case otl_var_char:
  25048. if (type_code == otl_var_char)
  25049. return 1;
  25050. case otl_var_raw:
  25051. if (type_code == otl_var_raw)
  25052. return 1;
  25053. case otl_var_timestamp:
  25054. case otl_var_tz_timestamp:
  25055. case otl_var_ltz_timestamp:
  25056. if (type_code == otl_var_timestamp)
  25057. return 1;
  25058. default:
  25059. #if defined(OTL_CHECK_IN_TYPE_FUNC)
  25060. if ((vl[cur_in]->get_ftype() == type_code &&
  25061. vl[cur_in]->get_elem_size() == tsize) ||
  25062. OTL_CHECK_IN_TYPE_FUNC(vl[cur_in]->get_ftype(),type_code))
  25063. return 1;
  25064. break;
  25065. #else
  25066. if (vl[cur_in]->get_ftype() == type_code &&
  25067. vl[cur_in]->get_elem_size() == tsize)
  25068. return 1;
  25069. #endif
  25070. }
  25071. return check_in_type_throw(type_code);
  25072. }
  25073. void check_in_var(void) {
  25074. if (vl_len == 0) {
  25075. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  25076. OTL_THROW((otl_exception(otl_error_msg_1, otl_error_code_1,
  25077. stm_label ? stm_label : stm_text, nullptr)));
  25078. }
  25079. }
  25080. void check_if_executed(void) {
  25081. if (!executed) {
  25082. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  25083. OTL_THROW((otl_exception(otl_error_msg_2, otl_error_code_2,
  25084. stm_label ? stm_label : stm_text, nullptr)));
  25085. }
  25086. }
  25087. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  25088. void strict_check_throw(int type_code) {
  25089. otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), type_code,
  25090. var_info, sizeof(var_info));
  25091. OTL_UNCAUGHT_EXCEPTION_NORETURN;
  25092. OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0,
  25093. this->stm_label ? this->stm_label : this->stm_text,
  25094. var_info)));
  25095. }
  25096. #endif
  25097. private:
  25098. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  25099. public:
  25100. otl_ref_select_stream(const otl_ref_select_stream &) = delete;
  25101. otl_ref_select_stream &operator=(const otl_ref_select_stream &) = delete;
  25102. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  25103. otl_ref_select_stream(otl_ref_select_stream &&) = delete;
  25104. otl_ref_select_stream &operator=(otl_ref_select_stream &&) = delete;
  25105. #endif
  25106. private:
  25107. #else
  25108. otl_ref_select_stream(const otl_ref_select_stream &)
  25109. : otl_ref_cursor(), override_(nullptr), delay_next(0), same_sl_flag(0),
  25110. _rfc(0), sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0),
  25111. ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() {}
  25112. otl_ref_select_stream &operator=(const otl_ref_select_stream &) {
  25113. return *this;
  25114. }
  25115. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  25116. otl_ref_select_stream(otl_ref_select_stream &&)
  25117. : otl_ref_cursor(), override_(nullptr), delay_next(0), same_sl_flag(0),
  25118. _rfc(0), sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0),
  25119. ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() {}
  25120. otl_ref_select_stream &operator=(otl_ref_select_stream &&) { return *this; }
  25121. #endif
  25122. #endif
  25123. };
  25124. class otl_stream_shell : public otl_stream_shell_generic {
  25125. public:
  25126. otl_ref_select_stream *ref_ss;
  25127. otl_select_stream *ss;
  25128. otl_inout_stream *io;
  25129. otl_connect *adb;
  25130. int auto_commit_flag;
  25131. bool lob_stream_flag;
  25132. otl_var_desc *iov;
  25133. int iov_len;
  25134. int next_iov_ndx;
  25135. otl_var_desc *ov;
  25136. int ov_len;
  25137. int next_ov_ndx;
  25138. bool flush_flag;
  25139. int stream_type;
  25140. otl_select_struct_override override_;
  25141. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  25142. defined(OTL_UNICODE_STRING_TYPE)) && \
  25143. defined(OTL_STREAM_POOLING_ON)
  25144. #if defined(OTL_UNICODE_STRING_TYPE)
  25145. std::string orig_sql_stm;
  25146. #else
  25147. OTL_STRING_CONTAINER orig_sql_stm;
  25148. #endif
  25149. #endif
  25150. otl_stream_shell()
  25151. : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr),
  25152. adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr),
  25153. iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0),
  25154. flush_flag(false), stream_type(otl_no_stream_type), override_()
  25155. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  25156. defined(OTL_UNICODE_STRING_TYPE)) && \
  25157. defined(OTL_STREAM_POOLING_ON)
  25158. ,
  25159. orig_sql_stm()
  25160. #endif
  25161. {
  25162. should_delete = 0;
  25163. }
  25164. otl_stream_shell(const int ashould_delete)
  25165. : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr),
  25166. adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr),
  25167. iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0),
  25168. flush_flag(true), stream_type(otl_no_stream_type), override_()
  25169. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  25170. defined(OTL_UNICODE_STRING_TYPE)) && \
  25171. defined(OTL_STREAM_POOLING_ON)
  25172. ,
  25173. orig_sql_stm()
  25174. #endif
  25175. {
  25176. should_delete = ashould_delete;
  25177. }
  25178. virtual ~otl_stream_shell() OTL_THROWS_OTL_EXCEPTION {
  25179. if (should_delete) {
  25180. delete[] iov;
  25181. delete[] ov;
  25182. iov = nullptr;
  25183. iov_len = 0;
  25184. ov = nullptr;
  25185. ov_len = 0;
  25186. next_iov_ndx = 0;
  25187. next_ov_ndx = 0;
  25188. override_.setLen(0);
  25189. flush_flag = true;
  25190. delete ss;
  25191. delete io;
  25192. delete ref_ss;
  25193. ss = nullptr;
  25194. io = nullptr;
  25195. ref_ss = nullptr;
  25196. adb = nullptr;
  25197. }
  25198. }
  25199. private:
  25200. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  25201. public:
  25202. otl_stream_shell(const otl_stream_shell &) = delete;
  25203. otl_stream_shell &operator=(const otl_stream_shell &) = delete;
  25204. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  25205. otl_stream_shell(otl_stream_shell &&) = delete;
  25206. otl_stream_shell &operator=(otl_stream_shell &&) = delete;
  25207. #endif
  25208. private:
  25209. #else
  25210. otl_stream_shell(const otl_stream_shell &)
  25211. : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr),
  25212. adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr),
  25213. iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0),
  25214. flush_flag(false), stream_type(otl_no_stream_type), override_()
  25215. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  25216. defined(OTL_UNICODE_STRING_TYPE)) && \
  25217. defined(OTL_STREAM_POOLING_ON)
  25218. ,
  25219. orig_sql_stm()
  25220. #endif
  25221. {
  25222. }
  25223. otl_stream_shell &operator=(const otl_stream_shell &) { return *this; }
  25224. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  25225. otl_stream_shell(otl_stream_shell &&)
  25226. : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr),
  25227. adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr),
  25228. iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0),
  25229. flush_flag(false), stream_type(otl_no_stream_type), override_()
  25230. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  25231. defined(OTL_UNICODE_STRING_TYPE)) && \
  25232. defined(OTL_STREAM_POOLING_ON)
  25233. ,
  25234. orig_sql_stm()
  25235. #endif
  25236. {
  25237. }
  25238. otl_stream_shell &operator=(otl_stream_shell &&) { return *this; }
  25239. #endif
  25240. #endif
  25241. };
  25242. class otl_sp_parm_desc {
  25243. public:
  25244. int position;
  25245. char arg_name[40];
  25246. char in_out[20];
  25247. char data_type[40];
  25248. char bind_var[128];
  25249. otl_sp_parm_desc()
  25250. : position(-1), arg_name(), in_out(), data_type(), bind_var() {
  25251. arg_name[0] = 0;
  25252. in_out[0] = 0;
  25253. data_type[0] = 0;
  25254. bind_var[0] = 0;
  25255. }
  25256. otl_sp_parm_desc(const otl_sp_parm_desc &r)
  25257. : position(-1), arg_name(), in_out(), data_type(), bind_var() {
  25258. copy(r);
  25259. }
  25260. otl_sp_parm_desc &operator=(const otl_sp_parm_desc &r) {
  25261. copy(r);
  25262. return *this;
  25263. }
  25264. ~otl_sp_parm_desc() {}
  25265. protected:
  25266. void copy(const otl_sp_parm_desc &r) {
  25267. position = r.position;
  25268. OTL_STRCPY_S(arg_name, sizeof(arg_name), r.arg_name);
  25269. OTL_STRCPY_S(in_out, sizeof(in_out), r.in_out);
  25270. OTL_STRCPY_S(data_type, sizeof(data_type), r.data_type);
  25271. OTL_STRCPY_S(bind_var, sizeof(bind_var), r.bind_var);
  25272. }
  25273. };
  25274. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  25275. class otl_stream;
  25276. class otl_for_range_loop_ora_stream_adapter{
  25277. public:
  25278. otl_for_range_loop_ora_stream_adapter(): str_(nullptr){}
  25279. otl_for_range_loop_ora_stream_adapter(otl_stream& str): str_(&str){}
  25280. otl_stream& operator*(){
  25281. return *str_;
  25282. }
  25283. otl_for_range_loop_ora_stream_adapter& operator++(){
  25284. return *this;
  25285. }
  25286. otl_stream* str_;
  25287. };
  25288. #endif
  25289. #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  25290. #include <array>
  25291. #endif
  25292. #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  25293. #include <array>
  25294. #endif
  25295. #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL)
  25296. #include <optional>
  25297. #endif
  25298. class otl_stream
  25299. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  25300. : public otl_read_stream_interface
  25301. #endif
  25302. {
  25303. protected:
  25304. otl_stream_shell *shell;
  25305. otl_ptr<otl_stream_shell> shell_pt;
  25306. int connected;
  25307. otl_ref_select_stream **ref_ss;
  25308. otl_select_stream **ss;
  25309. otl_inout_stream **io;
  25310. otl_connect **adb;
  25311. int *auto_commit_flag;
  25312. otl_var_desc **iov;
  25313. int *iov_len;
  25314. int *next_iov_ndx;
  25315. otl_var_desc **ov;
  25316. int *ov_len;
  25317. int *next_ov_ndx;
  25318. int end_marker;
  25319. int oper_int_called;
  25320. int last_eof_rc;
  25321. bool last_oper_was_read_op;
  25322. otl_select_struct_override *override_;
  25323. int buf_size_;
  25324. void inc_next_ov(void) {
  25325. if ((*ov_len) == 0)
  25326. return;
  25327. if ((*next_ov_ndx) < (*ov_len) - 1)
  25328. ++(*next_ov_ndx);
  25329. else
  25330. (*next_ov_ndx) = 0;
  25331. }
  25332. void inc_next_iov(void) {
  25333. if ((*iov_len) == 0)
  25334. return;
  25335. if ((*next_iov_ndx) < (*iov_len) - 1)
  25336. ++(*next_iov_ndx);
  25337. else
  25338. (*next_iov_ndx) = 0;
  25339. }
  25340. void reset_end_marker(void) {
  25341. last_eof_rc = 0;
  25342. end_marker = -1;
  25343. oper_int_called = 0;
  25344. }
  25345. static void convert_bind_var_datatype(char *out_buf,
  25346. const size_t out_buf_sz,
  25347. const char *datatype,
  25348. const int varchar_size,
  25349. const int all_num2type,
  25350. const int refcur_buf_size) {
  25351. out_buf[0] = 0;
  25352. if (strcmp(datatype, "BINARY_INTEGER") == 0 ||
  25353. strcmp(datatype, "NATIVE INTEGER") == 0 ||
  25354. strcmp(datatype, "BINARY_FLOAT") == 0 ||
  25355. strcmp(datatype, "BINARY_DOUBLE") == 0 ||
  25356. strcmp(datatype, "FLOAT") == 0 || strcmp(datatype, "NUMBER") == 0) {
  25357. switch (all_num2type) {
  25358. case otl_var_char:
  25359. OTL_STRCPY_S(out_buf, out_buf_sz, "char[50]");
  25360. break;
  25361. case otl_var_double:
  25362. OTL_STRCPY_S(out_buf, out_buf_sz, "double");
  25363. break;
  25364. case otl_var_float:
  25365. OTL_STRCPY_S(out_buf, out_buf_sz, "float");
  25366. break;
  25367. case otl_var_long_int:
  25368. OTL_STRCPY_S(out_buf, out_buf_sz, "long");
  25369. break;
  25370. case otl_var_int:
  25371. OTL_STRCPY_S(out_buf, out_buf_sz, "int");
  25372. break;
  25373. case otl_var_unsigned_int:
  25374. OTL_STRCPY_S(out_buf, out_buf_sz, "unsigned");
  25375. break;
  25376. case otl_var_short:
  25377. OTL_STRCPY_S(out_buf, out_buf_sz, "short");
  25378. break;
  25379. case otl_var_bfloat:
  25380. OTL_STRCPY_S(out_buf, out_buf_sz, "bfloat");
  25381. break;
  25382. case otl_var_bdouble:
  25383. OTL_STRCPY_S(out_buf, out_buf_sz, "bdouble");
  25384. break;
  25385. default:
  25386. break;
  25387. }
  25388. } else if (strcmp(datatype, "RAW") == 0) {
  25389. #if defined(OTL_ORA_CREATE_STORED_PROC_CALL_MAPS_RAW_TO_RAW_LONG)
  25390. OTL_STRCPY_S(out_buf, out_buf_sz, "raw_long");
  25391. #elif defined(OTL_ORA_CREATE_STORED_PROC_CALL_MAPS_RAW_TO_RAW)
  25392. OTL_SPRINTF_S(out_buf, out_buf_sz, "raw[%d]", varchar_size);
  25393. #else
  25394. #if defined(__clang__)
  25395. #pragma clang diagnostic push
  25396. #pragma clang diagnostic ignored "-Wunused-value"
  25397. #endif
  25398. OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size);
  25399. #if defined(__clang__)
  25400. #pragma clang diagnostic pop
  25401. #endif
  25402. #endif
  25403. } else if (strcmp(datatype, "LONG RAW") == 0) {
  25404. OTL_STRCPY_S(out_buf, out_buf_sz, "raw_long");
  25405. } else if (strcmp(datatype, "DATE") == 0)
  25406. OTL_STRCPY_S(out_buf, out_buf_sz, "timestamp");
  25407. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  25408. else if (strcmp(datatype, "TIMESTAMP") == 0)
  25409. OTL_STRCPY_S(out_buf, out_buf_sz, "timestamp");
  25410. #endif
  25411. else if (strcmp(datatype, "VARCHAR2") == 0)
  25412. #if defined(__clang__)
  25413. #pragma clang diagnostic push
  25414. #pragma clang diagnostic ignored "-Wunused-value"
  25415. #endif
  25416. OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size);
  25417. #if defined(__clang__)
  25418. #pragma clang diagnostic pop
  25419. #endif
  25420. else if (strcmp(datatype, "CHAR") == 0)
  25421. #if defined(__clang__)
  25422. #pragma clang diagnostic push
  25423. #pragma clang diagnostic ignored "-Wunused-value"
  25424. #endif
  25425. OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size);
  25426. #if defined(__clang__)
  25427. #pragma clang diagnostic pop
  25428. #endif
  25429. else if (strcmp(datatype, "REF CURSOR") == 0)
  25430. #if defined(__clang__)
  25431. #pragma clang diagnostic push
  25432. #pragma clang diagnostic ignored "-Wunused-value"
  25433. #endif
  25434. OTL_SPRINTF_S(out_buf, out_buf_sz, "refcur,out[%d]", refcur_buf_size);
  25435. #if defined(__clang__)
  25436. #pragma clang diagnostic pop
  25437. #endif
  25438. }
  25439. void throw_end_of_row()
  25440. #if defined(__GNUC__) && (__GNUC__ >= 4)
  25441. __attribute__((noreturn))
  25442. #endif
  25443. {
  25444. OTL_THROW((otl_exception(otl_error_msg_34, otl_error_code_34,
  25445. this->get_stm_text())));
  25446. }
  25447. public:
  25448. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  25449. otl_for_range_loop_ora_stream_adapter begin(){
  25450. if(!eof())
  25451. return otl_for_range_loop_ora_stream_adapter(*this);
  25452. else
  25453. return otl_for_range_loop_ora_stream_adapter();
  25454. }
  25455. otl_for_range_loop_ora_stream_adapter end(){
  25456. return otl_for_range_loop_ora_stream_adapter();
  25457. }
  25458. #endif
  25459. void set_batch_error_mode(const bool batch_error_mode) {
  25460. if (shell && shell->stream_type == otl_inout_stream_type)
  25461. (*io)->set_batch_error_mode(batch_error_mode);
  25462. }
  25463. OTL_NODISCARD int get_number_of_errors_in_batch() {
  25464. if (shell && shell->stream_type == otl_inout_stream_type)
  25465. return (*io)->get_number_of_errors_in_batch();
  25466. else
  25467. return 0;
  25468. }
  25469. void get_error(const int error_ndx, int &dml_row_offset,
  25470. otl_exception &exception) {
  25471. if (shell && shell->stream_type == otl_inout_stream_type)
  25472. (*io)->get_error(error_ndx, dml_row_offset, exception);
  25473. }
  25474. OTL_NODISCARD int get_auto_commit_flag() const {
  25475. if (!auto_commit_flag)
  25476. return 0;
  25477. else
  25478. return *auto_commit_flag;
  25479. }
  25480. OTL_NODISCARD bool get_lob_stream_flag() const {
  25481. if (!shell)
  25482. return false;
  25483. else
  25484. return shell->lob_stream_flag;
  25485. }
  25486. OTL_NODISCARD int get_adb_max_long_size() const {
  25487. return this->shell->adb->get_max_long_size();
  25488. }
  25489. void check_end_of_row() {
  25490. if (next_ov_ndx == nullptr || (*next_ov_ndx) != 0)
  25491. throw_end_of_row();
  25492. if (next_iov_ndx == nullptr || (*next_iov_ndx) != 0)
  25493. throw_end_of_row();
  25494. }
  25495. OTL_NODISCARD int get_prefetched_row_count() const {
  25496. switch (shell->stream_type) {
  25497. case otl_no_stream_type:
  25498. case otl_inout_stream_type:
  25499. return 0;
  25500. case otl_select_stream_type:
  25501. return (*ss)->get_prefetched_row_count();
  25502. case otl_refcur_stream_type:
  25503. return (*ref_ss)->get_prefetched_row_count();
  25504. default:
  25505. return 0;
  25506. }
  25507. }
  25508. OTL_NODISCARD int get_dirty_buf_len() const {
  25509. switch (shell->stream_type) {
  25510. case otl_no_stream_type:
  25511. return 0;
  25512. case otl_inout_stream_type:
  25513. return (*io)->get_dirty_buf_len();
  25514. case otl_select_stream_type: {
  25515. int rc = (*ss)->get_select_row_count();
  25516. if (rc < 0)
  25517. return 0;
  25518. else
  25519. return rc;
  25520. }
  25521. case otl_refcur_stream_type:
  25522. return (*ref_ss)->get_select_row_count();
  25523. default:
  25524. return 0;
  25525. }
  25526. }
  25527. OTL_NODISCARD otl_stream_shell *get_shell() { return shell; }
  25528. OTL_NODISCARD int get_connected() const { return connected; }
  25529. void setBufSize(int buf_size) { buf_size_ = buf_size; }
  25530. OTL_NODISCARD int getBufSize(void) const { return buf_size_; }
  25531. operator int(void) OTL_THROWS_OTL_EXCEPTION {
  25532. if (shell && shell->lob_stream_flag) {
  25533. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  25534. const char *stm_label = nullptr;
  25535. const char *stm_text = nullptr;
  25536. switch (shell->stream_type) {
  25537. case otl_no_stream_type:
  25538. break;
  25539. case otl_inout_stream_type:
  25540. stm_label = (*io)->get_stm_label();
  25541. stm_text = (*io)->get_stm_text();
  25542. break;
  25543. case otl_select_stream_type:
  25544. stm_label = (*ss)->get_stm_label();
  25545. stm_text = (*ss)->get_stm_text();
  25546. break;
  25547. case otl_refcur_stream_type:
  25548. stm_label = (*ref_ss)->get_stm_label();
  25549. stm_text = (*ref_ss)->get_stm_text();
  25550. break;
  25551. }
  25552. OTL_THROW((otl_exception(otl_error_msg_24, otl_error_code_24,
  25553. stm_label ? stm_label : stm_text)));
  25554. }
  25555. if (!last_oper_was_read_op) {
  25556. OTL_UNCAUGHT_EXCEPTION_RETURN(0);
  25557. const char *stm_label = nullptr;
  25558. const char *stm_text = nullptr;
  25559. switch (shell->stream_type) {
  25560. case otl_no_stream_type:
  25561. break;
  25562. case otl_inout_stream_type:
  25563. stm_label = (*io)->get_stm_label();
  25564. stm_text = (*io)->get_stm_text();
  25565. break;
  25566. case otl_select_stream_type:
  25567. stm_label = (*ss)->get_stm_label();
  25568. stm_text = (*ss)->get_stm_text();
  25569. break;
  25570. case otl_refcur_stream_type:
  25571. stm_label = (*ref_ss)->get_stm_label();
  25572. stm_text = (*ref_ss)->get_stm_text();
  25573. break;
  25574. }
  25575. OTL_THROW((otl_exception(otl_error_msg_18, otl_error_code_18,
  25576. stm_label ? stm_label : stm_text)));
  25577. }
  25578. if (end_marker == 1)
  25579. return 0;
  25580. int rc = 0;
  25581. int temp_eof = eof();
  25582. if (temp_eof && end_marker == -1 && oper_int_called == 0) {
  25583. end_marker = 1;
  25584. if (last_eof_rc == 1)
  25585. rc = 0;
  25586. else
  25587. rc = 1;
  25588. } else if (!temp_eof && end_marker == -1)
  25589. rc = 1;
  25590. else if (temp_eof && end_marker == -1) {
  25591. end_marker = 0;
  25592. rc = 1;
  25593. } else if (temp_eof && end_marker == 0) {
  25594. end_marker = 1;
  25595. rc = 0;
  25596. }
  25597. if (!oper_int_called)
  25598. oper_int_called = 1;
  25599. return rc;
  25600. }
  25601. #if !defined(OTL_UNICODE)
  25602. static void create_stored_proc_call(
  25603. otl_connect &db, otl_stream &args_strm, char *sql_stm, int &stm_type,
  25604. char *refcur_placeholder, const char *proc_name, const char *package_name,
  25605. const char *schema_name = nullptr,
  25606. const bool schema_name_included = false, const int varchar_size = 2001,
  25607. const int all_num2type = otl_var_double, const int refcur_buf_size = 1) {
  25608. sql_stm[0] = 0;
  25609. stm_type = otl_no_stream_type;
  25610. refcur_placeholder[0] = 0;
  25611. char full_name[1024];
  25612. char temp_buf[1024];
  25613. char temp_buf2[1024];
  25614. int i;
  25615. if (package_name == nullptr)
  25616. #if defined(__clang__)
  25617. #pragma clang diagnostic push
  25618. #pragma clang diagnostic ignored "-Wunused-value"
  25619. #endif
  25620. OTL_SPRINTF_S(full_name, sizeof(full_name), "%s", proc_name);
  25621. #if defined(__clang__)
  25622. #pragma clang diagnostic pop
  25623. #endif
  25624. else
  25625. #if defined(__clang__)
  25626. #pragma clang diagnostic push
  25627. #pragma clang diagnostic ignored "-Wunused-value"
  25628. #endif
  25629. OTL_SPRINTF_S(full_name, sizeof(full_name), "%s.%s", package_name, proc_name);
  25630. #if defined(__clang__)
  25631. #pragma clang diagnostic pop
  25632. #endif
  25633. if (schema_name_included && schema_name != nullptr) {
  25634. #if defined(__clang__)
  25635. #pragma clang diagnostic push
  25636. #pragma clang diagnostic ignored "-Wunused-value"
  25637. #endif
  25638. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "%s.%s", schema_name, full_name);
  25639. #if defined(__clang__)
  25640. #pragma clang diagnostic pop
  25641. #endif
  25642. OTL_STRCPY_S(full_name, sizeof(full_name), temp_buf);
  25643. }
  25644. if (!args_strm.good()) {
  25645. args_strm.open(
  25646. 50,
  25647. #if defined(OTL_ORA11G) || defined(OTL_ORA11G_R2)
  25648. "select nvl(position,1) position, "
  25649. " lower(':'||nvl(argument_name,'rc__')) argument_name, "
  25650. " in_out, "
  25651. " nvl(data_type,'*') data_type, "
  25652. " ':'||lower(nvl(argument_name,'rc__'))|| "
  25653. " decode(data_type,'REF CURSOR',' ', "
  25654. " '<'||'%s,'|| "
  25655. " decode(in_out,'IN','in', "
  25656. " 'OUT','out', "
  25657. " 'IN/OUT','inout', "
  25658. " 'xxx') "
  25659. " ||'>' "
  25660. " ) || decode(position,0,' := ',' ') "
  25661. " bind_var "
  25662. "from all_arguments a, all_procedures p "
  25663. "where upper(:obj_name/*char[50]*/) in "
  25664. "(p.procedure_name,p.object_name) "
  25665. "and (:pkg_name/*char[50]*/ is null and "
  25666. " p.procedure_name is null or "
  25667. " :pkg_name is not NULL and "
  25668. " (p.object_name=upper(:pkg_name) or "
  25669. " p.object_name = "
  25670. " (select package_name from "
  25671. " (select table_name as package_name "
  25672. " from user_synonyms "
  25673. " where synonym_name=upper(:pkg_name) "
  25674. " union all "
  25675. " select table_name as package_name "
  25676. " from all_synonyms "
  25677. " where synonym_name=upper(:pkg_name) "
  25678. " ) "
  25679. " where rownum = 1) "
  25680. ")) "
  25681. "and ((:owner/*char[50]*/ is null "
  25682. " and p.owner = "
  25683. " (select owner from "
  25684. " (select user as owner "
  25685. " from user_objects "
  25686. " where object_name = upper(nvl(:pkg_name, :obj_name)) "
  25687. " and object_type in ('PACKAGE','FUNCTION','PROCEDURE') "
  25688. " union all "
  25689. " select table_owner as owner "
  25690. " from user_synonyms "
  25691. " where synonym_name = upper(nvl(:pkg_name, :obj_name)) "
  25692. " union all "
  25693. " select table_owner as owner "
  25694. " from all_synonyms "
  25695. " where synonym_name = upper(nvl(:pkg_name, :obj_name)) "
  25696. " ) "
  25697. " where rownum = 1) "
  25698. " or "
  25699. " (:owner is not null and p.owner=upper(:owner))) "
  25700. " and a.data_level(+)=0 "
  25701. " ) "
  25702. "and a.object_id(+) = p.object_id "
  25703. "and a.subprogram_id(+) = p.subprogram_id "
  25704. "and a.owner(+) = p.owner "
  25705. "order by a.position ",
  25706. #else
  25707. "select position, "
  25708. " lower(':'||nvl(argument_name,'rc__')) argument_name, "
  25709. " in_out, "
  25710. " nvl(data_type,'*') data_type, "
  25711. " ':'||lower(nvl(argument_name,'rc__'))|| "
  25712. " decode(data_type,'REF CURSOR',' ', "
  25713. " '<'||'%s,'|| "
  25714. " decode(in_out,'IN','in', "
  25715. " 'OUT','out', "
  25716. " 'IN/OUT','inout', "
  25717. " 'xxx') "
  25718. " ||'>' "
  25719. " ) || decode(position,0,' := ',' ') "
  25720. " bind_var "
  25721. "from all_arguments "
  25722. "where object_name=upper(:obj_name<char[50]>) "
  25723. " and (:pkg_name<char[50]> is null and package_name is null or "
  25724. " :pkg_name is not null "
  25725. " and (package_name=upper(:pkg_name) "
  25726. " or package_name = "
  25727. " (select package_name from "
  25728. " (select table_name as package_name "
  25729. " from user_synonyms "
  25730. " where synonym_name=upper(:pkg_name) "
  25731. " union all "
  25732. " select table_name as package_name "
  25733. " from all_synonyms "
  25734. " where synonym_name=upper(:pkg_name) "
  25735. " )"
  25736. " where rownum = 1)"
  25737. " )) "
  25738. " and ((:owner<char[50]> is null "
  25739. " and owner= "
  25740. " (select owner from "
  25741. " (select user as owner "
  25742. " from user_objects "
  25743. " where (:pkg_name is not null "
  25744. " and object_name = upper(:pkg_name) "
  25745. " and object_type = 'PACKAGE') "
  25746. " or (:pkg_name is null "
  25747. " and object_name = upper(:obj_name) "
  25748. " and object_type in ('FUNCTION','PROCEDURE')) "
  25749. " union all "
  25750. " select table_owner as owner "
  25751. " from user_synonyms "
  25752. " where (:pkg_name is not null "
  25753. " and synonym_name = upper(:pkg_name)) "
  25754. " or (:pkg_name is null "
  25755. " and synonym_name = upper(:obj_name)) "
  25756. " union all "
  25757. " select table_owner as owner "
  25758. " from all_synonyms "
  25759. " where (:pkg_name is not null "
  25760. " and synonym_name = upper(:pkg_name)) "
  25761. " or (:pkg_name is null "
  25762. " and synonym_name = upper(:obj_name)) "
  25763. " ) "
  25764. " where rownum = 1) "
  25765. " or "
  25766. " (:owner is not null and owner=upper(:owner))) "
  25767. " and data_level=0 )"
  25768. "order by position",
  25769. #endif
  25770. db);
  25771. }
  25772. otl_auto_array_ptr<otl_Tptr<otl_sp_parm_desc> > desc(otl_var_list_size);
  25773. int desc_len = 0;
  25774. otl_sp_parm_desc parm;
  25775. args_strm << proc_name;
  25776. if (package_name == nullptr)
  25777. args_strm << otl_null();
  25778. else
  25779. args_strm << package_name;
  25780. if (schema_name == nullptr)
  25781. args_strm << otl_null();
  25782. else
  25783. args_strm << schema_name;
  25784. while (!args_strm.eof()) {
  25785. args_strm >> parm.position;
  25786. args_strm >> parm.arg_name;
  25787. args_strm >> parm.in_out;
  25788. args_strm >> parm.data_type;
  25789. args_strm >> parm.bind_var;
  25790. ++desc_len;
  25791. if (desc_len == desc.get_arr_size()) {
  25792. int j;
  25793. for (j = 0; j < desc.get_arr_size(); ++j)
  25794. desc.get_ptr()[j].set_do_not_destroy(true);
  25795. desc.double_size();
  25796. for (j = 0; j < desc.get_arr_size(); ++j)
  25797. desc.get_ptr()[j].set_do_not_destroy(false);
  25798. }
  25799. desc.get_ptr()[desc_len - 1].assign(new otl_sp_parm_desc(parm));
  25800. }
  25801. if (desc_len == 0) {
  25802. #if defined(__clang__)
  25803. #pragma clang diagnostic push
  25804. #pragma clang diagnostic ignored "-Wunused-value"
  25805. #endif
  25806. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name);
  25807. #if defined(__clang__)
  25808. #pragma clang diagnostic pop
  25809. #endif
  25810. {
  25811. // last ditch attemp to identify a global SP with no parms
  25812. bool global_sp_no_parms = false;
  25813. if (schema_name == nullptr) {
  25814. // schema name is not specified
  25815. otl_stream s2(1, "select 1 cnt "
  25816. "from user_procedures "
  25817. "where object_name=UPPER(:obj_name<char[50]>) "
  25818. " and procedure_name is null "
  25819. #if defined(OTL_ORA11G) || defined(OTL_ORA11G_R2)
  25820. " and object_type='PROCEDURE' "
  25821. #endif
  25822. "union all "
  25823. "select 1 cnt "
  25824. "from user_synonyms syn "
  25825. "where syn.synonym_name=UPPER(:obj_name) "
  25826. " and exists "
  25827. " (select 'x' "
  25828. " from all_procedures proc "
  25829. " where proc.owner=syn.table_owner "
  25830. " and proc.object_name=syn.table_name) "
  25831. "union all "
  25832. "select 1 cnt "
  25833. "from all_synonyms syn "
  25834. "where syn.synonym_name=UPPER(:obj_name) "
  25835. " and syn.owner='PUBLIC' "
  25836. " and exists "
  25837. " (select 'x' "
  25838. " from all_procedures proc "
  25839. " where proc.owner=syn.table_owner "
  25840. " and proc.object_name=syn.table_name)",
  25841. db);
  25842. s2 << proc_name;
  25843. global_sp_no_parms = !s2.eof();
  25844. } else {
  25845. // schema name is specified
  25846. otl_stream s2(1, "select object_name "
  25847. "from all_procedures "
  25848. "where object_name=UPPER(:obj_name<char[50]>) "
  25849. " and procedure_name is null "
  25850. " and object_type='PROCEDURE' "
  25851. " AND owner=UPPER(:owner<char[50]>) "
  25852. "union all "
  25853. "select synonym_name "
  25854. "from all_synonyms syn "
  25855. "where syn.synonym_name=UPPER(:obj_name) "
  25856. " AND syn.owner=UPPER(:owner) "
  25857. " and exists "
  25858. " (select 'x' "
  25859. " from all_procedures proc "
  25860. " where proc.owner=syn.table_owner "
  25861. " and proc.object_name=syn.table_name)",
  25862. db);
  25863. s2 << proc_name;
  25864. s2 << schema_name;
  25865. global_sp_no_parms = !s2.eof();
  25866. }
  25867. if (global_sp_no_parms) {
  25868. // procedure without any parameters
  25869. otl_strcat(sql_stm, "BEGIN ");
  25870. otl_strcat(sql_stm, full_name);
  25871. otl_strcat(sql_stm, "; END;");
  25872. stm_type = otl_constant_sql_type;
  25873. return;
  25874. } else {
  25875. OTL_THROW((otl_exception(otl_error_msg_13, otl_error_code_13, temp_buf)));
  25876. }
  25877. }
  25878. }
  25879. if (desc_len == 1) {
  25880. if (desc.get_ptr()[0].get_ptr()->position == 1 &&
  25881. desc.get_ptr()[0].get_ptr()->data_type[0] == '*') {
  25882. // procedure without any parameters
  25883. otl_strcat(sql_stm, "BEGIN ");
  25884. otl_strcat(sql_stm, full_name);
  25885. otl_strcat(sql_stm, "; END;");
  25886. stm_type = otl_constant_sql_type;
  25887. return;
  25888. }
  25889. if (desc.get_ptr()[0].get_ptr()->position == 1 &&
  25890. desc.get_ptr()[0].get_ptr()->data_type[0] != '*') {
  25891. // procedure with one parameter
  25892. if (strcmp(desc.get_ptr()[0].get_ptr()->data_type, "REF CURSOR") == 0) {
  25893. // procedure with one parameter of refcur type
  25894. if (strcmp(desc.get_ptr()[0].get_ptr()->in_out, "IN") == 0) {
  25895. // refcur parameter should be either OUT or IN OUT, not IN.
  25896. #if defined(__clang__)
  25897. #pragma clang diagnostic push
  25898. #pragma clang diagnostic ignored "-Wunused-value"
  25899. #endif
  25900. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name);
  25901. #if defined(__clang__)
  25902. #pragma clang diagnostic pop
  25903. #endif
  25904. OTL_THROW((otl_exception(otl_error_msg_15, otl_error_code_15, temp_buf,
  25905. nullptr)));
  25906. }
  25907. otl_strcat(sql_stm, "BEGIN ");
  25908. otl_strcat(sql_stm, full_name);
  25909. otl_strcat(sql_stm, "(");
  25910. otl_strcat(sql_stm, desc.get_ptr()[0].get_ptr()->bind_var);
  25911. otl_strcat(sql_stm, "); END;");
  25912. stm_type = otl_refcur_stream_type;
  25913. otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder),
  25914. OTL_RCAST(const unsigned char *,
  25915. desc.get_ptr()[0].get_ptr()->arg_name));
  25916. return;
  25917. } else {
  25918. // procedure with one scalar parameter
  25919. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  25920. desc.get_ptr()[0].get_ptr()->data_type,
  25921. varchar_size, all_num2type,
  25922. refcur_buf_size);
  25923. if (temp_buf[0] == 0) {
  25924. #if defined(__clang__)
  25925. #pragma clang diagnostic push
  25926. #pragma clang diagnostic ignored "-Wunused-value"
  25927. #endif
  25928. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  25929. full_name, desc.get_ptr()[0].get_ptr()->arg_name);
  25930. #if defined(__clang__)
  25931. #pragma clang diagnostic pop
  25932. #endif
  25933. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  25934. nullptr)));
  25935. }
  25936. #if defined(__clang__)
  25937. #pragma clang diagnostic push
  25938. #pragma clang diagnostic ignored "-Wunused-value"
  25939. #endif
  25940. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  25941. desc.get_ptr()[0].get_ptr()->bind_var, temp_buf);
  25942. #if defined(__clang__)
  25943. #pragma clang diagnostic pop
  25944. #endif
  25945. otl_strcat(sql_stm, "BEGIN ");
  25946. otl_strcat(sql_stm, full_name);
  25947. otl_strcat(sql_stm, "(");
  25948. otl_strcat(sql_stm, temp_buf2);
  25949. otl_strcat(sql_stm, "); END;");
  25950. stm_type = otl_inout_stream_type;
  25951. refcur_placeholder[0] = 0;
  25952. return;
  25953. }
  25954. } else if (desc.get_ptr()[0].get_ptr()->position == 0) {
  25955. if (strcmp(desc.get_ptr()[0].get_ptr()->data_type, "REF CURSOR") == 0) {
  25956. // refcur function without any parameters
  25957. otl_strcat(sql_stm, "BEGIN ");
  25958. otl_strcat(sql_stm, desc.get_ptr()[0].get_ptr()->bind_var);
  25959. otl_strcat(sql_stm, " ");
  25960. otl_strcat(sql_stm, full_name);
  25961. otl_strcat(sql_stm, "; END;");
  25962. stm_type = otl_refcur_stream_type;
  25963. otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder),
  25964. OTL_RCAST(const unsigned char *,
  25965. desc.get_ptr()[0].get_ptr()->arg_name));
  25966. return;
  25967. } else {
  25968. // scalar function without any parameters
  25969. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  25970. desc.get_ptr()[0].get_ptr()->data_type,
  25971. varchar_size, all_num2type,
  25972. refcur_buf_size);
  25973. if (temp_buf[0] == 0) {
  25974. #if defined(__clang__)
  25975. #pragma clang diagnostic push
  25976. #pragma clang diagnostic ignored "-Wunused-value"
  25977. #endif
  25978. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  25979. full_name, desc.get_ptr()[0].get_ptr()->arg_name);
  25980. #if defined(__clang__)
  25981. #pragma clang diagnostic pop
  25982. #endif
  25983. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  25984. nullptr)));
  25985. }
  25986. #if defined(__clang__)
  25987. #pragma clang diagnostic push
  25988. #pragma clang diagnostic ignored "-Wunused-value"
  25989. #endif
  25990. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  25991. desc.get_ptr()[0].get_ptr()->bind_var, temp_buf);
  25992. #if defined(__clang__)
  25993. #pragma clang diagnostic pop
  25994. #endif
  25995. otl_strcat(sql_stm, "BEGIN ");
  25996. otl_strcat(sql_stm, temp_buf2);
  25997. otl_strcat(sql_stm, " ");
  25998. otl_strcat(sql_stm, full_name);
  25999. otl_strcat(sql_stm, "; END;");
  26000. stm_type = otl_inout_stream_type;
  26001. refcur_placeholder[0] = 0;
  26002. return;
  26003. }
  26004. }
  26005. }
  26006. // Checking if the procedure is of the "refcur" type
  26007. bool refcur_flag = false;
  26008. bool refcur_outpar = false;
  26009. int refcur_count = 0;
  26010. bool inpar_only = true;
  26011. for (i = 0; i < desc_len; ++i) {
  26012. if (inpar_only &&
  26013. strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0 &&
  26014. strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") != 0)
  26015. inpar_only = false;
  26016. if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0) {
  26017. ++refcur_count;
  26018. refcur_flag = true;
  26019. if (refcur_count > 1) {
  26020. if (refcur_outpar)
  26021. refcur_outpar =
  26022. strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0;
  26023. } else
  26024. refcur_outpar =
  26025. strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0;
  26026. }
  26027. }
  26028. if (refcur_flag) {
  26029. if (!refcur_outpar) {
  26030. #if defined(__clang__)
  26031. #pragma clang diagnostic push
  26032. #pragma clang diagnostic ignored "-Wunused-value"
  26033. #endif
  26034. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name);
  26035. #if defined(__clang__)
  26036. #pragma clang diagnostic pop
  26037. #endif
  26038. OTL_THROW((otl_exception(otl_error_msg_15, otl_error_code_15, temp_buf,
  26039. nullptr)));
  26040. }
  26041. stm_type = otl_refcur_stream_type;
  26042. if (!inpar_only || refcur_count > 1)
  26043. stm_type = otl_mixed_refcur_stream_type;
  26044. refcur_placeholder[0] = 0;
  26045. sql_stm[0] = 0;
  26046. bool full_name_printed = false;
  26047. for (i = 0; i < desc_len; ++i) {
  26048. if (i == 0)
  26049. otl_strcat(sql_stm, "BEGIN ");
  26050. if (stm_type == otl_refcur_stream_type) {
  26051. // otl_refcur_stream_type
  26052. if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0)
  26053. otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder),
  26054. OTL_RCAST(const unsigned char *,
  26055. desc.get_ptr()[i].get_ptr()->arg_name));
  26056. }
  26057. // in case of a function, function's return code
  26058. if (desc.get_ptr()[i].get_ptr()->position == 0) {
  26059. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  26060. desc.get_ptr()[i].get_ptr()->data_type,
  26061. varchar_size, all_num2type,
  26062. refcur_buf_size);
  26063. if (temp_buf[0] == 0 && strcmp(desc.get_ptr()[i].get_ptr()->data_type,
  26064. "REF CURSOR") != 0) {
  26065. #if defined(__clang__)
  26066. #pragma clang diagnostic push
  26067. #pragma clang diagnostic ignored "-Wunused-value"
  26068. #endif
  26069. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  26070. full_name, desc.get_ptr()[i].get_ptr()->arg_name);
  26071. #if defined(__clang__)
  26072. #pragma clang diagnostic pop
  26073. #endif
  26074. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  26075. nullptr)));
  26076. }
  26077. if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") ==
  26078. 0 &&
  26079. stm_type == otl_refcur_stream_type)
  26080. OTL_STRCPY_S(temp_buf2, sizeof(temp_buf2),
  26081. desc.get_ptr()[i].get_ptr()->bind_var);
  26082. else if (strcmp(desc.get_ptr()[i].get_ptr()->data_type,
  26083. "REF CURSOR") == 0 &&
  26084. stm_type == otl_mixed_refcur_stream_type) {
  26085. desc.get_ptr()[i].get_ptr()->bind_var
  26086. [strlen(desc.get_ptr()[i].get_ptr()->bind_var) - 5] = 0;
  26087. #if defined(__clang__)
  26088. #pragma clang diagnostic push
  26089. #pragma clang diagnostic ignored "-Wunused-value"
  26090. #endif
  26091. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), "%s<%s> := ",
  26092. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26093. #if defined(__clang__)
  26094. #pragma clang diagnostic pop
  26095. #endif
  26096. } else
  26097. #if defined(__clang__)
  26098. #pragma clang diagnostic push
  26099. #pragma clang diagnostic ignored "-Wunused-value"
  26100. #endif
  26101. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  26102. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26103. #if defined(__clang__)
  26104. #pragma clang diagnostic pop
  26105. #endif
  26106. otl_strcat(sql_stm, temp_buf2);
  26107. }
  26108. // procedure/function's name
  26109. if (!full_name_printed) {
  26110. otl_strcat(sql_stm, full_name);
  26111. otl_strcat(sql_stm, "(");
  26112. full_name_printed = true;
  26113. }
  26114. if (desc.get_ptr()[i].get_ptr()->position != 0) {
  26115. // normal parameters
  26116. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  26117. desc.get_ptr()[i].get_ptr()->data_type,
  26118. varchar_size, all_num2type,
  26119. refcur_buf_size);
  26120. if (temp_buf[0] == 0 && strcmp(desc.get_ptr()[i].get_ptr()->data_type,
  26121. "REF CURSOR") != 0) {
  26122. #if defined(__clang__)
  26123. #pragma clang diagnostic push
  26124. #pragma clang diagnostic ignored "-Wunused-value"
  26125. #endif
  26126. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  26127. full_name, desc.get_ptr()[i].get_ptr()->arg_name);
  26128. #if defined(__clang__)
  26129. #pragma clang diagnostic pop
  26130. #endif
  26131. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  26132. nullptr)));
  26133. }
  26134. if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") ==
  26135. 0 &&
  26136. stm_type == otl_refcur_stream_type)
  26137. OTL_STRCPY_S(temp_buf2, sizeof(temp_buf2),
  26138. desc.get_ptr()[i].get_ptr()->bind_var);
  26139. else if (strcmp(desc.get_ptr()[i].get_ptr()->data_type,
  26140. "REF CURSOR") == 0 &&
  26141. stm_type == otl_mixed_refcur_stream_type) {
  26142. desc.get_ptr()[i].get_ptr()->bind_var
  26143. [strlen(desc.get_ptr()[i].get_ptr()->bind_var) - 2] = 0;
  26144. #if defined(__clang__)
  26145. #pragma clang diagnostic push
  26146. #pragma clang diagnostic ignored "-Wunused-value"
  26147. #endif
  26148. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), "%s<%s>",
  26149. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26150. #if defined(__clang__)
  26151. #pragma clang diagnostic pop
  26152. #endif
  26153. } else
  26154. #if defined(__clang__)
  26155. #pragma clang diagnostic push
  26156. #pragma clang diagnostic ignored "-Wunused-value"
  26157. #endif
  26158. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  26159. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26160. #if defined(__clang__)
  26161. #pragma clang diagnostic pop
  26162. #endif
  26163. otl_strcat(sql_stm, temp_buf2);
  26164. }
  26165. if (i < desc_len - 1 && desc.get_ptr()[i].get_ptr()->position != 0)
  26166. otl_strcat(sql_stm, ",");
  26167. else if (i == desc_len - 1)
  26168. otl_strcat(sql_stm, "); ");
  26169. }
  26170. otl_strcat(sql_stm, " END;");
  26171. return;
  26172. }
  26173. // The procedure is of the "general" type
  26174. stm_type = otl_inout_stream_type;
  26175. refcur_placeholder[0] = 0;
  26176. sql_stm[0] = 0;
  26177. bool full_name_printed = false;
  26178. for (i = 0; i < desc_len; ++i) {
  26179. if (i == 0)
  26180. otl_strcat(sql_stm, "BEGIN ");
  26181. // in case of a function, function's return code
  26182. if (desc.get_ptr()[i].get_ptr()->position == 0) {
  26183. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  26184. desc.get_ptr()[i].get_ptr()->data_type,
  26185. varchar_size, all_num2type, refcur_buf_size);
  26186. if (temp_buf[0] == 0) {
  26187. #if defined(__clang__)
  26188. #pragma clang diagnostic push
  26189. #pragma clang diagnostic ignored "-Wunused-value"
  26190. #endif
  26191. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  26192. full_name, desc.get_ptr()[i].get_ptr()->arg_name);
  26193. #if defined(__clang__)
  26194. #pragma clang diagnostic pop
  26195. #endif
  26196. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  26197. nullptr)));
  26198. }
  26199. #if defined(__clang__)
  26200. #pragma clang diagnostic push
  26201. #pragma clang diagnostic ignored "-Wunused-value"
  26202. #endif
  26203. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  26204. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26205. #if defined(__clang__)
  26206. #pragma clang diagnostic pop
  26207. #endif
  26208. otl_strcat(sql_stm, temp_buf2);
  26209. }
  26210. // procedure/function's name
  26211. if (!full_name_printed) {
  26212. otl_strcat(sql_stm, full_name);
  26213. otl_strcat(sql_stm, "(");
  26214. full_name_printed = true;
  26215. }
  26216. if (desc.get_ptr()[i].get_ptr()->position != 0) {
  26217. // normal parameters
  26218. convert_bind_var_datatype(temp_buf, sizeof(temp_buf),
  26219. desc.get_ptr()[i].get_ptr()->data_type,
  26220. varchar_size, all_num2type, refcur_buf_size);
  26221. if (temp_buf[0] == 0) {
  26222. #if defined(__clang__)
  26223. #pragma clang diagnostic push
  26224. #pragma clang diagnostic ignored "-Wunused-value"
  26225. #endif
  26226. OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s",
  26227. full_name, desc.get_ptr()[i].get_ptr()->arg_name);
  26228. #if defined(__clang__)
  26229. #pragma clang diagnostic pop
  26230. #endif
  26231. OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf,
  26232. nullptr)));
  26233. }
  26234. #if defined(__clang__)
  26235. #pragma clang diagnostic push
  26236. #pragma clang diagnostic ignored "-Wunused-value"
  26237. #endif
  26238. OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2),
  26239. desc.get_ptr()[i].get_ptr()->bind_var, temp_buf);
  26240. #if defined(__clang__)
  26241. #pragma clang diagnostic pop
  26242. #endif
  26243. otl_strcat(sql_stm, temp_buf2);
  26244. }
  26245. if (i < desc_len - 1 && desc.get_ptr()[i].get_ptr()->position != 0)
  26246. otl_strcat(sql_stm, ",");
  26247. else if (i == desc_len - 1)
  26248. otl_strcat(sql_stm, "); ");
  26249. }
  26250. otl_strcat(sql_stm, " END;");
  26251. }
  26252. #endif
  26253. OTL_NODISCARD int get_stream_type(void) OTL_NO_THROW {
  26254. if (shell == nullptr)
  26255. return otl_no_stream_type;
  26256. else
  26257. return shell->stream_type;
  26258. }
  26259. void set_column_type(const int column_ndx, const int col_type,
  26260. const int col_size = 0) OTL_NO_THROW {
  26261. if (shell == nullptr) {
  26262. init_stream();
  26263. shell->flush_flag = true;
  26264. }
  26265. override_->add_override(column_ndx, col_type, col_size);
  26266. }
  26267. void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW {
  26268. if (shell == nullptr) {
  26269. init_stream();
  26270. shell->flush_flag = true;
  26271. }
  26272. override_->set_all_column_types(mask);
  26273. }
  26274. void set_flush(const bool flush_flag = true) OTL_NO_THROW {
  26275. if (shell == nullptr)
  26276. init_stream();
  26277. shell->flush_flag = flush_flag;
  26278. }
  26279. void set_lob_stream_mode(const bool lob_stream_flag = false) OTL_NO_THROW {
  26280. if (shell == nullptr)
  26281. return;
  26282. shell->lob_stream_flag = lob_stream_flag;
  26283. }
  26284. OTL_NODISCARD otl_var_desc *describe_in_vars(int &desc_len) OTL_NO_THROW {
  26285. desc_len = 0;
  26286. if (shell == nullptr)
  26287. return nullptr;
  26288. if (shell->iov == nullptr)
  26289. return nullptr;
  26290. desc_len = shell->iov_len;
  26291. return shell->iov;
  26292. }
  26293. OTL_NODISCARD otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW {
  26294. desc_len = 0;
  26295. if (shell == nullptr)
  26296. return nullptr;
  26297. if (shell->ov == nullptr)
  26298. return nullptr;
  26299. desc_len = shell->ov_len;
  26300. return shell->ov;
  26301. }
  26302. OTL_NODISCARD otl_var_desc *describe_next_in_var(void) OTL_NO_THROW {
  26303. if (shell == nullptr)
  26304. return nullptr;
  26305. if (shell->iov == nullptr)
  26306. return nullptr;
  26307. return &(shell->iov[shell->next_iov_ndx]);
  26308. }
  26309. OTL_NODISCARD otl_var_desc *describe_next_out_var(void) OTL_NO_THROW {
  26310. if (shell == nullptr)
  26311. return nullptr;
  26312. if (shell->ov == nullptr)
  26313. return nullptr;
  26314. return &(shell->ov[shell->next_ov_ndx]);
  26315. }
  26316. OTL_NODISCARD const char *get_stm_text(void) {
  26317. const char *no_stm_text = OTL_NO_STM_TEXT;
  26318. switch (shell->stream_type) {
  26319. case otl_no_stream_type:
  26320. return no_stm_text;
  26321. case otl_inout_stream_type:
  26322. return (*io)->get_stm_label() ? (*io)->get_stm_label()
  26323. : (*io)->get_stm_text();
  26324. case otl_select_stream_type:
  26325. return (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  26326. : (*ss)->get_stm_text();
  26327. case otl_refcur_stream_type:
  26328. return (*ref_ss)->get_stm_label() ? (*ref_ss)->get_stm_label()
  26329. : (*ref_ss)->get_stm_text();
  26330. default:
  26331. return no_stm_text;
  26332. }
  26333. }
  26334. OTL_NODISCARD long get_rpc() OTL_NO_THROW {
  26335. switch (shell->stream_type) {
  26336. case otl_no_stream_type:
  26337. return 0;
  26338. case otl_inout_stream_type:
  26339. return (*io)->get_rpc();
  26340. case otl_select_stream_type:
  26341. return (*ss)->get_rfc();
  26342. case otl_refcur_stream_type:
  26343. return (*ref_ss)->get_rfc();
  26344. default:
  26345. return 0;
  26346. }
  26347. }
  26348. void create_var_desc(void) {
  26349. int i;
  26350. delete[](*iov);
  26351. delete[](*ov);
  26352. (*iov) = nullptr;
  26353. (*iov_len) = 0;
  26354. (*ov) = nullptr;
  26355. (*ov_len) = 0;
  26356. if ((*ss)) {
  26357. if ((*ss)->get_vl_len() > 0) {
  26358. (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_vl_len())];
  26359. (*iov_len) = (*ss)->get_vl_len();
  26360. for (i = 0; i < (*ss)->get_vl_len(); ++i)
  26361. (*ss)->get_vl()[i]->copy_var_desc((*iov)[i]);
  26362. }
  26363. if ((*ss)->get_sl_len() > 0) {
  26364. (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_sl_len())];
  26365. (*ov_len) = (*ss)->get_sl_len();
  26366. for (i = 0; i < (*ss)->get_sl_len(); ++i) {
  26367. (*ss)->get_sl()[i].copy_var_desc((*ov)[i]);
  26368. (*ov)[i].copy_name((*ss)->get_sl_desc()[i].name);
  26369. (*ov)[i].set_param_type(1);
  26370. }
  26371. }
  26372. } else if ((*io)) {
  26373. if ((*io)->get_vl_len() > 0) {
  26374. (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*io)->get_vl_len())];
  26375. (*iov_len) = (*io)->get_vl_len();
  26376. for (i = 0; i < (*io)->get_vl_len(); ++i)
  26377. (*io)->get_vl()[i]->copy_var_desc((*iov)[i]);
  26378. }
  26379. if ((*io)->get_iv_len() > 0) {
  26380. (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*io)->get_iv_len())];
  26381. (*ov_len) = (*io)->get_iv_len();
  26382. for (i = 0; i < (*io)->get_iv_len(); ++i)
  26383. (*io)->get_in_vl()[i]->copy_var_desc((*ov)[i]);
  26384. }
  26385. } else if ((*ref_ss)) {
  26386. if ((*ref_ss)->get_vl_len() > 0) {
  26387. (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ref_ss)->get_vl_len())];
  26388. (*iov_len) = (*ref_ss)->get_vl_len();
  26389. for (i = 0; i < (*ref_ss)->get_vl_len(); ++i)
  26390. (*ref_ss)->get_vl()[i]->copy_var_desc((*iov)[i]);
  26391. }
  26392. if ((*ref_ss)->get_sl_len() > 0) {
  26393. int temp_sl_len = (*ref_ss)->get_sl_len();
  26394. (*ov) = new otl_var_desc[OTL_SCAST(size_t,temp_sl_len)];
  26395. (*ov_len) = temp_sl_len;
  26396. for (i = 0; i < temp_sl_len; ++i) {
  26397. (*ref_ss)->get_sl()[i].copy_var_desc((*ov)[i]);
  26398. (*ov)[i].copy_name((*ref_ss)->get_sl_desc()[i].name);
  26399. }
  26400. }
  26401. }
  26402. }
  26403. void init_stream(void) {
  26404. buf_size_ = 1;
  26405. last_oper_was_read_op = false;
  26406. shell = nullptr;
  26407. shell = new otl_stream_shell(0);
  26408. shell_pt.assign(&shell);
  26409. connected = 0;
  26410. ref_ss = &(shell->ref_ss);
  26411. ss = &(shell->ss);
  26412. io = &(shell->io);
  26413. adb = &(shell->adb);
  26414. auto_commit_flag = &(shell->auto_commit_flag);
  26415. iov = &(shell->iov);
  26416. iov_len = &(shell->iov_len);
  26417. next_iov_ndx = &(shell->next_iov_ndx);
  26418. ov = &(shell->ov);
  26419. ov_len = &(shell->ov_len);
  26420. next_ov_ndx = &(shell->next_ov_ndx);
  26421. override_ = &(shell->override_);
  26422. (*ref_ss) = nullptr;
  26423. (*io) = nullptr;
  26424. (*ss) = nullptr;
  26425. (*adb) = nullptr;
  26426. (*ov) = nullptr;
  26427. (*ov_len) = 0;
  26428. (*next_iov_ndx) = 0;
  26429. (*next_ov_ndx) = 0;
  26430. (*auto_commit_flag) = 1;
  26431. (*iov) = nullptr;
  26432. (*iov_len) = 0;
  26433. }
  26434. otl_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm,
  26435. otl_connect &db, const char *ref_cur_placeholder = nullptr,
  26436. const char *sqlstm_label = nullptr)
  26437. OTL_THROWS_OTL_EXCEPTION:
  26438. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  26439. otl_read_stream_interface(),
  26440. #endif
  26441. shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr),
  26442. io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr),
  26443. iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr),
  26444. next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0),
  26445. last_oper_was_read_op(false), override_(nullptr), buf_size_(0) {
  26446. init_stream();
  26447. (*io) = nullptr;
  26448. (*ss) = nullptr;
  26449. (*ref_ss) = nullptr;
  26450. (*iov) = nullptr;
  26451. (*iov_len) = 0;
  26452. (*ov) = nullptr;
  26453. (*ov_len) = 0;
  26454. (*auto_commit_flag) = 1;
  26455. (*next_iov_ndx) = 0;
  26456. (*next_ov_ndx) = 0;
  26457. (*adb) = &db;
  26458. shell->flush_flag = true;
  26459. open(arr_size, sqlstm, db, ref_cur_placeholder, sqlstm_label);
  26460. }
  26461. otl_stream() OTL_NO_THROW :
  26462. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  26463. otl_read_stream_interface(),
  26464. #endif
  26465. shell(nullptr),
  26466. shell_pt(),
  26467. connected(0),
  26468. ref_ss(nullptr),
  26469. ss(nullptr),
  26470. io(nullptr),
  26471. adb(nullptr),
  26472. auto_commit_flag(nullptr),
  26473. iov(nullptr),
  26474. iov_len(nullptr),
  26475. next_iov_ndx(nullptr),
  26476. ov(nullptr),
  26477. ov_len(nullptr),
  26478. next_ov_ndx(nullptr),
  26479. end_marker(0),
  26480. oper_int_called(0),
  26481. last_eof_rc(0),
  26482. last_oper_was_read_op(false),
  26483. override_(nullptr),
  26484. buf_size_(0) {
  26485. init_stream();
  26486. shell->flush_flag = true;
  26487. }
  26488. virtual ~otl_stream()
  26489. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  26490. OTL_THROWS_OTL_EXCEPTION
  26491. #else
  26492. OTL_NO_THROW
  26493. #endif
  26494. {
  26495. if (!connected)
  26496. return;
  26497. try {
  26498. if ((*io) != nullptr && shell->flush_flag == false)
  26499. (*io)->set_flush_flag2(false);
  26500. close();
  26501. if (shell != nullptr) {
  26502. if ((*io) != nullptr)
  26503. (*io)->set_flush_flag2(true);
  26504. }
  26505. }
  26506. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26507. if (shell != nullptr) {
  26508. if ((*io) != nullptr)
  26509. (*io)->set_flush_flag2(true);
  26510. }
  26511. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  26512. defined(OTL_STREAM_POOLING_ON)
  26513. clean(1);
  26514. if (shell != nullptr)
  26515. shell->set_should_delete(1);
  26516. shell_pt.destroy();
  26517. #else
  26518. shell_pt.destroy();
  26519. #endif
  26520. #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW)
  26521. throw;
  26522. #endif
  26523. }
  26524. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  26525. defined(OTL_STREAM_POOLING_ON)
  26526. if(otl_uncaught_exception()){}
  26527. #else
  26528. shell_pt.destroy();
  26529. #endif
  26530. }
  26531. OTL_NODISCARD int eof(void) OTL_THROWS_OTL_EXCEPTION{
  26532. if ((*io)) {
  26533. return (*io)->eof();
  26534. } else if ((*ss)) {
  26535. return (*ss)->eof();
  26536. } else if ((*ref_ss)) {
  26537. return (*ref_ss)->eof();
  26538. } else
  26539. return 1;
  26540. }
  26541. void skip_to_end_of_row() OTL_NO_THROW {
  26542. if (next_ov_ndx == nullptr)
  26543. return;
  26544. if ((*ov_len) == 0)
  26545. return;
  26546. last_oper_was_read_op = true;
  26547. switch (shell->stream_type) {
  26548. case otl_no_stream_type:
  26549. break;
  26550. case otl_inout_stream_type:
  26551. last_eof_rc = (*io)->eof();
  26552. (*io)->skip_to_end_of_row();
  26553. break;
  26554. case otl_select_stream_type:
  26555. last_eof_rc = (*ss)->eof();
  26556. (*ss)->skip_to_end_of_row();
  26557. break;
  26558. case otl_refcur_stream_type:
  26559. last_eof_rc = (*ref_ss)->eof();
  26560. (*ref_ss)->skip_to_end_of_row();
  26561. break;
  26562. }
  26563. *next_ov_ndx = 0;
  26564. }
  26565. void skip_to_next_var() OTL_NO_THROW {
  26566. if (next_ov_ndx == nullptr)
  26567. return;
  26568. if ((*ov_len) == 0)
  26569. return;
  26570. last_oper_was_read_op = true;
  26571. switch (shell->stream_type) {
  26572. case otl_no_stream_type:
  26573. break;
  26574. case otl_inout_stream_type:
  26575. last_eof_rc = (*io)->eof();
  26576. (*io)->skip_to_next_var();
  26577. break;
  26578. case otl_select_stream_type:
  26579. last_eof_rc = (*ss)->eof();
  26580. (*ss)->skip_to_next_var();
  26581. break;
  26582. case otl_refcur_stream_type:
  26583. last_eof_rc = (*ref_ss)->eof();
  26584. (*ref_ss)->skip_to_next_var();
  26585. break;
  26586. }
  26587. if((*next_ov_ndx)<(*ov_len)-1)
  26588. ++(*next_ov_ndx);
  26589. }
  26590. void reset_to_last_valid_row() {
  26591. if ((*io)) {
  26592. (*io)->reset_to_last_valid_row();
  26593. }
  26594. }
  26595. void flush(const int rowoff = 0,
  26596. const bool force_flush = false) OTL_THROWS_OTL_EXCEPTION {
  26597. if ((*io)) {
  26598. (*io)->flush(rowoff, force_flush);
  26599. }
  26600. }
  26601. OTL_NODISCARD bool get_error_state(void) const {
  26602. if (otl_uncaught_exception())
  26603. return true;
  26604. else if ((*io))
  26605. return (*io)->get_error_state();
  26606. else
  26607. return false;
  26608. }
  26609. void clean(const int clean_up_error_flag = 0) OTL_THROWS_OTL_EXCEPTION {
  26610. if(next_ov_ndx!=nullptr)(*next_ov_ndx)=0;
  26611. if(next_iov_ndx!=nullptr)(*next_iov_ndx)=0;
  26612. if ((*io)) {
  26613. (*io)->clean(clean_up_error_flag);
  26614. } else if (*ss) {
  26615. (*ss)->clean();
  26616. } else if (*ref_ss) {
  26617. (*ref_ss)->clean();
  26618. }
  26619. }
  26620. void rewind(void) OTL_THROWS_OTL_EXCEPTION {
  26621. if ((*io)) {
  26622. (*io)->rewind();
  26623. } else if ((*ss)) {
  26624. (*ss)->rewind();
  26625. } else if ((*ref_ss)) {
  26626. (*ref_ss)->rewind();
  26627. }
  26628. }
  26629. OTL_NODISCARD int is_null(void) OTL_NO_THROW {
  26630. if ((*io))
  26631. return (*io)->is_null();
  26632. else if ((*ss))
  26633. return (*ss)->is_null();
  26634. else if ((*ref_ss))
  26635. return (*ref_ss)->is_null();
  26636. else
  26637. return 0;
  26638. }
  26639. void set_commit(int auto_commit = 0) OTL_NO_THROW {
  26640. (*auto_commit_flag) = auto_commit;
  26641. if ((*io)) {
  26642. (*io)->set_commit(auto_commit);
  26643. }
  26644. }
  26645. void open(const otl_stream_buffer_size_type arr_size, const char *sqlstm,
  26646. otl_connect &db, const char *ref_cur_placeholder = nullptr,
  26647. const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION {
  26648. if (arr_size <= 0) {
  26649. OTL_THROW((otl_exception(otl_error_msg_40, otl_error_code_40, sqlstm)));
  26650. }
  26651. #if defined(OTL_STREAM_THROWS_NOT_CONNECTED_TO_DATABASE_EXCEPTION)
  26652. if (!db.connected) {
  26653. OTL_THROW((otl_exception(otl_error_msg_35, otl_error_code_35, sqlstm)));
  26654. }
  26655. #endif
  26656. reset_end_marker();
  26657. if (this->good()) {
  26658. const char *temp_stm_text = nullptr;
  26659. switch (shell->stream_type) {
  26660. case otl_no_stream_type:
  26661. temp_stm_text = OTL_NO_STM_TEXT;
  26662. break;
  26663. case otl_inout_stream_type:
  26664. temp_stm_text = (*io)->get_stm_label() ? (*io)->get_stm_label()
  26665. : (*io)->get_stm_text();
  26666. break;
  26667. case otl_select_stream_type:
  26668. temp_stm_text = (*ss)->get_stm_label() ? (*ss)->get_stm_label()
  26669. : (*ss)->get_stm_text();
  26670. break;
  26671. case otl_refcur_stream_type:
  26672. temp_stm_text = (*ref_ss)->get_stm_label() ? (*ref_ss)->get_stm_label()
  26673. : (*ref_ss)->get_stm_text();
  26674. break;
  26675. default:
  26676. temp_stm_text = OTL_NO_STM_TEXT;
  26677. break;
  26678. }
  26679. OTL_THROW((otl_exception(otl_error_msg_29, otl_error_code_29, temp_stm_text)));
  26680. }
  26681. if (shell == nullptr)
  26682. init_stream();
  26683. buf_size_ = arr_size;
  26684. OTL_TRACE_STREAM_OPEN2
  26685. #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \
  26686. defined(OTL_STREAM_POOLING_ON)
  26687. if (*adb == nullptr)
  26688. *adb = &db;
  26689. if ((*adb) && (**adb).get_stream_pool_enabled_flag()) {
  26690. char temp_buf[128];
  26691. otl_itoa(arr_size, temp_buf);
  26692. const char delimiter = ';';
  26693. #if defined(OTL_STREAM_POOL_USES_STREAM_LABEL_AS_KEY)
  26694. const char *temp_label = sqlstm_label ? sqlstm_label : sqlstm;
  26695. #if defined(OTL_UNICODE_STRING_TYPE)
  26696. std::string sql_stm(temp_label);
  26697. sql_stm += delimiter;
  26698. sql_stm += std::string(temp_buf);
  26699. #else
  26700. OTL_STRING_CONTAINER sql_stm(temp_label);
  26701. sql_stm += delimiter;
  26702. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  26703. #endif
  26704. #else
  26705. #if defined(OTL_UNICODE_STRING_TYPE)
  26706. std::string sql_stm(sqlstm);
  26707. #else
  26708. OTL_STRING_CONTAINER sql_stm(sqlstm);
  26709. #endif
  26710. sql_stm += delimiter;
  26711. #if defined(OTL_UNICODE_STRING_TYPE)
  26712. sql_stm += std::string(temp_buf);
  26713. #else
  26714. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  26715. #endif
  26716. #endif
  26717. if (shell != nullptr) {
  26718. otl_select_struct_override &temp_override = shell->override_;
  26719. for (int i = 0; i < temp_override.getLen(); ++i) {
  26720. otl_itoa(OTL_SCAST(int, temp_override.get_col_type(i)), temp_buf);
  26721. sql_stm += delimiter;
  26722. #if defined(OTL_UNICODE_STRING_TYPE)
  26723. sql_stm += std::string(temp_buf);
  26724. #else
  26725. sql_stm += OTL_STRING_CONTAINER(temp_buf);
  26726. #endif
  26727. }
  26728. }
  26729. otl_stream_shell_generic *temp_shell = db.get_sc().find(sql_stm);
  26730. if (temp_shell) {
  26731. if (shell != nullptr)
  26732. shell_pt.destroy();
  26733. shell = OTL_RCAST(otl_stream_shell *, temp_shell);
  26734. ref_ss = &(shell->ref_ss);
  26735. ss = &(shell->ss);
  26736. io = &(shell->io);
  26737. if ((*io) != nullptr){
  26738. (*io)->set_flush_flag2(true);
  26739. }
  26740. adb = &(shell->adb);
  26741. auto_commit_flag = &(shell->auto_commit_flag);
  26742. iov = &(shell->iov);
  26743. iov_len = &(shell->iov_len);
  26744. next_iov_ndx = &(shell->next_iov_ndx);
  26745. ov = &(shell->ov);
  26746. ov_len = &(shell->ov_len);
  26747. next_ov_ndx = &(shell->next_ov_ndx);
  26748. override_ = &(shell->override_);
  26749. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  26750. try {
  26751. if ((*iov_len) == 0)
  26752. this->rewind();
  26753. }
  26754. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26755. if ((*adb))
  26756. (*adb)->get_sc().remove(shell, shell->orig_sql_stm);
  26757. intern_cleanup();
  26758. shell_pt.destroy();
  26759. connected = 0;
  26760. throw;
  26761. }
  26762. connected = 1;
  26763. return;
  26764. }
  26765. shell->orig_sql_stm = sql_stm;
  26766. }
  26767. #endif
  26768. delete[](*iov);
  26769. delete[](*ov);
  26770. (*iov) = nullptr;
  26771. (*iov_len) = 0;
  26772. (*ov) = nullptr;
  26773. (*ov_len) = 0;
  26774. (*next_iov_ndx) = 0;
  26775. (*next_ov_ndx) = 0;
  26776. char tmp[7];
  26777. char *c = OTL_CCAST(char *, sqlstm);
  26778. while (otl_isspace(*c) || (*c) == '(')
  26779. ++c;
  26780. OTL_STRNCPY_S(tmp, sizeof(tmp), c, 6);
  26781. tmp[6] = 0;
  26782. c = tmp;
  26783. while (*c) {
  26784. *c = OTL_SCAST(char, otl_to_upper(*c));
  26785. ++c;
  26786. }
  26787. if (adb == nullptr)
  26788. adb = &(shell->adb);
  26789. (*adb) = &db;
  26790. try {
  26791. if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0) &&
  26792. ref_cur_placeholder == nullptr) {
  26793. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  26794. (*ss) = new otl_select_stream(override_, arr_size, sqlstm, db,
  26795. otl_explicit_select, sqlstm_label);
  26796. shell->stream_type = otl_select_stream_type;
  26797. } else if (ref_cur_placeholder != nullptr) {
  26798. override_->set_master_stream_ptr(OTL_RCAST(void *, this));
  26799. (*ref_ss) = new otl_ref_select_stream(
  26800. override_, arr_size, sqlstm, ref_cur_placeholder, db, sqlstm_label);
  26801. shell->stream_type = otl_refcur_stream_type;
  26802. } else {
  26803. (*io) = new otl_inout_stream(
  26804. arr_size, sqlstm, db, OTL_RCAST(void *, this), false, sqlstm_label);
  26805. (*io)->set_flush_flag(shell->flush_flag);
  26806. shell->stream_type = otl_inout_stream_type;
  26807. }
  26808. }
  26809. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26810. shell_pt.destroy();
  26811. throw;
  26812. }
  26813. if ((*io))
  26814. (*io)->set_commit((*auto_commit_flag));
  26815. create_var_desc();
  26816. connected = 1;
  26817. }
  26818. void intern_cleanup(void) {
  26819. delete[](*iov);
  26820. delete[](*ov);
  26821. (*iov) = nullptr;
  26822. (*iov_len) = 0;
  26823. (*ov) = nullptr;
  26824. (*ov_len) = 0;
  26825. (*next_iov_ndx) = 0;
  26826. (*next_ov_ndx) = 0;
  26827. override_->setLen(0);
  26828. switch (shell->stream_type) {
  26829. case otl_no_stream_type:
  26830. break;
  26831. case otl_inout_stream_type:
  26832. try {
  26833. if ((*io) != nullptr) {
  26834. (*io)->flush();
  26835. (*io)->close();
  26836. }
  26837. }
  26838. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26839. clean(1);
  26840. (*io)->close();
  26841. delete (*io);
  26842. (*io) = nullptr;
  26843. shell->stream_type = otl_no_stream_type;
  26844. throw;
  26845. }
  26846. delete (*io);
  26847. (*io) = nullptr;
  26848. shell->stream_type = otl_no_stream_type;
  26849. break;
  26850. case otl_select_stream_type:
  26851. try {
  26852. if ((*ss) != nullptr)
  26853. (*ss)->close();
  26854. }
  26855. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26856. delete (*ss);
  26857. (*ss) = nullptr;
  26858. shell->stream_type = otl_no_stream_type;
  26859. throw;
  26860. }
  26861. delete (*ss);
  26862. (*ss) = nullptr;
  26863. shell->stream_type = otl_no_stream_type;
  26864. break;
  26865. case otl_refcur_stream_type:
  26866. try {
  26867. if ((*ref_ss) != nullptr)
  26868. (*ref_ss)->close();
  26869. }
  26870. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26871. delete (*ref_ss);
  26872. (*ref_ss) = nullptr;
  26873. shell->stream_type = otl_no_stream_type;
  26874. throw;
  26875. }
  26876. delete (*ref_ss);
  26877. (*ref_ss) = nullptr;
  26878. shell->stream_type = otl_no_stream_type;
  26879. break;
  26880. }
  26881. (*ss) = nullptr;
  26882. (*io) = nullptr;
  26883. (*ref_ss) = nullptr;
  26884. if (adb != nullptr)
  26885. (*adb) = nullptr;
  26886. adb = nullptr;
  26887. }
  26888. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  26889. defined(OTL_UNICODE_STRING_TYPE)) && \
  26890. defined(OTL_STREAM_POOLING_ON)
  26891. void close(const bool save_in_stream_pool = true)
  26892. #else
  26893. void close(void)
  26894. #endif
  26895. {
  26896. if (shell == nullptr)
  26897. return;
  26898. OTL_TRACE_FUNC(0x4, "otl_stream", "close", "")
  26899. #if (defined(OTL_STL) || defined(OTL_ACE) || \
  26900. defined(OTL_UNICODE_STRING_TYPE)) && \
  26901. defined(OTL_STREAM_POOLING_ON)
  26902. if (save_in_stream_pool && (*adb) &&
  26903. (**adb).get_stream_pool_enabled_flag() &&
  26904. !otl_uncaught_exception()) {
  26905. try {
  26906. this->flush();
  26907. this->clean(1);
  26908. }
  26909. catch (OTL_CONST_EXCEPTION otl_exception &) {
  26910. this->clean(1);
  26911. throw;
  26912. }
  26913. if (otl_uncaught_exception()) {
  26914. (*adb)->get_sc().remove(shell, shell->orig_sql_stm);
  26915. intern_cleanup();
  26916. shell_pt.destroy();
  26917. connected = 0;
  26918. return;
  26919. }
  26920. #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  26921. if (otl_uncaught_exception()) {
  26922. if ((*adb))
  26923. (*adb)->get_sc().remove(shell, shell->orig_sql_stm);
  26924. intern_cleanup();
  26925. shell_pt.destroy();
  26926. connected = 0;
  26927. return;
  26928. }
  26929. #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON)
  26930. if (otl_uncaught_exception()) {
  26931. if ((*adb))
  26932. (*adb)->get_sc().remove(shell, shell->orig_sql_stm);
  26933. intern_cleanup();
  26934. shell_pt.destroy();
  26935. connected = 0;
  26936. return;
  26937. }
  26938. #endif
  26939. if(shell->io!=nullptr)
  26940. shell->io->set_commit(1);
  26941. (*adb)->get_sc().add(shell, shell->orig_sql_stm.c_str());
  26942. shell_pt.disconnect();
  26943. connected = 0;
  26944. } else {
  26945. if ((*adb))
  26946. (*adb)->get_sc().remove(shell, shell->orig_sql_stm);
  26947. intern_cleanup();
  26948. shell_pt.destroy();
  26949. connected = 0;
  26950. }
  26951. #else
  26952. intern_cleanup();
  26953. connected = 0;
  26954. #endif
  26955. }
  26956. OTL_NODISCARD otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW {
  26957. desc_len = 0;
  26958. switch (shell->stream_type) {
  26959. case otl_no_stream_type:
  26960. return nullptr;
  26961. case otl_inout_stream_type:
  26962. return nullptr;
  26963. case otl_select_stream_type:
  26964. desc_len = (*ss)->get_sl_len();
  26965. return (*ss)->get_sl_desc();
  26966. case otl_refcur_stream_type:
  26967. desc_len = (*ref_ss)->get_sl_len();
  26968. return (*ref_ss)->get_sl_desc();
  26969. default:
  26970. return nullptr;
  26971. }
  26972. }
  26973. OTL_NODISCARD int good(void) OTL_NO_THROW {
  26974. if (!connected)
  26975. return 0;
  26976. if ((*io) || (*ss) || (*ref_ss)) {
  26977. return 1;
  26978. } else
  26979. return 0;
  26980. }
  26981. otl_stream &operator>>(otl_stream &(*pf)(otl_stream &)) {
  26982. (*pf)(*this);
  26983. return *this;
  26984. }
  26985. otl_stream &operator<<(otl_stream &(*pf)(otl_stream &)) {
  26986. (*pf)(*this);
  26987. return *this;
  26988. }
  26989. #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED)
  26990. public:
  26991. template<typename...T>
  26992. otl_stream& operator<<(const std::tuple<T...>& t){
  26993. otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::write(*this,t);
  26994. return (*this);
  26995. }
  26996. template<typename...T>
  26997. otl_stream& operator>>(std::tuple<T...>& t){
  26998. otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::read(*this,t);
  26999. return (*this);
  27000. }
  27001. #endif
  27002. #if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON)
  27003. public:
  27004. template<typename...T>
  27005. otl_stream& operator<<(const std::variant<T...>& v){
  27006. bool value_written=false;
  27007. otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
  27008. ::write(*this,v,value_written);
  27009. return (*this);
  27010. }
  27011. template<typename...T>
  27012. otl_stream& operator>>(std::variant<T...>& v){
  27013. bool value_read=false;
  27014. otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
  27015. ::read(*this,v,value_read);
  27016. return (*this);
  27017. }
  27018. #endif
  27019. #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_CPP_14_ON)
  27020. #if defined(OTL_COMPILER_HAS_STD_OPTIONAL)
  27021. template<OTL_TYPE_NAME TData>
  27022. otl_stream& operator<<(const std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  27023. if(var)
  27024. (*this)<<(*var);
  27025. else
  27026. (*this)<<otl_null();
  27027. return *this;
  27028. }
  27029. template<OTL_TYPE_NAME TData>
  27030. otl_stream& operator>>(std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  27031. if(var){
  27032. (*this)>>(*var);
  27033. if(this->is_null())var=std::optional<TData>();
  27034. }else{
  27035. TData temp_var;
  27036. (*this)>>temp_var;
  27037. if(!this->is_null())var.emplace(std::move(temp_var));
  27038. }
  27039. return *this;
  27040. }
  27041. #else
  27042. template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
  27043. otl_stream& operator<<(const Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  27044. if(var)
  27045. (*this)<<(*var);
  27046. else
  27047. (*this)<<otl_null();
  27048. return *this;
  27049. }
  27050. template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
  27051. otl_stream& operator>>(Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  27052. if(var){
  27053. (*this)>>(*var);
  27054. if(this->is_null())var=Optional<TData>();
  27055. }else{
  27056. TData temp_var;
  27057. (*this)>>temp_var;
  27058. if(!this->is_null())var.emplace(std::move(temp_var));
  27059. }
  27060. return *this;
  27061. }
  27062. #endif
  27063. #endif
  27064. #if defined(OTL_PARANOID_EOF)
  27065. void throw_if_eof_was_already_reached(const int eof_flag,
  27066. const char *operator_type = nullptr) {
  27067. if (eof_flag) {
  27068. char out_buf[256];
  27069. #if defined(__clang__)
  27070. #pragma clang diagnostic push
  27071. #pragma clang diagnostic ignored "-Wunused-value"
  27072. #endif
  27073. OTL_SPRINTF_S(out_buf, sizeof(out_buf), otl_error_msg_42,
  27074. operator_type == nullptr ? "" : operator_type);
  27075. #if defined(__clang__)
  27076. #pragma clang diagnostic pop
  27077. #endif
  27078. OTL_THROW((otl_exception(out_buf, otl_error_code_42, this->get_stm_text(),
  27079. this->describe_next_out_var()->name)));
  27080. }
  27081. }
  27082. #endif
  27083. otl_stream &operator>>(otl_pl_tab_generic &tab) OTL_THROWS_OTL_EXCEPTION {
  27084. last_oper_was_read_op = true;
  27085. if ((*io)) {
  27086. last_eof_rc = (*io)->eof();
  27087. #if defined(OTL_PARANOID_EOF)
  27088. throw_if_eof_was_already_reached(last_eof_rc, "otl_pl_tab_generic&");
  27089. #endif
  27090. (*io)->operator>>(tab);
  27091. OTL_TRACE_WRITE(", tab len=" << tab.len(), "operator >>", "PL/SQL Tab&")
  27092. inc_next_ov();
  27093. }
  27094. return *this;
  27095. }
  27096. otl_stream &operator>>(otl_refcur_stream &s) OTL_THROWS_OTL_EXCEPTION {
  27097. last_oper_was_read_op = true;
  27098. if ((*io)) {
  27099. last_eof_rc = (*io)->eof();
  27100. #if defined(OTL_PARANOID_EOF)
  27101. throw_if_eof_was_already_reached(last_eof_rc, "otl_refcur_stream&");
  27102. #endif
  27103. (*io)->operator>>(s);
  27104. OTL_TRACE_WRITE(" ref.cur.stream", "operator >>", "otl_refcur_stream&")
  27105. inc_next_ov();
  27106. }
  27107. return *this;
  27108. }
  27109. otl_stream &operator<<(otl_pl_tab_generic &tab) OTL_THROWS_OTL_EXCEPTION {
  27110. last_oper_was_read_op = false;
  27111. reset_end_marker();
  27112. if ((*io)) {
  27113. (*io)->operator<<(tab);
  27114. OTL_TRACE_READ(", tab len=" << tab.len(), "operator <<", "PL/SQL Tab&")
  27115. inc_next_iov();
  27116. }
  27117. return *this;
  27118. }
  27119. #if defined(OTL_PL_TAB) && defined(OTL_STL)
  27120. otl_stream &operator>>(otl_pl_vec_generic &vec) OTL_THROWS_OTL_EXCEPTION {
  27121. last_oper_was_read_op = true;
  27122. if ((*io)) {
  27123. last_eof_rc = (*io)->eof();
  27124. #if defined(OTL_PARANOID_EOF)
  27125. throw_if_eof_was_already_reached(last_eof_rc, "otl_pl_tab_generic&");
  27126. #endif
  27127. (*io)->operator>>(vec);
  27128. OTL_TRACE_WRITE(", tab len=" << vec.len(), "operator >>", "PL/SQL Tab&")
  27129. inc_next_ov();
  27130. }
  27131. return *this;
  27132. }
  27133. otl_stream &operator<<(otl_pl_vec_generic &vec) OTL_THROWS_OTL_EXCEPTION {
  27134. last_oper_was_read_op = false;
  27135. reset_end_marker();
  27136. if ((*io)) {
  27137. (*io)->operator<<(vec);
  27138. OTL_TRACE_READ(", tab len=" << vec.len(), "operator <<", "PL/SQL Tab&")
  27139. inc_next_iov();
  27140. }
  27141. return *this;
  27142. }
  27143. #endif
  27144. otl_stream &operator<<(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION {
  27145. last_oper_was_read_op = false;
  27146. reset_end_marker();
  27147. if ((*io)) {
  27148. (*io)->operator<<(s);
  27149. OTL_TRACE_READ(", lob stream", "operator <<", "PL/otl_lob_stream&")
  27150. inc_next_iov();
  27151. }
  27152. return *this;
  27153. }
  27154. otl_stream &operator>>(otl_time0 &s) OTL_THROWS_OTL_EXCEPTION {
  27155. last_oper_was_read_op = true;
  27156. switch (shell->stream_type) {
  27157. case otl_no_stream_type:
  27158. break;
  27159. case otl_inout_stream_type: {
  27160. last_eof_rc = (*io)->eof();
  27161. #if defined(OTL_PARANOID_EOF)
  27162. throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&");
  27163. #endif
  27164. (*io)->operator>>(s);
  27165. #if defined(OTL_ORA_TIMESTAMP)
  27166. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27167. "otl_datetime&");
  27168. #endif
  27169. break;
  27170. }
  27171. case otl_select_stream_type: {
  27172. last_eof_rc = (*ss)->eof();
  27173. #if defined(OTL_PARANOID_EOF)
  27174. throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&");
  27175. #endif
  27176. (*ss)->operator>>(s);
  27177. #if defined(OTL_ORA_TIMESTAMP)
  27178. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27179. "otl_datetime&");
  27180. #endif
  27181. break;
  27182. }
  27183. case otl_refcur_stream_type: {
  27184. last_eof_rc = (*ref_ss)->eof();
  27185. #if defined(OTL_PARANOID_EOF)
  27186. throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&");
  27187. #endif
  27188. (*ref_ss)->operator>>(s);
  27189. #if defined(OTL_ORA_TIMESTAMP)
  27190. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27191. "otl_datetime&");
  27192. #endif
  27193. break;
  27194. }
  27195. }
  27196. #if defined(OTL_ORA_TIMESTAMP)
  27197. inc_next_ov();
  27198. #endif
  27199. return *this;
  27200. }
  27201. otl_stream &operator<<(const otl_time0 &n) OTL_THROWS_OTL_EXCEPTION {
  27202. last_oper_was_read_op = false;
  27203. reset_end_marker();
  27204. switch (shell->stream_type) {
  27205. case otl_no_stream_type:
  27206. break;
  27207. case otl_inout_stream_type: {
  27208. (*io)->operator<<(n);
  27209. #if defined(OTL_ORA_TIMESTAMP)
  27210. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<",
  27211. "otl_datetime&");
  27212. #endif
  27213. break;
  27214. }
  27215. case otl_select_stream_type: {
  27216. (*ss)->operator<<(n);
  27217. #if defined(OTL_ORA_TIMESTAMP)
  27218. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<",
  27219. "otl_datetime&");
  27220. #endif
  27221. break;
  27222. }
  27223. case otl_refcur_stream_type: {
  27224. (*ref_ss)->operator<<(n);
  27225. if (!(*ov) && (*ref_ss)->get_sl())
  27226. create_var_desc();
  27227. #if defined(OTL_ORA_TIMESTAMP)
  27228. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<",
  27229. "otl_datetime&");
  27230. #endif
  27231. break;
  27232. }
  27233. }
  27234. #if defined(OTL_ORA_TIMESTAMP)
  27235. inc_next_iov();
  27236. #endif
  27237. return *this;
  27238. }
  27239. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  27240. // already declared
  27241. #else
  27242. OTL_ORA_COMMON_READ_STREAM &
  27243. operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION {
  27244. last_oper_was_read_op = true;
  27245. #if defined(OTL_ORA7_STRING_TO_TIMESTAMP)
  27246. otl_var_desc *temp_next_var = describe_next_out_var();
  27247. if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) {
  27248. #if defined(OTL_UNICODE)
  27249. OTL_CHAR tmp_str[100];
  27250. #elif defined(OTL_UNICODE) && defined(OTL_UNICODE_CHAR_TYPE)
  27251. OTL_UNICODE_CHAR_TYPE tmp_str[100];
  27252. #else
  27253. char tmp_str[100];
  27254. #endif
  27255. (*this) >> tmp_str;
  27256. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  27257. if ((*this).is_null())
  27258. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  27259. else
  27260. OTL_ORA7_STRING_TO_TIMESTAMP(tmp_str, s);
  27261. #else
  27262. OTL_ORA7_STRING_TO_TIMESTAMP(tmp_str, s);
  27263. #endif
  27264. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27265. "otl_datetime&");
  27266. return *this;
  27267. } else {
  27268. otl_time0 tmp;
  27269. (*this) >> tmp;
  27270. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  27271. if ((*this).is_null())
  27272. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  27273. else {
  27274. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  27275. (OTL_SCAST(int, tmp.year) - 100);
  27276. s.month = tmp.month;
  27277. s.day = tmp.day;
  27278. s.hour = tmp.hour - 1;
  27279. s.minute = tmp.minute - 1;
  27280. s.second = tmp.second - 1;
  27281. }
  27282. #else
  27283. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  27284. (OTL_SCAST(int, tmp.year) - 100);
  27285. s.month = tmp.month;
  27286. s.day = tmp.day;
  27287. s.hour = tmp.hour - 1;
  27288. s.minute = tmp.minute - 1;
  27289. s.second = tmp.second - 1;
  27290. #endif
  27291. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27292. "otl_datetime&")
  27293. inc_next_ov();
  27294. return *this;
  27295. }
  27296. #else
  27297. otl_time0 tmp;
  27298. (*this) >> tmp;
  27299. #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL)
  27300. if ((*this).is_null())
  27301. s = OTL_DEFAULT_DATETIME_NULL_TO_VAL;
  27302. else {
  27303. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  27304. (OTL_SCAST(int, tmp.year) - 100);
  27305. s.month = tmp.month;
  27306. s.day = tmp.day;
  27307. s.hour = tmp.hour - 1;
  27308. s.minute = tmp.minute - 1;
  27309. s.second = tmp.second - 1;
  27310. }
  27311. #else
  27312. s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 +
  27313. (OTL_SCAST(int, tmp.year) - 100);
  27314. s.month = tmp.month;
  27315. s.day = tmp.day;
  27316. s.hour = tmp.hour - 1;
  27317. s.minute = tmp.minute - 1;
  27318. s.second = tmp.second - 1;
  27319. #endif
  27320. OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>",
  27321. "otl_datetime&");
  27322. inc_next_ov();
  27323. return *this;
  27324. #endif
  27325. }
  27326. #endif
  27327. #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP)
  27328. // already declared
  27329. #else
  27330. otl_stream &operator<<(const otl_datetime &s) OTL_THROWS_OTL_EXCEPTION {
  27331. last_oper_was_read_op = false;
  27332. reset_end_marker();
  27333. #if defined(OTL_ORA7_TIMESTAMP_TO_STRING)
  27334. otl_var_desc *temp_next_var = describe_next_in_var();
  27335. if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) {
  27336. #if defined(OTL_UNICODE)
  27337. OTL_CHAR tmp_str[100];
  27338. #elif defined(OTL_UNICODE) && defined(OTL_UNICODE_CHAR_TYPE)
  27339. OTL_UNICODE_CHAR_TYPE tmp_str[100];
  27340. #else
  27341. char tmp_str[100];
  27342. #endif
  27343. OTL_ORA7_TIMESTAMP_TO_STRING(s, tmp_str);
  27344. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<",
  27345. "otl_datetime&");
  27346. (*this) << tmp_str;
  27347. return *this;
  27348. } else {
  27349. otl_time0 tmp;
  27350. tmp.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100));
  27351. tmp.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100));
  27352. tmp.month = OTL_SCAST(unsigned char, s.month);
  27353. tmp.day = OTL_SCAST(unsigned char, s.day);
  27354. tmp.hour = OTL_SCAST(unsigned char, (s.hour + 1));
  27355. tmp.minute = OTL_SCAST(unsigned char, (s.minute + 1));
  27356. tmp.second = OTL_SCAST(unsigned char, (s.second + 1));
  27357. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<",
  27358. "otl_datetime&");
  27359. (*this) << tmp;
  27360. inc_next_iov();
  27361. return *this;
  27362. }
  27363. #else
  27364. otl_time0 tmp;
  27365. tmp.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100));
  27366. tmp.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100));
  27367. tmp.month = OTL_SCAST(unsigned char, s.month);
  27368. tmp.day = OTL_SCAST(unsigned char, s.day);
  27369. tmp.hour = OTL_SCAST(unsigned char, (s.hour + 1));
  27370. tmp.minute = OTL_SCAST(unsigned char, (s.minute + 1));
  27371. tmp.second = OTL_SCAST(unsigned char, (s.second + 1));
  27372. OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<",
  27373. "otl_datetime&");
  27374. (*this) << tmp;
  27375. inc_next_iov();
  27376. return *this;
  27377. #endif
  27378. }
  27379. #endif
  27380. #if !defined(OTL_UNICODE)
  27381. OTL_ORA_COMMON_READ_STREAM &operator>>(char &c) OTL_THROWS_OTL_EXCEPTION {
  27382. last_oper_was_read_op = true;
  27383. switch (shell->stream_type) {
  27384. case otl_no_stream_type:
  27385. break;
  27386. case otl_inout_stream_type:
  27387. last_eof_rc = (*io)->eof();
  27388. #if defined(OTL_PARANOID_EOF)
  27389. throw_if_eof_was_already_reached(last_eof_rc, "char&");
  27390. #endif
  27391. (*io)->operator>>(c);
  27392. break;
  27393. case otl_select_stream_type:
  27394. last_eof_rc = (*ss)->eof();
  27395. #if defined(OTL_PARANOID_EOF)
  27396. throw_if_eof_was_already_reached(last_eof_rc, "char&");
  27397. #endif
  27398. (*ss)->operator>>(c);
  27399. break;
  27400. case otl_refcur_stream_type:
  27401. last_eof_rc = (*ref_ss)->eof();
  27402. #if defined(OTL_PARANOID_EOF)
  27403. throw_if_eof_was_already_reached(last_eof_rc, "char&");
  27404. #endif
  27405. (*ref_ss)->operator>>(c);
  27406. break;
  27407. }
  27408. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  27409. if ((*this).is_null())
  27410. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  27411. #endif
  27412. OTL_TRACE_WRITE("'" << c << "'", "operator >>", "char&")
  27413. inc_next_ov();
  27414. return *this;
  27415. }
  27416. #endif
  27417. OTL_ORA_COMMON_READ_STREAM &
  27418. operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION {
  27419. last_oper_was_read_op = true;
  27420. switch (shell->stream_type) {
  27421. case otl_no_stream_type:
  27422. break;
  27423. case otl_inout_stream_type:
  27424. last_eof_rc = (*io)->eof();
  27425. #if defined(OTL_PARANOID_EOF)
  27426. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&");
  27427. #endif
  27428. (*io)->operator>>(c);
  27429. break;
  27430. case otl_select_stream_type:
  27431. last_eof_rc = (*ss)->eof();
  27432. #if defined(OTL_PARANOID_EOF)
  27433. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&");
  27434. #endif
  27435. (*ss)->operator>>(c);
  27436. break;
  27437. case otl_refcur_stream_type:
  27438. last_eof_rc = (*ref_ss)->eof();
  27439. #if defined(OTL_PARANOID_EOF)
  27440. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&");
  27441. #endif
  27442. (*ref_ss)->operator>>(c);
  27443. break;
  27444. }
  27445. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  27446. if ((*this).is_null())
  27447. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  27448. #endif
  27449. OTL_TRACE_WRITE("'" << c << "'", "operator >>", "unsigned char&")
  27450. inc_next_ov();
  27451. return *this;
  27452. }
  27453. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  27454. OTL_ORA_COMMON_READ_STREAM &
  27455. operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION {
  27456. last_oper_was_read_op = true;
  27457. switch (shell->stream_type) {
  27458. case otl_no_stream_type:
  27459. break;
  27460. case otl_inout_stream_type:
  27461. last_eof_rc = (*io)->eof();
  27462. #if defined(OTL_PARANOID_EOF)
  27463. throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&");
  27464. #endif
  27465. (*io)->operator>>(s);
  27466. break;
  27467. case otl_select_stream_type:
  27468. last_eof_rc = (*ss)->eof();
  27469. #if defined(OTL_PARANOID_EOF)
  27470. throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&");
  27471. #endif
  27472. (*ss)->operator>>(s);
  27473. break;
  27474. case otl_refcur_stream_type:
  27475. last_eof_rc = (*ref_ss)->eof();
  27476. #if defined(OTL_PARANOID_EOF)
  27477. throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&");
  27478. #endif
  27479. (*ref_ss)->operator>>(s);
  27480. break;
  27481. }
  27482. #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL)
  27483. if ((*this).is_null()) {
  27484. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s);
  27485. }
  27486. #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27487. if ((*this).is_null())
  27488. s = OTL_DEFAULT_STRING_NULL_TO_VAL;
  27489. #endif
  27490. OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "OTL_STRING_CONTAINER&")
  27491. inc_next_ov();
  27492. return *this;
  27493. }
  27494. #endif
  27495. #if !defined(OTL_UNICODE)
  27496. OTL_ORA_COMMON_READ_STREAM &operator>>(char *s) OTL_THROWS_OTL_EXCEPTION {
  27497. last_oper_was_read_op = true;
  27498. switch (shell->stream_type) {
  27499. case otl_no_stream_type:
  27500. break;
  27501. case otl_inout_stream_type:
  27502. last_eof_rc = (*io)->eof();
  27503. #if defined(OTL_PARANOID_EOF)
  27504. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  27505. #endif
  27506. (*io)->operator>>(s);
  27507. break;
  27508. case otl_select_stream_type:
  27509. last_eof_rc = (*ss)->eof();
  27510. #if defined(OTL_PARANOID_EOF)
  27511. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  27512. #endif
  27513. (*ss)->operator>>(s);
  27514. break;
  27515. case otl_refcur_stream_type:
  27516. last_eof_rc = (*ref_ss)->eof();
  27517. #if defined(OTL_PARANOID_EOF)
  27518. throw_if_eof_was_already_reached(last_eof_rc, "char*");
  27519. #endif
  27520. (*ref_ss)->operator>>(s);
  27521. break;
  27522. }
  27523. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27524. if ((*this).is_null())
  27525. otl_strcpy(
  27526. OTL_RCAST(unsigned char *, s),
  27527. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  27528. #endif
  27529. OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "char*")
  27530. inc_next_ov();
  27531. return *this;
  27532. }
  27533. #endif
  27534. #if !defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  27535. template<const size_t N>
  27536. OTL_ORA_COMMON_READ_STREAM &operator>>(std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
  27537. last_oper_was_read_op = true;
  27538. switch (shell->stream_type) {
  27539. case otl_no_stream_type:
  27540. break;
  27541. case otl_inout_stream_type:
  27542. last_eof_rc = (*io)->eof();
  27543. #if defined(OTL_PARANOID_EOF)
  27544. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char,...>&");
  27545. #endif
  27546. (*io)->operator>>(s);
  27547. break;
  27548. case otl_select_stream_type:
  27549. last_eof_rc = (*ss)->eof();
  27550. #if defined(OTL_PARANOID_EOF)
  27551. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char,...>&");
  27552. #endif
  27553. (*ss)->getString(s.data(),OTL_SCAST(int,s.size()));
  27554. break;
  27555. case otl_refcur_stream_type:
  27556. last_eof_rc = (*ref_ss)->eof();
  27557. #if defined(OTL_PARANOID_EOF)
  27558. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char,...>&");
  27559. #endif
  27560. (*ref_ss)->operator>>(s);
  27561. break;
  27562. }
  27563. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27564. if ((*this).is_null())
  27565. otl_strcpy(
  27566. OTL_RCAST(unsigned char *, s),
  27567. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  27568. #endif
  27569. OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "std::array<char,...>&")
  27570. inc_next_ov();
  27571. return *this;
  27572. }
  27573. template<const size_t N>
  27574. otl_stream &operator<<(const std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
  27575. last_oper_was_read_op = false;
  27576. reset_end_marker();
  27577. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char,...>&");
  27578. switch (shell->stream_type) {
  27579. case otl_no_stream_type:
  27580. break;
  27581. case otl_inout_stream_type:
  27582. (*io)->operator<<(s);
  27583. break;
  27584. case otl_select_stream_type:
  27585. (*ss)->operator<<(s);
  27586. break;
  27587. case otl_refcur_stream_type:
  27588. (*ref_ss)->operator<<(s);
  27589. if (!(*ov) && (*ref_ss)->get_sl())
  27590. create_var_desc();
  27591. break;
  27592. }
  27593. inc_next_iov();
  27594. return *this;
  27595. }
  27596. #endif
  27597. #if defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
  27598. template<const size_t N>
  27599. OTL_ORA_COMMON_READ_STREAM &operator>>(std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
  27600. last_oper_was_read_op = true;
  27601. switch (shell->stream_type) {
  27602. case otl_no_stream_type:
  27603. break;
  27604. case otl_inout_stream_type:
  27605. last_eof_rc = (*io)->eof();
  27606. #if defined(OTL_PARANOID_EOF)
  27607. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char16_t,...>&");
  27608. #endif
  27609. (*io)->operator>>(s);
  27610. break;
  27611. case otl_select_stream_type:
  27612. last_eof_rc = (*ss)->eof();
  27613. #if defined(OTL_PARANOID_EOF)
  27614. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char16_t,...>&");
  27615. #endif
  27616. (*ss)->getString(s.data(),OTL_SCAST(int,s.size()));
  27617. break;
  27618. case otl_refcur_stream_type:
  27619. last_eof_rc = (*ref_ss)->eof();
  27620. #if defined(OTL_PARANOID_EOF)
  27621. throw_if_eof_was_already_reached(last_eof_rc, "std::array<char16_t,...>&");
  27622. #endif
  27623. (*ref_ss)->operator>>(s);
  27624. break;
  27625. }
  27626. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27627. if ((*this).is_null())
  27628. otl_strcpy(
  27629. OTL_RCAST(unsigned char *, s),
  27630. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  27631. #endif
  27632. OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "std::array<char16_t,...>&")
  27633. inc_next_ov();
  27634. return *this;
  27635. }
  27636. template<const size_t N>
  27637. otl_stream &operator<<(const std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
  27638. last_oper_was_read_op = false;
  27639. reset_end_marker();
  27640. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char16_t,...>&");
  27641. switch (shell->stream_type) {
  27642. case otl_no_stream_type:
  27643. break;
  27644. case otl_inout_stream_type:
  27645. (*io)->operator<<(s);
  27646. break;
  27647. case otl_select_stream_type:
  27648. (*ss)->operator<<(s);
  27649. break;
  27650. case otl_refcur_stream_type:
  27651. (*ref_ss)->operator<<(s);
  27652. if (!(*ov) && (*ref_ss)->get_sl())
  27653. create_var_desc();
  27654. break;
  27655. }
  27656. inc_next_iov();
  27657. return *this;
  27658. }
  27659. #endif
  27660. #if defined(OTL_UNICODE_STRING_TYPE)
  27661. OTL_ORA_COMMON_READ_STREAM &
  27662. operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION {
  27663. last_oper_was_read_op = true;
  27664. switch (shell->stream_type) {
  27665. case otl_no_stream_type:
  27666. break;
  27667. case otl_inout_stream_type:
  27668. last_eof_rc = (*io)->eof();
  27669. #if defined(OTL_PARANOID_EOF)
  27670. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&");
  27671. #endif
  27672. (*io)->operator>>(s);
  27673. break;
  27674. case otl_select_stream_type:
  27675. last_eof_rc = (*ss)->eof();
  27676. #if defined(OTL_PARANOID_EOF)
  27677. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&");
  27678. #endif
  27679. (*ss)->operator>>(s);
  27680. break;
  27681. case otl_refcur_stream_type:
  27682. last_eof_rc = (*ref_ss)->eof();
  27683. #if defined(OTL_PARANOID_EOF)
  27684. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&");
  27685. #endif
  27686. (*ref_ss)->operator>>(s);
  27687. break;
  27688. }
  27689. #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL)
  27690. if ((*this).is_null()) {
  27691. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s);
  27692. }
  27693. #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27694. if ((*this).is_null())
  27695. s = OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *,
  27696. OTL_DEFAULT_STRING_NULL_TO_VAL);
  27697. #endif
  27698. OTL_TRACE_WRITE("\"" << s.c_str() << "\"", "operator >>",
  27699. "OTL_UNICODE_STRING_TYPE&");
  27700. inc_next_ov();
  27701. return *this;
  27702. }
  27703. otl_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s)
  27704. OTL_THROWS_OTL_EXCEPTION {
  27705. last_oper_was_read_op = false;
  27706. reset_end_marker();
  27707. OTL_TRACE_READ("\"" << s.c_str() << "\"", "operator <<",
  27708. "OTL_UNICODE_STRING_TYPE&");
  27709. switch (shell->stream_type) {
  27710. case otl_no_stream_type:
  27711. break;
  27712. case otl_inout_stream_type:
  27713. (*io)->operator<<(s);
  27714. break;
  27715. case otl_select_stream_type:
  27716. (*ss)->operator<<(s);
  27717. break;
  27718. case otl_refcur_stream_type:
  27719. (*ref_ss)->operator<<(s);
  27720. if (!(*ov) && (*ref_ss)->get_sl())
  27721. create_var_desc();
  27722. break;
  27723. }
  27724. inc_next_iov();
  27725. return *this;
  27726. }
  27727. #endif
  27728. #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS))
  27729. otl_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s)
  27730. OTL_THROWS_OTL_EXCEPTION {
  27731. last_oper_was_read_op = false;
  27732. reset_end_marker();
  27733. #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)
  27734. OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<",
  27735. "OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS");
  27736. #else
  27737. OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<",
  27738. "OTL_STD_UNICODE_STRING_VIEW_CLASS");
  27739. #endif
  27740. switch (shell->stream_type) {
  27741. case otl_no_stream_type:
  27742. break;
  27743. case otl_inout_stream_type:
  27744. (*io)->operator<<(s);
  27745. break;
  27746. case otl_select_stream_type:
  27747. (*ss)->operator<<(s);
  27748. break;
  27749. case otl_refcur_stream_type:
  27750. (*ref_ss)->operator<<(s);
  27751. if (!(*ov) && (*ref_ss)->get_sl())
  27752. create_var_desc();
  27753. break;
  27754. }
  27755. inc_next_iov();
  27756. return *this;
  27757. }
  27758. #endif
  27759. OTL_ORA_COMMON_READ_STREAM &
  27760. operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION {
  27761. last_oper_was_read_op = true;
  27762. switch (shell->stream_type) {
  27763. case otl_no_stream_type:
  27764. break;
  27765. case otl_inout_stream_type:
  27766. last_eof_rc = (*io)->eof();
  27767. #if defined(OTL_PARANOID_EOF)
  27768. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*");
  27769. #endif
  27770. (*io)->operator>>(s);
  27771. break;
  27772. case otl_select_stream_type:
  27773. last_eof_rc = (*ss)->eof();
  27774. #if defined(OTL_PARANOID_EOF)
  27775. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*");
  27776. #endif
  27777. (*ss)->operator>>(s);
  27778. break;
  27779. case otl_refcur_stream_type:
  27780. last_eof_rc = (*ref_ss)->eof();
  27781. #if defined(OTL_PARANOID_EOF)
  27782. throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*");
  27783. #endif
  27784. (*ref_ss)->operator>>(s);
  27785. break;
  27786. }
  27787. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27788. if ((*this).is_null())
  27789. otl_strcpy(
  27790. OTL_RCAST(unsigned char *, s),
  27791. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  27792. #endif
  27793. #if defined(OTL_UNICODE)
  27794. OTL_TRACE_WRITE("\"" << OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s) << "\"",
  27795. "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*")
  27796. #else
  27797. OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "unsigned char*")
  27798. #endif
  27799. inc_next_ov();
  27800. return *this;
  27801. }
  27802. #if defined(OTL_UNICODE)
  27803. OTL_ORA_COMMON_READ_STREAM &
  27804. operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION {
  27805. last_oper_was_read_op = true;
  27806. switch (shell->stream_type) {
  27807. case otl_no_stream_type:
  27808. break;
  27809. case otl_inout_stream_type:
  27810. last_eof_rc = (*io)->eof();
  27811. #if defined(OTL_PARANOID_EOF)
  27812. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*");
  27813. #endif
  27814. (*io)->operator>>(OTL_RCAST(unsigned char *, s));
  27815. break;
  27816. case otl_select_stream_type:
  27817. last_eof_rc = (*ss)->eof();
  27818. #if defined(OTL_PARANOID_EOF)
  27819. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*");
  27820. #endif
  27821. (*ss)->operator>>(OTL_RCAST(unsigned char *, s));
  27822. break;
  27823. case otl_refcur_stream_type:
  27824. last_eof_rc = (*ref_ss)->eof();
  27825. #if defined(OTL_PARANOID_EOF)
  27826. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*");
  27827. #endif
  27828. (*ref_ss)->operator>>(OTL_RCAST(unsigned char *, s));
  27829. break;
  27830. }
  27831. #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL)
  27832. if ((*this).is_null())
  27833. otl_strcpy(
  27834. OTL_RCAST(unsigned char *, s),
  27835. OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL));
  27836. #endif
  27837. OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>",
  27838. OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*")
  27839. inc_next_ov();
  27840. return *this;
  27841. }
  27842. OTL_ORA_COMMON_READ_STREAM &
  27843. operator>>(OTL_UNICODE_CHAR_TYPE &c) OTL_THROWS_OTL_EXCEPTION {
  27844. OTL_UNICODE_CHAR_TYPE s[1024];
  27845. last_oper_was_read_op = true;
  27846. switch (shell->stream_type) {
  27847. case otl_no_stream_type:
  27848. break;
  27849. case otl_inout_stream_type:
  27850. last_eof_rc = (*io)->eof();
  27851. #if defined(OTL_PARANOID_EOF)
  27852. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&");
  27853. #endif
  27854. (*io)->operator>>(OTL_RCAST(unsigned char *, s));
  27855. break;
  27856. case otl_select_stream_type:
  27857. last_eof_rc = (*ss)->eof();
  27858. #if defined(OTL_PARANOID_EOF)
  27859. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&");
  27860. #endif
  27861. (*ss)->operator>>(OTL_RCAST(unsigned char *, s));
  27862. break;
  27863. case otl_refcur_stream_type:
  27864. last_eof_rc = (*ref_ss)->eof();
  27865. #if defined(OTL_PARANOID_EOF)
  27866. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&");
  27867. #endif
  27868. (*ref_ss)->operator>>(OTL_RCAST(unsigned char *, s));
  27869. break;
  27870. }
  27871. #if defined(_MSC_VER) && (_MSC_VER >= 1700)
  27872. #pragma warning(push)
  27873. #pragma warning(disable : 6001)
  27874. #endif
  27875. c = s[0];
  27876. #if defined(_MSC_VER) && (_MSC_VER >= 1700)
  27877. #pragma warning(pop)
  27878. #endif
  27879. #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL)
  27880. if ((*this).is_null())
  27881. c = OTL_DEFAULT_CHAR_NULL_TO_VAL;
  27882. #endif
  27883. OTL_TRACE_WRITE(c, "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "")
  27884. inc_next_ov();
  27885. return *this;
  27886. }
  27887. #endif
  27888. #if defined(OTL_BIGINT) && \
  27889. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  27890. !defined(OTL_BIGINT_TO_STR))
  27891. OTL_ORA_COMMON_READ_STREAM &
  27892. operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  27893. last_oper_was_read_op = true;
  27894. switch (shell->stream_type) {
  27895. case otl_no_stream_type:
  27896. break;
  27897. case otl_inout_stream_type:
  27898. last_eof_rc = (*io)->eof();
  27899. #if defined(OTL_PARANOID_EOF)
  27900. throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&");
  27901. #endif
  27902. (*io)->operator>>(n);
  27903. break;
  27904. case otl_select_stream_type:
  27905. last_eof_rc = (*ss)->eof();
  27906. #if defined(OTL_PARANOID_EOF)
  27907. throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&");
  27908. #endif
  27909. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  27910. (*ss)->operator>>(n);
  27911. #else
  27912. (*ss)->operator>><OTL_BIGINT, otl_var_bigint>(n);
  27913. #endif
  27914. break;
  27915. case otl_refcur_stream_type:
  27916. last_eof_rc = (*ref_ss)->eof();
  27917. #if defined(OTL_PARANOID_EOF)
  27918. throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&");
  27919. #endif
  27920. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  27921. (*ref_ss)->operator>>(n);
  27922. #else
  27923. (*ref_ss)->operator>><OTL_BIGINT, otl_var_bigint>(n);
  27924. #endif
  27925. break;
  27926. }
  27927. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  27928. if ((*this).is_null())
  27929. n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  27930. #endif
  27931. OTL_TRACE_WRITE(n, "operator >>", "OTL_BIGINT&")
  27932. inc_next_ov();
  27933. return *this;
  27934. }
  27935. #endif
  27936. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  27937. OTL_ORA_COMMON_READ_STREAM &
  27938. operator>>(OTL_UBIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  27939. last_oper_was_read_op = true;
  27940. switch (shell->stream_type) {
  27941. case otl_no_stream_type:
  27942. break;
  27943. case otl_inout_stream_type:
  27944. last_eof_rc = (*io)->eof();
  27945. #if defined(OTL_PARANOID_EOF)
  27946. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&");
  27947. #endif
  27948. (*io)->operator>>(n);
  27949. break;
  27950. case otl_select_stream_type:
  27951. last_eof_rc = (*ss)->eof();
  27952. #if defined(OTL_PARANOID_EOF)
  27953. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&");
  27954. #endif
  27955. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  27956. (*ss)->operator>>(n);
  27957. #else
  27958. (*ss)->operator>><OTL_UBIGINT, otl_var_ubigint>(n);
  27959. #endif
  27960. break;
  27961. case otl_refcur_stream_type:
  27962. last_eof_rc = (*ref_ss)->eof();
  27963. #if defined(OTL_PARANOID_EOF)
  27964. throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&");
  27965. #endif
  27966. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  27967. (*ref_ss)->operator>>(n);
  27968. #else
  27969. (*ref_ss)->operator>><OTL_UBIGINT, otl_var_ubigint>(n);
  27970. #endif
  27971. break;
  27972. }
  27973. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  27974. if ((*this).is_null())
  27975. n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  27976. #endif
  27977. OTL_TRACE_WRITE(n, "operator >>", "OTL_UBIGINT&")
  27978. inc_next_ov();
  27979. return *this;
  27980. }
  27981. #endif
  27982. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  27983. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  27984. otl_stream &operator>>(OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION {
  27985. char temp_val[otl_numeric_type_1_str_size];
  27986. #if defined(OTL_UNICODE)
  27987. OTL_CHAR unitemp_val[otl_numeric_type_1_str_size];
  27988. (*this) >> OTL_RCAST(unsigned char *, unitemp_val);
  27989. OTL_CHAR *uc = unitemp_val;
  27990. char *c = temp_val;
  27991. while (*uc) {
  27992. *c = OTL_SCAST(char, *uc);
  27993. ++uc;
  27994. ++c;
  27995. }
  27996. *c = 0;
  27997. #else
  27998. (*this) >> temp_val;
  27999. #endif
  28000. if (this->is_null()) {
  28001. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28002. if (this->is_null())
  28003. n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28004. #endif
  28005. return *this;
  28006. }
  28007. OTL_STR_TO_NUMERIC_TYPE_1(temp_val, n)
  28008. return *this;
  28009. }
  28010. otl_stream &operator<<(const OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION {
  28011. #if defined(OTL_UNICODE)
  28012. char temp_val[otl_numeric_type_1_str_size];
  28013. OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val)
  28014. OTL_CHAR unitemp_val[otl_numeric_type_1_str_size];
  28015. OTL_CHAR *uc = unitemp_val;
  28016. char *c = temp_val;
  28017. while (*c) {
  28018. *uc = OTL_SCAST(OTL_CHAR, *c);
  28019. ++uc;
  28020. ++c;
  28021. }
  28022. *uc = 0;
  28023. (*this) << OTL_RCAST(unsigned char *, unitemp_val);
  28024. #else
  28025. char temp_val[otl_numeric_type_1_str_size];
  28026. OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val)
  28027. (*this) << temp_val;
  28028. #endif
  28029. return *this;
  28030. }
  28031. #endif
  28032. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  28033. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  28034. otl_stream &operator>>(OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION {
  28035. char temp_val[otl_numeric_type_2_str_size];
  28036. #if defined(OTL_UNICODE)
  28037. OTL_CHAR unitemp_val[otl_numeric_type_2_str_size];
  28038. (*this) >> OTL_RCAST(unsigned char *, unitemp_val);
  28039. OTL_CHAR *uc = unitemp_val;
  28040. char *c = temp_val;
  28041. while (*uc) {
  28042. *c = OTL_SCAST(char, *uc);
  28043. ++uc;
  28044. ++c;
  28045. }
  28046. *c = 0;
  28047. #else
  28048. (*this) >> temp_val;
  28049. #endif
  28050. if (this->is_null()) {
  28051. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28052. if (this->is_null())
  28053. n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28054. #endif
  28055. return *this;
  28056. }
  28057. OTL_STR_TO_NUMERIC_TYPE_2(temp_val, n)
  28058. return *this;
  28059. }
  28060. otl_stream &operator<<(const OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION {
  28061. #if defined(OTL_UNICODE)
  28062. char temp_val[otl_numeric_type_2_str_size];
  28063. OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val)
  28064. OTL_CHAR unitemp_val[otl_numeric_type_2_str_size];
  28065. OTL_CHAR *uc = unitemp_val;
  28066. char *c = temp_val;
  28067. while (*c) {
  28068. *uc = OTL_SCAST(OTL_CHAR, *c);
  28069. ++uc;
  28070. ++c;
  28071. }
  28072. *uc = 0;
  28073. (*this) << OTL_RCAST(unsigned char *, unitemp_val);
  28074. #else
  28075. char temp_val[otl_numeric_type_2_str_size];
  28076. OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val)
  28077. (*this) << temp_val;
  28078. #endif
  28079. return *this;
  28080. }
  28081. #endif
  28082. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  28083. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  28084. otl_stream &operator>>(OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION {
  28085. char temp_val[otl_numeric_type_3_str_size];
  28086. #if defined(OTL_UNICODE)
  28087. OTL_CHAR unitemp_val[otl_numeric_type_3_str_size];
  28088. (*this) >> OTL_RCAST(unsigned char *, unitemp_val);
  28089. OTL_CHAR *uc = unitemp_val;
  28090. char *c = temp_val;
  28091. while (*uc) {
  28092. *c = OTL_SCAST(char, *uc);
  28093. ++uc;
  28094. ++c;
  28095. }
  28096. *c = 0;
  28097. #else
  28098. (*this) >> temp_val;
  28099. #endif
  28100. if (this->is_null()) {
  28101. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28102. if (this->is_null())
  28103. n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28104. #endif
  28105. return *this;
  28106. }
  28107. OTL_STR_TO_NUMERIC_TYPE_3(temp_val, n)
  28108. return *this;
  28109. }
  28110. otl_stream &operator<<(const OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION {
  28111. #if defined(OTL_UNICODE)
  28112. char temp_val[otl_numeric_type_3_str_size];
  28113. OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val)
  28114. OTL_CHAR unitemp_val[otl_numeric_type_3_str_size];
  28115. OTL_CHAR *uc = unitemp_val;
  28116. char *c = temp_val;
  28117. while (*c) {
  28118. *uc = OTL_SCAST(OTL_CHAR, *c);
  28119. ++uc;
  28120. ++c;
  28121. }
  28122. *uc = 0;
  28123. (*this) << OTL_RCAST(unsigned char *, unitemp_val);
  28124. #else
  28125. char temp_val[otl_numeric_type_3_str_size];
  28126. OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val)
  28127. (*this) << temp_val;
  28128. #endif
  28129. return *this;
  28130. }
  28131. #endif
  28132. #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \
  28133. defined(OTL_BIGINT_TO_STR)
  28134. otl_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  28135. char temp_val[otl_bigint_str_size];
  28136. #if defined(OTL_UNICODE)
  28137. OTL_CHAR unitemp_val[otl_bigint_str_size];
  28138. (*this) >> OTL_RCAST(unsigned char *, unitemp_val);
  28139. OTL_CHAR *uc = unitemp_val;
  28140. char *c = temp_val;
  28141. while (*uc) {
  28142. *c = OTL_SCAST(char, *uc);
  28143. ++uc;
  28144. ++c;
  28145. }
  28146. *c = 0;
  28147. #else
  28148. (*this) >> temp_val;
  28149. #endif
  28150. if (this->is_null()) {
  28151. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28152. if (this->is_null())
  28153. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28154. #endif
  28155. return *this;
  28156. }
  28157. OTL_STR_TO_BIGINT(temp_val, n)
  28158. return *this;
  28159. }
  28160. otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION {
  28161. #if defined(OTL_UNICODE)
  28162. char temp_val[otl_bigint_str_size];
  28163. OTL_BIGINT_TO_STR(n, temp_val)
  28164. OTL_CHAR unitemp_val[otl_bigint_str_size];
  28165. OTL_CHAR *uc = unitemp_val;
  28166. char *c = temp_val;
  28167. while (*c) {
  28168. *uc = OTL_SCAST(OTL_CHAR, *c);
  28169. ++uc;
  28170. ++c;
  28171. }
  28172. *uc = 0;
  28173. (*this) << OTL_RCAST(unsigned char *, unitemp_val);
  28174. #else
  28175. char temp_val[otl_bigint_str_size];
  28176. OTL_BIGINT_TO_STR(n, temp_val)
  28177. (*this) << temp_val;
  28178. #endif
  28179. return *this;
  28180. }
  28181. #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG)
  28182. otl_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION {
  28183. long temp_val;
  28184. (*this) >> temp_val;
  28185. if (this->is_null()) {
  28186. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28187. if (this->is_null())
  28188. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28189. #endif
  28190. return *this;
  28191. }
  28192. n = OTL_SCAST(OTL_BIGINT, temp_val);
  28193. return *this;
  28194. }
  28195. otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION {
  28196. long temp_val = OTL_SCAST(long, n);
  28197. (*this) << temp_val;
  28198. return *this;
  28199. }
  28200. #endif
  28201. OTL_ORA_COMMON_READ_STREAM &operator>>(int &n) OTL_THROWS_OTL_EXCEPTION {
  28202. last_oper_was_read_op = true;
  28203. switch (shell->stream_type) {
  28204. case otl_no_stream_type:
  28205. break;
  28206. case otl_inout_stream_type:
  28207. last_eof_rc = (*io)->eof();
  28208. #if defined(OTL_PARANOID_EOF)
  28209. throw_if_eof_was_already_reached(last_eof_rc, "int&");
  28210. #endif
  28211. (*io)->operator>>(n);
  28212. break;
  28213. case otl_select_stream_type:
  28214. last_eof_rc = (*ss)->eof();
  28215. #if defined(OTL_PARANOID_EOF)
  28216. throw_if_eof_was_already_reached(last_eof_rc, "int&");
  28217. #endif
  28218. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28219. (*ss)->operator>>(n);
  28220. #else
  28221. (*ss)->operator>><int, otl_var_int>(n);
  28222. #endif
  28223. break;
  28224. case otl_refcur_stream_type:
  28225. last_eof_rc = (*ref_ss)->eof();
  28226. #if defined(OTL_PARANOID_EOF)
  28227. throw_if_eof_was_already_reached(last_eof_rc, "int&");
  28228. #endif
  28229. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28230. (*ref_ss)->operator>>(n);
  28231. #else
  28232. (*ref_ss)->operator>><int, otl_var_int>(n);
  28233. #endif
  28234. break;
  28235. }
  28236. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28237. if ((*this).is_null())
  28238. n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28239. #endif
  28240. OTL_TRACE_WRITE(n, "operator >>", "int&")
  28241. inc_next_ov();
  28242. return *this;
  28243. }
  28244. OTL_ORA_COMMON_READ_STREAM &operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION {
  28245. last_oper_was_read_op = true;
  28246. switch (shell->stream_type) {
  28247. case otl_no_stream_type:
  28248. break;
  28249. case otl_inout_stream_type:
  28250. last_eof_rc = (*io)->eof();
  28251. #if defined(OTL_PARANOID_EOF)
  28252. throw_if_eof_was_already_reached(last_eof_rc, "unsigned int&");
  28253. #endif
  28254. (*io)->operator>>(u);
  28255. break;
  28256. case otl_select_stream_type:
  28257. last_eof_rc = (*ss)->eof();
  28258. #if defined(OTL_PARANOID_EOF)
  28259. throw_if_eof_was_already_reached(last_eof_rc, "unsigned int&");
  28260. #endif
  28261. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28262. (*ss)->operator>>(u);
  28263. #else
  28264. (*ss)->operator>><unsigned, otl_var_unsigned_int>(u);
  28265. #endif
  28266. break;
  28267. case otl_refcur_stream_type:
  28268. last_eof_rc = (*ref_ss)->eof();
  28269. #if defined(OTL_PARANOID_EOF)
  28270. throw_if_eof_was_already_reached(last_eof_rc, "unsigned int&");
  28271. #endif
  28272. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28273. (*ref_ss)->operator>>(u);
  28274. #else
  28275. (*ref_ss)->operator>><unsigned, otl_var_unsigned_int>(u);
  28276. #endif
  28277. break;
  28278. }
  28279. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28280. if ((*this).is_null())
  28281. u = OTL_SCAST(unsigned int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28282. #endif
  28283. OTL_TRACE_WRITE(u, "operator >>", "unsigned&")
  28284. inc_next_ov();
  28285. return *this;
  28286. }
  28287. OTL_ORA_COMMON_READ_STREAM &operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION {
  28288. last_oper_was_read_op = true;
  28289. switch (shell->stream_type) {
  28290. case otl_no_stream_type:
  28291. break;
  28292. case otl_inout_stream_type:
  28293. last_eof_rc = (*io)->eof();
  28294. #if defined(OTL_PARANOID_EOF)
  28295. throw_if_eof_was_already_reached(last_eof_rc, "short int&");
  28296. #endif
  28297. (*io)->operator>>(sh);
  28298. break;
  28299. case otl_select_stream_type:
  28300. last_eof_rc = (*ss)->eof();
  28301. #if defined(OTL_PARANOID_EOF)
  28302. throw_if_eof_was_already_reached(last_eof_rc, "short int&");
  28303. #endif
  28304. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28305. (*ss)->operator>>(sh);
  28306. #else
  28307. (*ss)->operator>><short, otl_var_short>(sh);
  28308. #endif
  28309. break;
  28310. case otl_refcur_stream_type:
  28311. last_eof_rc = (*ref_ss)->eof();
  28312. #if defined(OTL_PARANOID_EOF)
  28313. throw_if_eof_was_already_reached(last_eof_rc, "short int&");
  28314. #endif
  28315. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28316. (*ref_ss)->operator>>(sh);
  28317. #else
  28318. (*ref_ss)->operator>><short, otl_var_short>(sh);
  28319. #endif
  28320. break;
  28321. }
  28322. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28323. if ((*this).is_null())
  28324. sh = OTL_SCAST(short int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28325. #endif
  28326. OTL_TRACE_WRITE(sh, "operator >>", "short int&")
  28327. inc_next_ov();
  28328. return *this;
  28329. }
  28330. OTL_ORA_COMMON_READ_STREAM &operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION {
  28331. last_oper_was_read_op = true;
  28332. switch (shell->stream_type) {
  28333. case otl_no_stream_type:
  28334. break;
  28335. case otl_inout_stream_type:
  28336. last_eof_rc = (*io)->eof();
  28337. #if defined(OTL_PARANOID_EOF)
  28338. throw_if_eof_was_already_reached(last_eof_rc, "long int&");
  28339. #endif
  28340. (*io)->operator>>(l);
  28341. break;
  28342. case otl_select_stream_type:
  28343. last_eof_rc = (*ss)->eof();
  28344. #if defined(OTL_PARANOID_EOF)
  28345. throw_if_eof_was_already_reached(last_eof_rc, "long int&");
  28346. #endif
  28347. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28348. (*ss)->operator>>(l);
  28349. #else
  28350. (*ss)->operator>><long, otl_var_long_int>(l);
  28351. #endif
  28352. break;
  28353. case otl_refcur_stream_type:
  28354. last_eof_rc = (*ref_ss)->eof();
  28355. #if defined(OTL_PARANOID_EOF)
  28356. throw_if_eof_was_already_reached(last_eof_rc, "long int&");
  28357. #endif
  28358. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28359. (*ref_ss)->operator>>(l);
  28360. #else
  28361. (*ref_ss)->operator>><long, otl_var_long_int>(l);
  28362. #endif
  28363. break;
  28364. }
  28365. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28366. if ((*this).is_null())
  28367. l = OTL_SCAST(long int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28368. #endif
  28369. OTL_TRACE_WRITE(l, "operator >>", "long int&")
  28370. inc_next_ov();
  28371. return *this;
  28372. }
  28373. OTL_ORA_COMMON_READ_STREAM &operator>>(float &f) OTL_THROWS_OTL_EXCEPTION {
  28374. last_oper_was_read_op = true;
  28375. switch (shell->stream_type) {
  28376. case otl_no_stream_type:
  28377. break;
  28378. case otl_inout_stream_type:
  28379. last_eof_rc = (*io)->eof();
  28380. #if defined(OTL_PARANOID_EOF)
  28381. throw_if_eof_was_already_reached(last_eof_rc, "float&");
  28382. #endif
  28383. (*io)->operator>>(f);
  28384. break;
  28385. case otl_select_stream_type:
  28386. last_eof_rc = (*ss)->eof();
  28387. #if defined(OTL_PARANOID_EOF)
  28388. throw_if_eof_was_already_reached(last_eof_rc, "float&");
  28389. #endif
  28390. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28391. (*ss)->operator>>(f);
  28392. #else
  28393. (*ss)->operator>><float, otl_var_float>(f);
  28394. #endif
  28395. break;
  28396. case otl_refcur_stream_type:
  28397. last_eof_rc = (*ref_ss)->eof();
  28398. #if defined(OTL_PARANOID_EOF)
  28399. throw_if_eof_was_already_reached(last_eof_rc, "float&");
  28400. #endif
  28401. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28402. (*ref_ss)->operator>>(f);
  28403. #else
  28404. (*ref_ss)->operator>><float, otl_var_float>(f);
  28405. #endif
  28406. break;
  28407. }
  28408. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28409. if ((*this).is_null())
  28410. f = OTL_SCAST(float, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28411. #endif
  28412. OTL_TRACE_WRITE(f, "operator >>", "float&")
  28413. inc_next_ov();
  28414. return *this;
  28415. }
  28416. OTL_ORA_COMMON_READ_STREAM &operator>>(double &d) OTL_THROWS_OTL_EXCEPTION {
  28417. last_oper_was_read_op = true;
  28418. switch (shell->stream_type) {
  28419. case otl_no_stream_type:
  28420. break;
  28421. case otl_inout_stream_type:
  28422. last_eof_rc = (*io)->eof();
  28423. #if defined(OTL_PARANOID_EOF)
  28424. throw_if_eof_was_already_reached(last_eof_rc, "double&");
  28425. #endif
  28426. (*io)->operator>>(d);
  28427. break;
  28428. case otl_select_stream_type:
  28429. last_eof_rc = (*ss)->eof();
  28430. #if defined(OTL_PARANOID_EOF)
  28431. throw_if_eof_was_already_reached(last_eof_rc, "double&");
  28432. #endif
  28433. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28434. (*ss)->operator>>(d);
  28435. #else
  28436. (*ss)->operator>><double, otl_var_double>(d);
  28437. #endif
  28438. break;
  28439. case otl_refcur_stream_type:
  28440. last_eof_rc = (*ref_ss)->eof();
  28441. #if defined(OTL_PARANOID_EOF)
  28442. throw_if_eof_was_already_reached(last_eof_rc, "double&");
  28443. #endif
  28444. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28445. (*ref_ss)->operator>>(d);
  28446. #else
  28447. (*ref_ss)->operator>><double, otl_var_double>(d);
  28448. #endif
  28449. break;
  28450. }
  28451. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  28452. if ((*this).is_null())
  28453. d = OTL_SCAST(double, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  28454. #endif
  28455. OTL_TRACE_WRITE(d, "operator >>", "double&")
  28456. inc_next_ov();
  28457. return *this;
  28458. }
  28459. OTL_ORA_COMMON_READ_STREAM &
  28460. operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION {
  28461. last_oper_was_read_op = true;
  28462. switch (shell->stream_type) {
  28463. case otl_no_stream_type:
  28464. break;
  28465. case otl_inout_stream_type:
  28466. (*io)->operator>>(s);
  28467. break;
  28468. case otl_select_stream_type:
  28469. (*ss)->operator>>(s);
  28470. break;
  28471. case otl_refcur_stream_type:
  28472. (*ref_ss)->operator>>(s);
  28473. break;
  28474. }
  28475. OTL_TRACE_WRITE(" len=" << s.len(), "operator >>", "otl_long_string&")
  28476. inc_next_ov();
  28477. return *this;
  28478. }
  28479. OTL_ORA_COMMON_READ_STREAM &
  28480. operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION {
  28481. last_oper_was_read_op = true;
  28482. switch (shell->stream_type) {
  28483. case otl_no_stream_type:
  28484. break;
  28485. case otl_inout_stream_type:
  28486. last_eof_rc = (*io)->eof();
  28487. #if defined(OTL_PARANOID_EOF)
  28488. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  28489. #endif
  28490. (*io)->operator>>(s);
  28491. break;
  28492. case otl_select_stream_type:
  28493. last_eof_rc = (*ss)->eof();
  28494. #if defined(OTL_PARANOID_EOF)
  28495. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  28496. #endif
  28497. (*ss)->operator>>(s);
  28498. break;
  28499. case otl_refcur_stream_type:
  28500. last_eof_rc = (*ref_ss)->eof();
  28501. #if defined(OTL_PARANOID_EOF)
  28502. throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&");
  28503. #endif
  28504. (*ref_ss)->operator>>(s);
  28505. break;
  28506. }
  28507. shell->lob_stream_flag = true;
  28508. OTL_TRACE_WRITE(" lob stream", "operator >>", "otl_lob_stream&")
  28509. inc_next_ov();
  28510. return *this;
  28511. }
  28512. #if defined(OTL_ORA_SDO_GEOMETRY)
  28513. OTL_ORA_COMMON_READ_STREAM &
  28514. operator >> (oci_spatial_geometry &s) OTL_THROWS_OTL_EXCEPTION{
  28515. last_oper_was_read_op = true;
  28516. switch(shell->stream_type){
  28517. case otl_no_stream_type:
  28518. break;
  28519. case otl_inout_stream_type:
  28520. last_eof_rc = (*io)->eof();
  28521. #if defined(OTL_PARANOID_EOF)
  28522. throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&");
  28523. #endif
  28524. (*io)->operator >> (s);
  28525. break;
  28526. case otl_select_stream_type:
  28527. last_eof_rc = (*ss)->eof();
  28528. #if defined(OTL_PARANOID_EOF)
  28529. throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&");
  28530. #endif
  28531. (*ss)->operator >> (s);
  28532. break;
  28533. case otl_refcur_stream_type:
  28534. last_eof_rc = (*ref_ss)->eof();
  28535. #if defined(OTL_PARANOID_EOF)
  28536. throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&");
  28537. #endif
  28538. (*ref_ss)->operator >> (s);
  28539. break;
  28540. }
  28541. shell->lob_stream_flag = true;
  28542. OTL_TRACE_WRITE(" lob stream", "operator >>", "oci_spatial_geometry&")
  28543. inc_next_ov();
  28544. return *this;
  28545. }
  28546. #endif
  28547. #if !defined(OTL_UNICODE)
  28548. otl_stream &operator<<(const char c) OTL_THROWS_OTL_EXCEPTION {
  28549. last_oper_was_read_op = false;
  28550. reset_end_marker();
  28551. OTL_TRACE_READ("'" << c << "'", "operator <<", "char");
  28552. switch (shell->stream_type) {
  28553. case otl_no_stream_type:
  28554. break;
  28555. case otl_inout_stream_type:
  28556. (*io)->operator<<(c);
  28557. break;
  28558. case otl_select_stream_type:
  28559. (*ss)->operator<<(c);
  28560. break;
  28561. case otl_refcur_stream_type:
  28562. (*ref_ss)->operator<<(c);
  28563. if (!(*ov) && (*ref_ss)->get_sl())
  28564. create_var_desc();
  28565. break;
  28566. }
  28567. inc_next_iov();
  28568. return *this;
  28569. }
  28570. #endif
  28571. otl_stream &operator<<(const unsigned char c) OTL_THROWS_OTL_EXCEPTION {
  28572. last_oper_was_read_op = false;
  28573. reset_end_marker();
  28574. OTL_TRACE_READ("'" << c << "'", "operator <<", "unsigned char");
  28575. switch (shell->stream_type) {
  28576. case otl_no_stream_type:
  28577. break;
  28578. case otl_inout_stream_type:
  28579. (*io)->operator<<(c);
  28580. break;
  28581. case otl_select_stream_type:
  28582. (*ss)->operator<<(c);
  28583. break;
  28584. case otl_refcur_stream_type:
  28585. (*ref_ss)->operator<<(c);
  28586. if (!(*ov) && (*ref_ss)->get_sl())
  28587. create_var_desc();
  28588. break;
  28589. }
  28590. inc_next_iov();
  28591. return *this;
  28592. }
  28593. #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS))
  28594. otl_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s)
  28595. OTL_THROWS_OTL_EXCEPTION {
  28596. last_oper_was_read_op = false;
  28597. reset_end_marker();
  28598. #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)
  28599. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_THIRD_PARTY_STRING_VIEW_CLASS");
  28600. #else
  28601. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STD_STRING_VIEW_CLASS");
  28602. #endif
  28603. switch (shell->stream_type) {
  28604. case otl_no_stream_type:
  28605. break;
  28606. case otl_inout_stream_type:
  28607. (*io)->operator<<(s);
  28608. break;
  28609. case otl_select_stream_type:
  28610. (*ss)->operator<<(s);
  28611. break;
  28612. case otl_refcur_stream_type:
  28613. (*ref_ss)->operator<<(s);
  28614. if (!(*ov) && (*ref_ss)->get_sl())
  28615. create_var_desc();
  28616. break;
  28617. }
  28618. inc_next_iov();
  28619. return *this;
  28620. }
  28621. #endif
  28622. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  28623. otl_stream &operator<<(const OTL_STRING_CONTAINER &s)
  28624. OTL_THROWS_OTL_EXCEPTION {
  28625. last_oper_was_read_op = false;
  28626. reset_end_marker();
  28627. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STRING_CONTAINER&");
  28628. switch (shell->stream_type) {
  28629. case otl_no_stream_type:
  28630. break;
  28631. case otl_inout_stream_type:
  28632. (*io)->operator<<(s);
  28633. break;
  28634. case otl_select_stream_type:
  28635. (*ss)->operator<<(s);
  28636. break;
  28637. case otl_refcur_stream_type:
  28638. (*ref_ss)->operator<<(s);
  28639. if (!(*ov) && (*ref_ss)->get_sl())
  28640. create_var_desc();
  28641. break;
  28642. }
  28643. inc_next_iov();
  28644. return *this;
  28645. }
  28646. #endif
  28647. #if !defined(OTL_UNICODE)
  28648. otl_stream &operator<<(const char *s) OTL_THROWS_OTL_EXCEPTION {
  28649. last_oper_was_read_op = false;
  28650. reset_end_marker();
  28651. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "char*");
  28652. switch (shell->stream_type) {
  28653. case otl_no_stream_type:
  28654. break;
  28655. case otl_inout_stream_type:
  28656. (*io)->operator<<(s);
  28657. break;
  28658. case otl_select_stream_type:
  28659. (*ss)->operator<<(s);
  28660. break;
  28661. case otl_refcur_stream_type:
  28662. (*ref_ss)->operator<<(s);
  28663. if (!(*ov) && (*ref_ss)->get_sl())
  28664. create_var_desc();
  28665. break;
  28666. }
  28667. inc_next_iov();
  28668. return *this;
  28669. }
  28670. #endif
  28671. otl_stream &operator<<(const unsigned char *s) OTL_THROWS_OTL_EXCEPTION {
  28672. last_oper_was_read_op = false;
  28673. reset_end_marker();
  28674. #if defined(OTL_UNICODE)
  28675. OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"",
  28676. "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*");
  28677. #else
  28678. OTL_TRACE_READ("\"" << s << "\"", "operator <<", "unsigned char*");
  28679. #endif
  28680. switch (shell->stream_type) {
  28681. case otl_no_stream_type:
  28682. break;
  28683. case otl_inout_stream_type:
  28684. (*io)->operator<<(s);
  28685. break;
  28686. case otl_select_stream_type:
  28687. (*ss)->operator<<(s);
  28688. break;
  28689. case otl_refcur_stream_type:
  28690. (*ref_ss)->operator<<(s);
  28691. if (!(*ov) && (*ref_ss)->get_sl())
  28692. create_var_desc();
  28693. break;
  28694. }
  28695. inc_next_iov();
  28696. return *this;
  28697. }
  28698. #if defined(OTL_UNICODE)
  28699. otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE *s)
  28700. OTL_THROWS_OTL_EXCEPTION {
  28701. last_oper_was_read_op = false;
  28702. reset_end_marker();
  28703. OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"",
  28704. "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*");
  28705. switch (shell->stream_type) {
  28706. case otl_no_stream_type:
  28707. break;
  28708. case otl_inout_stream_type:
  28709. (*io)->operator<<(OTL_RCAST(const unsigned char *, s));
  28710. break;
  28711. case otl_select_stream_type:
  28712. (*ss)->operator<<(OTL_RCAST(const unsigned char *, s));
  28713. break;
  28714. case otl_refcur_stream_type:
  28715. (*ref_ss)->operator<<(OTL_RCAST(const unsigned char *, s));
  28716. if (!(*ov) && (*ref_ss)->get_sl())
  28717. create_var_desc();
  28718. break;
  28719. }
  28720. inc_next_iov();
  28721. return *this;
  28722. }
  28723. otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE c)
  28724. OTL_THROWS_OTL_EXCEPTION {
  28725. OTL_UNICODE_CHAR_TYPE s[2];
  28726. s[0] = c;
  28727. s[1] = 0;
  28728. (*this) << s;
  28729. return *this;
  28730. }
  28731. #endif
  28732. #if defined(OTL_BIGINT) && \
  28733. (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \
  28734. !defined(OTL_BIGINT_TO_STR))
  28735. otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION {
  28736. last_oper_was_read_op = false;
  28737. reset_end_marker();
  28738. OTL_TRACE_READ(n, "operator <<", "OTL_BIGINT");
  28739. switch (shell->stream_type) {
  28740. case otl_no_stream_type:
  28741. break;
  28742. case otl_inout_stream_type:
  28743. (*io)->operator<<(n);
  28744. break;
  28745. case otl_select_stream_type:
  28746. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28747. (*ss)->operator<<(n);
  28748. #else
  28749. (*ss)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  28750. #endif
  28751. break;
  28752. case otl_refcur_stream_type:
  28753. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28754. (*ref_ss)->operator<<(n);
  28755. #else
  28756. (*ref_ss)->operator<<<OTL_BIGINT, otl_var_bigint>(n);
  28757. #endif
  28758. if (!(*ov) && (*ref_ss)->get_sl())
  28759. create_var_desc();
  28760. break;
  28761. }
  28762. inc_next_iov();
  28763. return *this;
  28764. }
  28765. #endif
  28766. #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2)
  28767. otl_stream &operator<<(const OTL_UBIGINT n) OTL_THROWS_OTL_EXCEPTION {
  28768. last_oper_was_read_op = false;
  28769. reset_end_marker();
  28770. OTL_TRACE_READ(n, "operator <<", "OTL_UBIGINT");
  28771. switch (shell->stream_type) {
  28772. case otl_no_stream_type:
  28773. break;
  28774. case otl_inout_stream_type:
  28775. (*io)->operator<<(n);
  28776. break;
  28777. case otl_select_stream_type:
  28778. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28779. (*ss)->operator<<(n);
  28780. #else
  28781. (*ss)->operator<<<OTL_UBIGINT, otl_var_ubigint>(n);
  28782. #endif
  28783. break;
  28784. case otl_refcur_stream_type:
  28785. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28786. (*ref_ss)->operator<<(n);
  28787. #else
  28788. (*ref_ss)->operator<<<OTL_UBIGINT, otl_var_ubigint>(n);
  28789. #endif
  28790. if (!(*ov) && (*ref_ss)->get_sl())
  28791. create_var_desc();
  28792. break;
  28793. }
  28794. inc_next_iov();
  28795. return *this;
  28796. }
  28797. #endif
  28798. otl_stream &operator<<(const int n) OTL_THROWS_OTL_EXCEPTION {
  28799. last_oper_was_read_op = false;
  28800. reset_end_marker();
  28801. OTL_TRACE_READ(n, "operator <<", "int");
  28802. switch (shell->stream_type) {
  28803. case otl_no_stream_type:
  28804. break;
  28805. case otl_inout_stream_type:
  28806. (*io)->operator<<(n);
  28807. break;
  28808. case otl_select_stream_type:
  28809. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28810. (*ss)->operator<<(n);
  28811. #else
  28812. (*ss)->operator<<<int, otl_var_int>(n);
  28813. #endif
  28814. break;
  28815. case otl_refcur_stream_type:
  28816. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28817. (*ref_ss)->operator<<(n);
  28818. #else
  28819. (*ref_ss)->operator<<<int, otl_var_int>(n);
  28820. #endif
  28821. if (!(*ov) && (*ref_ss)->get_sl())
  28822. create_var_desc();
  28823. break;
  28824. }
  28825. inc_next_iov();
  28826. return *this;
  28827. }
  28828. otl_stream &operator<<(const unsigned u) OTL_THROWS_OTL_EXCEPTION {
  28829. last_oper_was_read_op = false;
  28830. reset_end_marker();
  28831. OTL_TRACE_READ(u, "operator <<", "unsigned");
  28832. switch (shell->stream_type) {
  28833. case otl_no_stream_type:
  28834. break;
  28835. case otl_inout_stream_type:
  28836. (*io)->operator<<(u);
  28837. break;
  28838. case otl_select_stream_type:
  28839. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28840. (*ss)->operator<<(u);
  28841. #else
  28842. (*ss)->operator<<<unsigned, otl_var_unsigned_int>(u);
  28843. #endif
  28844. break;
  28845. case otl_refcur_stream_type:
  28846. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28847. (*ref_ss)->operator<<(u);
  28848. #else
  28849. (*ref_ss)->operator<<<unsigned, otl_var_unsigned_int>(u);
  28850. #endif
  28851. if (!(*ov) && (*ref_ss)->get_sl())
  28852. create_var_desc();
  28853. break;
  28854. }
  28855. inc_next_iov();
  28856. return *this;
  28857. }
  28858. otl_stream &operator<<(const short sh) OTL_THROWS_OTL_EXCEPTION {
  28859. last_oper_was_read_op = false;
  28860. reset_end_marker();
  28861. OTL_TRACE_READ(sh, "operator <<", "short int");
  28862. switch (shell->stream_type) {
  28863. case otl_no_stream_type:
  28864. break;
  28865. case otl_inout_stream_type:
  28866. (*io)->operator<<(sh);
  28867. break;
  28868. case otl_select_stream_type:
  28869. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28870. (*ss)->operator<<(sh);
  28871. #else
  28872. (*ss)->operator<<<short, otl_var_short>(sh);
  28873. #endif
  28874. break;
  28875. case otl_refcur_stream_type:
  28876. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28877. (*ref_ss)->operator<<(sh);
  28878. #else
  28879. (*ref_ss)->operator<<<short, otl_var_short>(sh);
  28880. #endif
  28881. if (!(*ov) && (*ref_ss)->get_sl())
  28882. create_var_desc();
  28883. break;
  28884. }
  28885. inc_next_iov();
  28886. return *this;
  28887. }
  28888. otl_stream &operator<<(const long int l) OTL_THROWS_OTL_EXCEPTION {
  28889. last_oper_was_read_op = false;
  28890. reset_end_marker();
  28891. OTL_TRACE_READ(l, "operator <<", "long int");
  28892. switch (shell->stream_type) {
  28893. case otl_no_stream_type:
  28894. break;
  28895. case otl_inout_stream_type:
  28896. (*io)->operator<<(l);
  28897. break;
  28898. case otl_select_stream_type:
  28899. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28900. (*ss)->operator<<(l);
  28901. #else
  28902. (*ss)->operator<<<long, otl_var_long_int>(l);
  28903. #endif
  28904. break;
  28905. case otl_refcur_stream_type:
  28906. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28907. (*ref_ss)->operator<<(l);
  28908. #else
  28909. (*ref_ss)->operator<<<long, otl_var_long_int>(l);
  28910. #endif
  28911. if (!(*ov) && (*ref_ss)->get_sl())
  28912. create_var_desc();
  28913. break;
  28914. }
  28915. inc_next_iov();
  28916. return *this;
  28917. }
  28918. otl_stream &operator<<(const float f) OTL_THROWS_OTL_EXCEPTION {
  28919. last_oper_was_read_op = false;
  28920. reset_end_marker();
  28921. OTL_TRACE_READ(f, "operator <<", "float");
  28922. switch (shell->stream_type) {
  28923. case otl_no_stream_type:
  28924. break;
  28925. case otl_inout_stream_type:
  28926. (*io)->operator<<(f);
  28927. break;
  28928. case otl_select_stream_type:
  28929. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28930. (*ss)->operator<<(f);
  28931. #else
  28932. (*ss)->operator<<<float, otl_var_float>(f);
  28933. #endif
  28934. break;
  28935. case otl_refcur_stream_type:
  28936. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28937. (*ref_ss)->operator<<(f);
  28938. #else
  28939. (*ref_ss)->operator<<<float, otl_var_float>(f);
  28940. #endif
  28941. if (!(*ov) && (*ref_ss)->get_sl())
  28942. create_var_desc();
  28943. break;
  28944. }
  28945. inc_next_iov();
  28946. return *this;
  28947. }
  28948. otl_stream &operator<<(const double d) OTL_THROWS_OTL_EXCEPTION {
  28949. last_oper_was_read_op = false;
  28950. reset_end_marker();
  28951. OTL_TRACE_READ(d, "operator <<", "double");
  28952. switch (shell->stream_type) {
  28953. case otl_no_stream_type:
  28954. break;
  28955. case otl_inout_stream_type:
  28956. (*io)->operator<<(d);
  28957. break;
  28958. case otl_select_stream_type:
  28959. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28960. (*ss)->operator<<(d);
  28961. #else
  28962. (*ss)->operator<<<double, otl_var_double>(d);
  28963. #endif
  28964. break;
  28965. case otl_refcur_stream_type:
  28966. #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
  28967. (*ref_ss)->operator<<(d);
  28968. #else
  28969. (*ref_ss)->operator<<<double, otl_var_double>(d);
  28970. #endif
  28971. if (!(*ov) && (*ref_ss)->get_sl())
  28972. create_var_desc();
  28973. break;
  28974. }
  28975. inc_next_iov();
  28976. return *this;
  28977. }
  28978. otl_stream &operator<<(const otl_null &n) OTL_THROWS_OTL_EXCEPTION {
  28979. last_oper_was_read_op = false;
  28980. reset_end_marker();
  28981. OTL_TRACE_READ("NULL", "operator <<", "otl_null&");
  28982. switch (shell->stream_type) {
  28983. case otl_no_stream_type:
  28984. break;
  28985. case otl_inout_stream_type:
  28986. (*io)->operator<<(n);
  28987. break;
  28988. case otl_select_stream_type:
  28989. (*ss)->operator<<(n);
  28990. break;
  28991. case otl_refcur_stream_type:
  28992. (*ref_ss)->operator<<(n);
  28993. if (!(*ov) && (*ref_ss)->get_sl())
  28994. create_var_desc();
  28995. break;
  28996. }
  28997. inc_next_iov();
  28998. return *this;
  28999. }
  29000. otl_stream &operator<<(const otl_long_string &d) OTL_THROWS_OTL_EXCEPTION {
  29001. last_oper_was_read_op = false;
  29002. reset_end_marker();
  29003. OTL_TRACE_READ(" len=" << d.len(), "operator <<", "otl_long_string&");
  29004. switch (shell->stream_type) {
  29005. case otl_no_stream_type:
  29006. break;
  29007. case otl_inout_stream_type:
  29008. (*io)->operator<<(d);
  29009. break;
  29010. case otl_select_stream_type:
  29011. (*ss)->operator<<(d);
  29012. break;
  29013. case otl_refcur_stream_type:
  29014. (*ref_ss)->operator<<(d);
  29015. if (!(*ov) && (*ref_ss)->get_sl())
  29016. create_var_desc();
  29017. break;
  29018. }
  29019. inc_next_iov();
  29020. return *this;
  29021. }
  29022. #if defined(OTL_ORA_SDO_GEOMETRY)
  29023. OTL_ORA_COMMON_READ_STREAM &
  29024. operator << (oci_spatial_geometry &s) OTL_THROWS_OTL_EXCEPTION{
  29025. last_oper_was_read_op = false;
  29026. reset_end_marker();
  29027. OTL_TRACE_READ("geometry", "operator <<", "oci_spatial_geometry&");
  29028. switch(shell->stream_type){
  29029. case otl_no_stream_type:
  29030. break;
  29031. case otl_inout_stream_type:
  29032. (*io)->operator<<(s);
  29033. break;
  29034. case otl_select_stream_type:
  29035. (*ss)->operator<<(s);
  29036. break;
  29037. case otl_refcur_stream_type:
  29038. (*ref_ss)->operator<<(s);
  29039. if(!(*ov) && (*ref_ss)->get_sl())
  29040. create_var_desc();
  29041. break;
  29042. }
  29043. inc_next_iov();
  29044. return *this;
  29045. }
  29046. #endif
  29047. private:
  29048. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  29049. public:
  29050. otl_stream &operator=(const otl_stream &) = delete;
  29051. otl_stream(const otl_stream &) = delete;
  29052. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  29053. otl_stream &operator=(otl_stream &&) = delete;
  29054. otl_stream(otl_stream &&) = delete;
  29055. #endif
  29056. #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS)
  29057. otl_stream &operator>>(bool &) = delete;
  29058. otl_stream &operator<<(const bool) = delete;
  29059. #endif
  29060. #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS)
  29061. otl_stream &operator>>(unsigned long int &) = delete;
  29062. otl_stream &operator<<(const unsigned long int) = delete;
  29063. #endif
  29064. private:
  29065. #else
  29066. otl_stream &operator=(const otl_stream &) { return *this; }
  29067. otl_stream(const otl_stream &)
  29068. :
  29069. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  29070. otl_read_stream_interface(),
  29071. #endif
  29072. shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr),
  29073. io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr),
  29074. iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr),
  29075. next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0),
  29076. last_oper_was_read_op(false), override_(nullptr), buf_size_(0) {
  29077. }
  29078. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  29079. otl_stream &operator=(otl_stream &&) { return *this; }
  29080. otl_stream(otl_stream &&)
  29081. :
  29082. #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE)
  29083. otl_read_stream_interface(),
  29084. #endif
  29085. shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr),
  29086. io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr),
  29087. iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr),
  29088. next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0),
  29089. last_oper_was_read_op(false), override_(nullptr), buf_size_(0) {
  29090. }
  29091. #endif
  29092. #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS)
  29093. otl_stream &operator>>(bool &) OTL_NO_THROW { return *this; }
  29094. otl_stream &operator<<(const bool) OTL_NO_THROW { return *this; }
  29095. #endif
  29096. #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS)
  29097. otl_stream &operator>>(unsigned long int &) OTL_NO_THROW { return *this; }
  29098. otl_stream &operator<<(const unsigned long int) OTL_NO_THROW { return *this; }
  29099. #endif
  29100. #endif
  29101. };
  29102. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  29103. inline bool operator!=(const otl_for_range_loop_ora_stream_adapter& a1,
  29104. const otl_for_range_loop_ora_stream_adapter& /*a2*/){
  29105. return !a1.str_->eof();
  29106. }
  29107. #endif
  29108. #if defined(OTL_ORA_SUBSCRIBE)
  29109. #if !defined(OTL_ORA_OCI_ENV_CREATE)
  29110. #error OTL_ORA_SUBSCRIBE requires #define OTL_ORA_OCI_ENV_CREATE to be enabled
  29111. #endif
  29112. #if !defined(OTL_ORA_OCI_ENV_CREATE_MODE)
  29113. #error OTL_ORA_SUBSCRIBE requires #define OTL_ORA_OCI_ENV_CREATE_MODE to be \
  29114. enabled and to have OCI_THREADED|OCI_OBJECT|OCI_EVENTS
  29115. #endif
  29116. class otl_subscriber {
  29117. public:
  29118. otl_subscriber(otl_connect *adb = nullptr) : db(adb), subscrhp(nullptr) {}
  29119. virtual ~otl_subscriber(void) OTL_THROWS_OTL_EXCEPTION4 { unsubscribe(); }
  29120. void subscribe(const char *name = nullptr, int port = 0, int timeout = 1800
  29121. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  29122. ,
  29123. const char *ipaddr = nullptr)
  29124. #else
  29125. )
  29126. #endif
  29127. {
  29128. if (subscrhp)
  29129. unsubscribe();
  29130. if (!db || (db && !db->connected))
  29131. OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32)));
  29132. OCIEnv *envhp = db->get_connect_struct().get_envhp();
  29133. OCIError *errhp = db->get_connect_struct().get_errhp();
  29134. OCISvcCtx *svchp = db->get_connect_struct().get_svchp();
  29135. if (port)
  29136. check(OCIAttrSet(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV),
  29137. OTL_RCAST(dvoid *, &port), 0, OCI_ATTR_SUBSCR_PORTNO,
  29138. errhp));
  29139. #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C)
  29140. if (ipaddr)
  29141. check(OCIAttrSet(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV),
  29142. OTL_RCAST(dvoid *, OTL_CCAST(char *, ipaddr)),
  29143. OTL_SCAST(ub4, strlen(ipaddr)), OCI_ATTR_SUBSCR_IPADDR,
  29144. errhp));
  29145. #endif
  29146. OCISubscription **temp_subscrhp = &subscrhp;
  29147. check(OCIHandleAlloc(
  29148. OTL_RCAST(dvoid *, envhp), OTL_RCAST(dvoid **, temp_subscrhp),
  29149. OCI_HTYPE_SUBSCRIPTION, OTL_SCAST(size_t, 0), nullptr));
  29150. if (name && *name)
  29151. check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION,
  29152. OTL_RCAST(void *, OTL_CCAST(char *, name)),
  29153. OTL_SCAST(ub4, strlen(name)), OCI_ATTR_SUBSCR_NAME,
  29154. errhp));
  29155. ub4 nspace = OCI_SUBSCR_NAMESPACE_DBCHANGE;
  29156. check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION,
  29157. OTL_RCAST(dvoid *, &nspace), sizeof(ub4),
  29158. OCI_ATTR_SUBSCR_NAMESPACE, errhp));
  29159. check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION,
  29160. #if defined(__GNUC__) && (__GNUC__ < 4)
  29161. (void *)common_notification_callback,
  29162. #else
  29163. OTL_RCAST(void *, common_notification_callback),
  29164. #endif
  29165. 0, OCI_ATTR_SUBSCR_CALLBACK, errhp));
  29166. int rowids_needed = 1;
  29167. check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION,
  29168. OTL_RCAST(dvoid *, &rowids_needed), sizeof(ub4),
  29169. OCI_ATTR_CHNF_ROWIDS, errhp));
  29170. check(OCIAttrSet(subscrhp, OTL_SCAST(ub4, OCI_HTYPE_SUBSCRIPTION),
  29171. OTL_RCAST(dvoid *, this), 0, OCI_ATTR_SUBSCR_CTX, errhp));
  29172. if (timeout)
  29173. check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION,
  29174. OTL_RCAST(dvoid *, &timeout), 0, OCI_ATTR_SUBSCR_TIMEOUT,
  29175. errhp));
  29176. check(OCISubscriptionRegister(svchp, &subscrhp, 1, errhp, OCI_DEFAULT));
  29177. }
  29178. void unsubscribe(void) {
  29179. if (!subscrhp)
  29180. return;
  29181. if (!db || (db && !db->connected))
  29182. OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32)));
  29183. OCIError *errhp = db->get_connect_struct().get_errhp();
  29184. OCISvcCtx *svchp = db->get_connect_struct().get_svchp();
  29185. OCISubscriptionUnRegister(svchp, subscrhp, errhp, OCI_DEFAULT);
  29186. OCIHandleFree(OTL_RCAST(dvoid *, subscrhp), OCI_HTYPE_SUBSCRIPTION);
  29187. subscrhp = nullptr;
  29188. }
  29189. void associate_table(const char *table_name) {
  29190. if (!db || (db && !db->connected))
  29191. OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32)));
  29192. char sql_stmt[1024];
  29193. OTL_STRCPY_S(sql_stmt, sizeof(sql_stmt), "select :i<int> from ");
  29194. OTL_STRCAT_S(sql_stmt, sizeof(sql_stmt), table_name);
  29195. int arg = 0;
  29196. otl_stream s(1, sql_stmt, *db);
  29197. if (!s.get_shell() || !s.get_shell()->ss)
  29198. OTL_THROW((otl_exception(db->get_connect_struct(), sql_stmt)));
  29199. OCIError *errhp = db->get_connect_struct().get_errhp();
  29200. OCIStmt *stmthp = s.get_shell()->ss->get_cursor_struct().cda;
  29201. check(OCIAttrSet(stmthp, OCI_HTYPE_STMT, subscrhp, 0,
  29202. OCI_ATTR_CHNF_REGHANDLE, errhp));
  29203. s << arg;
  29204. }
  29205. void associate_query(const char *stmt) {
  29206. if (!db || (db && !db->connected))
  29207. OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32)));
  29208. otl_stream s(1, stmt, *db);
  29209. if (!s.get_shell() || !s.get_shell()->ss)
  29210. OTL_THROW((otl_exception(db->get_connect_struct(), stmt)));
  29211. OCIError *errhp = db->get_connect_struct().get_errhp();
  29212. OCIStmt *stmthp = s.get_shell()->ss->get_cursor_struct().cda;
  29213. check(OCIAttrSet(stmthp, OCI_HTYPE_STMT, subscrhp, 0,
  29214. OCI_ATTR_CHNF_REGHANDLE, errhp));
  29215. s << 0;
  29216. }
  29217. protected:
  29218. void check(int ret_code) {
  29219. if (ret_code != OCI_SUCCESS)
  29220. OTL_THROW((otl_exception(db->get_connect_struct())));
  29221. }
  29222. virtual void OnException(OTL_CONST_EXCEPTION otl_exception &e) = 0;
  29223. virtual void OnDeRegistration(void) = 0;
  29224. //--- DB events:
  29225. virtual void OnStartup(void) = 0;
  29226. virtual void OnInstanceShutdown(void) = 0;
  29227. virtual void OnAnyInstanceShutdown(void) = 0;
  29228. //--- Table events:
  29229. virtual void OnTableInvalidate(text *table_name) = 0;
  29230. virtual void OnTableAlter(text *table_name, bool all_rows = false) = 0;
  29231. virtual void OnTableDrop(text *table_name, bool all_rows = false) = 0;
  29232. virtual void OnTableChange(text *table_name, bool all_rows = false) = 0;
  29233. //--- Row events:
  29234. virtual void OnRowInsert(text *table_name, text *row_id) = 0;
  29235. virtual void OnRowUpdate(text *table_name, text *row_id) = 0;
  29236. virtual void OnRowDelete(text *table_name, text *row_id) = 0;
  29237. protected:
  29238. otl_connect *db;
  29239. private:
  29240. OCISubscription *subscrhp;
  29241. void notification_callback(dvoid * /*payload*/, ub4 /*paylen*/, dvoid *desc,
  29242. ub4 /*mode*/) {
  29243. if (!db || (db && !db->connected))
  29244. return;
  29245. ub4 num_rows = 0;
  29246. OCIColl *row_changes = nullptr;
  29247. dvoid *row_desc, **row_descp;
  29248. dvoid ***temp_row_descp = &row_descp;
  29249. text *row_id;
  29250. ub4 rowid_size;
  29251. ub4 row_op;
  29252. unsigned int j;
  29253. try {
  29254. OCIEnv *envhp = db->get_connect_struct().get_envhp();
  29255. OCIError *errhp = db->get_connect_struct().get_errhp();
  29256. //----------------
  29257. ub4 notify_type;
  29258. check(OCIAttrGet(desc, OCI_DTYPE_CHDES, &notify_type, nullptr,
  29259. OCI_ATTR_CHDES_NFYTYPE, errhp));
  29260. switch (notify_type) {
  29261. case OCI_EVENT_STARTUP:
  29262. OnStartup();
  29263. return;
  29264. case OCI_EVENT_SHUTDOWN:
  29265. OnInstanceShutdown();
  29266. return;
  29267. case OCI_EVENT_SHUTDOWN_ANY:
  29268. OnAnyInstanceShutdown();
  29269. return;
  29270. case OCI_EVENT_DEREG:
  29271. OnDeRegistration();
  29272. return;
  29273. case OCI_EVENT_OBJCHANGE:
  29274. break;
  29275. default:
  29276. return;
  29277. }
  29278. OCIColl *table_changes = nullptr;
  29279. check(OCIAttrGet(desc, OCI_DTYPE_CHDES, &table_changes, nullptr,
  29280. OCI_ATTR_CHDES_TABLE_CHANGES, errhp));
  29281. if (!table_changes)
  29282. return;
  29283. ub4 num_tables = 0;
  29284. check(OCICollSize(envhp, errhp, OTL_RCAST(CONST OCIColl *, table_changes),
  29285. OTL_RCAST(sb4 *, &num_tables)));
  29286. if (!num_tables)
  29287. return;
  29288. for (unsigned int i = 0; i < num_tables; i++) {
  29289. int exist;
  29290. dvoid *elemind = nullptr, *table_desc, **table_descp;
  29291. dvoid ***temp_table_descp = &table_descp;
  29292. check(OCICollGetElem(envhp, errhp, table_changes, OTL_SCAST(sb4, i),
  29293. &exist, OTL_RCAST(dvoid **, temp_table_descp),
  29294. &elemind));
  29295. table_desc = *table_descp;
  29296. text *table_name;
  29297. check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES, &table_name,
  29298. nullptr, OCI_ATTR_CHDES_TABLE_NAME, errhp));
  29299. ub4 table_op;
  29300. check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES,
  29301. OTL_RCAST(dvoid *, &table_op), nullptr,
  29302. OCI_ATTR_CHDES_TABLE_OPFLAGS, errhp));
  29303. bool all_rows = table_op & OCI_OPCODE_ALLROWS;
  29304. switch (table_op) {
  29305. case OCI_OPCODE_ALLROWS:
  29306. OnTableInvalidate(table_name);
  29307. continue;
  29308. case OCI_OPCODE_ALTER:
  29309. case(OCI_OPCODE_ALTER + OCI_OPCODE_ALLROWS) :
  29310. OnTableAlter(table_name, all_rows);
  29311. continue;
  29312. case OCI_OPCODE_DROP:
  29313. case(OCI_OPCODE_DROP + OCI_OPCODE_ALLROWS) :
  29314. OnTableDrop(table_name, all_rows);
  29315. continue;
  29316. case(OCI_OPCODE_INSERT + OCI_OPCODE_ALLROWS) :
  29317. case(OCI_OPCODE_UPDATE + OCI_OPCODE_ALLROWS) :
  29318. case(OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) :
  29319. case(OCI_OPCODE_INSERT + OCI_OPCODE_UPDATE + OCI_OPCODE_ALLROWS) :
  29320. case(OCI_OPCODE_INSERT + OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) :
  29321. case(OCI_OPCODE_UPDATE + OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) :
  29322. case(OCI_OPCODE_INSERT + OCI_OPCODE_UPDATE + OCI_OPCODE_DELETE +
  29323. OCI_OPCODE_ALLROWS)
  29324. :
  29325. case(OCI_OPCODE_UNKNOWN + OCI_OPCODE_ALLROWS) :
  29326. OnTableChange(table_name, all_rows);
  29327. continue;
  29328. case OCI_OPCODE_INSERT:
  29329. case OCI_OPCODE_UPDATE:
  29330. case OCI_OPCODE_DELETE:
  29331. OnTableChange(table_name, all_rows);
  29332. break;
  29333. }
  29334. row_changes = nullptr;
  29335. check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES, &row_changes,
  29336. nullptr, OCI_ATTR_CHDES_TABLE_ROW_CHANGES, errhp));
  29337. if (!row_changes)
  29338. continue;
  29339. num_rows = 0;
  29340. check(OCICollSize(envhp, errhp, row_changes,
  29341. OTL_RCAST(sb4 *, &num_rows)));
  29342. for (j = 0; j < num_rows; j++) {
  29343. elemind = nullptr;
  29344. check(OCICollGetElem(envhp, errhp, row_changes, OTL_SCAST(sb4, j),
  29345. &exist, OTL_RCAST(dvoid **, temp_row_descp),
  29346. &elemind));
  29347. row_desc = *row_descp;
  29348. check(OCIAttrGet(row_desc, OCI_DTYPE_ROW_CHDES,
  29349. OTL_RCAST(dvoid *, &row_id), &rowid_size,
  29350. OCI_ATTR_CHDES_ROW_ROWID, errhp));
  29351. check(OCIAttrGet(row_desc, OCI_DTYPE_ROW_CHDES,
  29352. OTL_RCAST(dvoid *, &row_op), nullptr,
  29353. OCI_ATTR_CHDES_ROW_OPFLAGS, errhp));
  29354. if (row_op == OCI_OPCODE_INSERT)
  29355. OnRowInsert(table_name, row_id);
  29356. else if (row_op == OCI_OPCODE_DELETE)
  29357. OnRowDelete(table_name, row_id);
  29358. else if (row_op == OCI_OPCODE_UPDATE)
  29359. OnRowUpdate(table_name, row_id);
  29360. }
  29361. }
  29362. }
  29363. catch (OTL_CONST_EXCEPTION otl_exception &e) {
  29364. OnException(e);
  29365. }
  29366. }
  29367. static void common_notification_callback(dvoid *ctx,
  29368. OCISubscription * /*subscrhp*/,
  29369. dvoid *payload, ub4 paylen,
  29370. dvoid *desc, ub4 mode) {
  29371. if (!ctx)
  29372. return;
  29373. (OTL_RCAST(otl_subscriber *, ctx))
  29374. ->notification_callback(payload, paylen, desc, mode);
  29375. }
  29376. public:
  29377. OTL_NODISCARD bool is_online(void) { return subscrhp != nullptr; }
  29378. private:
  29379. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  29380. public:
  29381. otl_subscriber(const otl_subscriber &) = delete;
  29382. otl_subscriber &operator=(const otl_subscriber &) = delete;
  29383. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  29384. otl_subscriber(otl_subscriber &&) = delete;
  29385. otl_subscriber &operator=(otl_subscriber &&) = delete;
  29386. #endif
  29387. private:
  29388. #else
  29389. otl_subscriber(const otl_subscriber &) : db(nullptr), subscrhp(nullptr) {}
  29390. otl_subscriber &operator=(const otl_subscriber &) { return *this; }
  29391. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  29392. otl_subscriber(otl_subscriber &&) : db(nullptr), subscrhp(nullptr) {}
  29393. otl_subscriber &operator=(otl_subscriber &&) { return *this; }
  29394. #endif
  29395. #endif
  29396. };
  29397. #endif
  29398. inline otl_connect &operator>>(otl_connect &connect, otl_stream &s) {
  29399. const char *cmd = connect.getCmd();
  29400. const char *invalid_cmd = "*** INVALID COMMAND ***";
  29401. if (!cmd)
  29402. cmd = invalid_cmd;
  29403. s.open(s.getBufSize(), cmd, connect);
  29404. return connect;
  29405. }
  29406. #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \
  29407. defined(OTL_VALUE_TEMPLATE)
  29408. template <OTL_TYPE_NAME TData>
  29409. inline otl_stream &operator<<(otl_stream &s,
  29410. const otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  29411. if (var.is_null())
  29412. s << otl_null();
  29413. else
  29414. s << var.v;
  29415. return s;
  29416. }
  29417. template <OTL_TYPE_NAME TData>
  29418. inline otl_stream &operator>>(otl_stream &s,
  29419. otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  29420. s >> var.v;
  29421. if(s.is_null())
  29422. var.set_null(true);
  29423. else
  29424. var.set_null(false);
  29425. return s;
  29426. }
  29427. template <OTL_TYPE_NAME TData>
  29428. inline otl_refcur_stream &operator>>(otl_refcur_stream &s,
  29429. otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
  29430. s >> var.v;
  29431. if(s.is_null())
  29432. var.set_null(true);
  29433. else
  29434. var.set_null(false);
  29435. return s;
  29436. }
  29437. template <OTL_TYPE_NAME TData, const TData null_value>
  29438. inline otl_stream &operator<<
  29439. (otl_stream &s,
  29440. const otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
  29441. if (var.is_null())
  29442. s << otl_null();
  29443. else
  29444. s << var.v;
  29445. return s;
  29446. }
  29447. template <OTL_TYPE_NAME TData, const TData null_value>
  29448. inline otl_stream &operator>>
  29449. (otl_stream &s,
  29450. otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
  29451. s >> var.v;
  29452. if(s.is_null())
  29453. var.set_null(true);
  29454. else
  29455. var.set_null(false);
  29456. return s;
  29457. }
  29458. template <OTL_TYPE_NAME TData, const TData null_value>
  29459. inline otl_refcur_stream &operator>>
  29460. (otl_refcur_stream &s,
  29461. otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
  29462. s >> var.v;
  29463. if(s.is_null())
  29464. var.set_null(true);
  29465. else
  29466. var.set_null(false);
  29467. return s;
  29468. }
  29469. #endif
  29470. typedef otl_tmpl_nocommit_stream<otl_stream, otl_connect, otl_exception>
  29471. otl_nocommit_stream;
  29472. inline otl_stream &endr(otl_stream &s) {
  29473. s.check_end_of_row();
  29474. return s;
  29475. }
  29476. OTL_ORA8_NAMESPACE_END
  29477. #ifndef OTL_STDC_DEFINED
  29478. #undef __STDC__
  29479. #endif
  29480. #endif
  29481. #if defined(OTL_STL) && !defined(OTL_STLPORT)
  29482. #define STL_INPUT_ITERATOR_TO_DERIVE_FROM
  29483. #if defined (_MSC_VER) && defined(_HAS_TR1_NAMESPACE) && (_HAS_TR1_NAMESPACE==1)
  29484. #define OTL_VC_TR1_NAMESPACE tr1::
  29485. #else
  29486. #define OTL_VC_TR1_NAMESPACE
  29487. #endif
  29488. #if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_SECURE_SCL) && \
  29489. (_SECURE_SCL == 1) && !defined(OTL_STLPORT)
  29490. #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name) \
  29491. _STD_BEGIN template <OTL_TYPE_NAME T> \
  29492. struct _Is_checked_helper< \
  29493. namespace_name otl_output_iterator<T> > : \
  29494. public _STD OTL_VC_TR1_NAMESPACE true_type {}; \
  29495. _STD_END
  29496. #if defined(_MSC_VER) && (_MSC_VER >= 1911)
  29497. // Visual Studio 2017 Update 3 or higher
  29498. #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM
  29499. #else
  29500. #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM : public _STD _Outit
  29501. #endif
  29502. #else
  29503. #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM
  29504. #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name)
  29505. #endif
  29506. #elif defined(OTL_STLPORT)
  29507. #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name)
  29508. #define STL_INPUT_ITERATOR_TO_DERIVE_FROM \
  29509. : public STD_NAMESPACE_PREFIX iterator \
  29510. <STD_NAMESPACE_PREFIX input_iterator_tag, \
  29511. T,Distance,T*,T&>
  29512. #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM \
  29513. : public STD_NAMESPACE_PREFIX iterator \
  29514. <STD_NAMESPACE_PREFIX output_iterator_tag, \
  29515. T,void,void,void>
  29516. #endif
  29517. #if defined(OTL_STL) || defined(OTL_STLPORT)
  29518. #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
  29519. (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) || \
  29520. (defined(__clang__) && __clang_major__ * 100 + __clang_minor__ >= 306)
  29521. #define OTL_ITER_DISTANCE Distance = STD_NAMESPACE_PREFIX ptrdiff_t
  29522. #else
  29523. #define OTL_ITER_DISTANCE Distance = ptrdiff_t
  29524. #endif
  29525. #define OTL_ITERATORS \
  29526. template <OTL_TYPE_NAME T, OTL_TYPE_NAME OTL_ITER_DISTANCE> \
  29527. class otl_input_iterator STL_INPUT_ITERATOR_TO_DERIVE_FROM { \
  29528. public: \
  29529. typedef STD_NAMESPACE_PREFIX input_iterator_tag iterator_category; \
  29530. typedef T value_type; \
  29531. typedef Distance difference_type; \
  29532. typedef const T *pointer; \
  29533. typedef const T &reference; \
  29534. \
  29535. otl_stream *stream; \
  29536. T value; \
  29537. int end_marker; \
  29538. \
  29539. void read() { \
  29540. if (!stream) { \
  29541. end_marker = -1; \
  29542. return; \
  29543. } \
  29544. if (stream->eof()) { \
  29545. end_marker = -1; \
  29546. return; \
  29547. } \
  29548. end_marker = stream->eof(); \
  29549. if (!end_marker) \
  29550. *stream >> value; \
  29551. if (stream->eof()) \
  29552. end_marker = 1; \
  29553. } \
  29554. \
  29555. otl_input_iterator() : stream(nullptr), value(), end_marker(-1) {} \
  29556. otl_input_iterator(otl_stream &s) : stream(&s), value(), end_marker(0) { \
  29557. read(); \
  29558. } \
  29559. \
  29560. const T &operator*() const { return value; } \
  29561. \
  29562. otl_input_iterator<T, Distance> &operator++() { \
  29563. read(); \
  29564. return *this; \
  29565. } \
  29566. \
  29567. otl_input_iterator<T, Distance> operator++(int) { \
  29568. otl_input_iterator<T, Distance> tmp = *this; \
  29569. read(); \
  29570. return tmp; \
  29571. } \
  29572. \
  29573. otl_input_iterator(const otl_input_iterator &src) \
  29574. : stream(src.stream), value(src.value), end_marker(src.end_marker) {} \
  29575. \
  29576. otl_input_iterator &operator=(const otl_input_iterator &src) { \
  29577. stream = src.stream; \
  29578. value = src.value; \
  29579. end_marker = src.end_marker; \
  29580. return *this; \
  29581. } \
  29582. }; \
  29583. template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
  29584. inline STD_NAMESPACE_PREFIX input_iterator_tag \
  29585. iterator_category(const otl_input_iterator<T, Distance> &) { \
  29586. return STD_NAMESPACE_PREFIX input_iterator_tag(); \
  29587. } \
  29588. template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
  29589. inline T *value_type(const otl_input_iterator<T, Distance> &) { \
  29590. return nullptr; \
  29591. } \
  29592. template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
  29593. inline Distance *distance_type(const otl_input_iterator<T, Distance> &) { \
  29594. return nullptr; \
  29595. } \
  29596. template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
  29597. bool operator==(const otl_input_iterator<T, Distance> &x, \
  29598. const otl_input_iterator<T, Distance> &y) { \
  29599. return (x.stream == y.stream && x.end_marker == y.end_marker) || \
  29600. (x.end_marker == -1 && y.end_marker == -1); \
  29601. } \
  29602. template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
  29603. bool operator!=(const otl_input_iterator<T, Distance> &x, \
  29604. const otl_input_iterator<T, Distance> &y) { \
  29605. return !(x == y); \
  29606. } \
  29607. template <OTL_TYPE_NAME T> \
  29608. class otl_output_iterator STL_OUTPUT_ITERATOR_TO_DERIVE_FROM { \
  29609. protected: \
  29610. otl_stream *stream; \
  29611. \
  29612. public: \
  29613. typedef STD_NAMESPACE_PREFIX output_iterator_tag iterator_category; \
  29614. typedef void value_type; \
  29615. typedef void difference_type; \
  29616. typedef void pointer; \
  29617. typedef void reference; \
  29618. \
  29619. otl_output_iterator(otl_stream &s) : stream(&s) {} \
  29620. otl_output_iterator<T> &operator=(const T &value) { \
  29621. *stream << value; \
  29622. return *this; \
  29623. } \
  29624. otl_output_iterator<T> &operator*() { return *this; } \
  29625. otl_output_iterator<T> &operator++() { return *this; } \
  29626. otl_output_iterator<T> operator++(int) { return *this; } \
  29627. };
  29628. #define OTL_ITERATOR_TAG(namespace_name) \
  29629. template <OTL_TYPE_NAME T> \
  29630. inline STD_NAMESPACE_PREFIX output_iterator_tag \
  29631. iterator_category(const namespace_name otl_output_iterator<T> &) { \
  29632. return STD_NAMESPACE_PREFIX output_iterator_tag(); \
  29633. }
  29634. #if defined(OTL_ORA8)
  29635. OTL_ORA8_NAMESPACE_BEGIN
  29636. OTL_ITERATORS
  29637. OTL_ORA8_NAMESPACE_END
  29638. OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(OTL_ORA8_NAMESPACE_PREFIX)
  29639. OTL_ITERATOR_TAG(OTL_ORA8_NAMESPACE_PREFIX)
  29640. #endif
  29641. #if defined(OTL_ODBC)
  29642. OTL_ODBC_NAMESPACE_BEGIN
  29643. OTL_ITERATORS
  29644. OTL_ODBC_NAMESPACE_END
  29645. OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(OTL_ODBC_NAMESPACE_PREFIX)
  29646. OTL_ITERATOR_TAG(OTL_ODBC_NAMESPACE_PREFIX)
  29647. #endif
  29648. #endif
  29649. #if defined(OTL_STREAM_READ_ITERATOR_ON)
  29650. #if defined(OTL_UNICODE)
  29651. #error UNICODE is not supported when #define OTL_STREAM_READ_ITERATOR_ON is enabled
  29652. #endif
  29653. #if defined(OTL_STL)
  29654. #include <map>
  29655. #endif
  29656. #if defined(OTL_ACE)
  29657. #include <ace/SString.h>
  29658. #include <ace/Array.h>
  29659. #include <ace/Functor.h>
  29660. #include <ace/RB_Tree.h>
  29661. #include <ace/Null_Mutex.h>
  29662. #endif
  29663. #if defined(OTL_STL) || defined(OTL_ACE)
  29664. class otl_ltcharstar {
  29665. public:
  29666. #if defined(OTL_STL)
  29667. bool
  29668. #else
  29669. int
  29670. #endif
  29671. operator()(const char *s1, const char *s2) const {
  29672. #if defined(__BORLANDC__) || (defined(_MSC_VER) && !defined(__clang__))
  29673. return stricmp(s1, s2) < 0;
  29674. #elif (defined(_MSC_VER) && defined(__clang__))
  29675. return _stricmp(s1, s2) < 0;
  29676. #else
  29677. #if defined(__STRICT_ANSI__)
  29678. while (otl_to_upper(*s1) == otl_to_upper(*s2) && *s1) {
  29679. ++s1;
  29680. ++s2;
  29681. }
  29682. return *s1 < *s2;
  29683. #else
  29684. return strcasecmp(s1, s2) < 0;
  29685. #endif
  29686. #endif
  29687. }
  29688. };
  29689. #endif
  29690. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  29691. template<class OTLStream,
  29692. class OTLException,
  29693. class OTLLobStream>
  29694. class otl_stream_read_iterator;
  29695. template <OTL_TYPE_NAME OTLStream,
  29696. OTL_TYPE_NAME OTLException,
  29697. OTL_TYPE_NAME OTLLobStream>
  29698. class otl_for_range_loop_adapter{
  29699. public:
  29700. typedef otl_stream_read_iterator<OTLStream,OTLException,OTLLobStream> read_iter_type;
  29701. otl_for_range_loop_adapter(read_iter_type& iter):iter_(&iter){}
  29702. otl_for_range_loop_adapter():iter_(nullptr) {}
  29703. bool operator!=(const otl_for_range_loop_adapter& /*that*/){
  29704. return !iter_->get_last_eof();
  29705. }
  29706. read_iter_type& operator*(){
  29707. return *iter_;
  29708. }
  29709. otl_for_range_loop_adapter& operator++(){
  29710. (void)iter_->next_row();
  29711. return *this;
  29712. }
  29713. private:
  29714. read_iter_type* iter_;
  29715. };
  29716. #endif
  29717. template <OTL_TYPE_NAME OTLStream, OTL_TYPE_NAME OTLException,
  29718. OTL_TYPE_NAME OTLLobStream>
  29719. class otl_stream_read_iterator {
  29720. public:
  29721. #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
  29722. typedef otl_for_range_loop_adapter<OTLStream,OTLException,OTLLobStream> FRL_type;
  29723. OTL_NODISCARD FRL_type begin(){
  29724. (void)next_row();
  29725. if(!last_eof_)
  29726. return FRL_type(*this);
  29727. else
  29728. return FRL_type();
  29729. }
  29730. OTL_NODISCARD FRL_type end(){
  29731. return FRL_type();
  29732. }
  29733. #endif
  29734. otl_stream_read_iterator(OTLStream &s) {
  29735. set();
  29736. attach(s);
  29737. }
  29738. otl_stream_read_iterator()
  29739. : out_vars_(nullptr), out_vars_len_(0), str_(nullptr),
  29740. out_vars_arr_(nullptr), out_vars_null_arr_(nullptr),
  29741. out_vars_constructed_(false), lob_stream_mode_flag_(false),
  29742. last_eof_(false)
  29743. #if defined(OTL_STL)
  29744. ,
  29745. var_name2pos_map_()
  29746. #endif
  29747. #if defined(OTL_ACE)
  29748. ,
  29749. var_name2pos_map_()
  29750. #endif
  29751. {
  29752. set();
  29753. }
  29754. ~otl_stream_read_iterator() OTL_THROWS_OTL_EXCEPTION { reset(); }
  29755. void attach(OTLStream &s) {
  29756. reset();
  29757. str_ = &s;
  29758. if (!str_->good()) {
  29759. str_ = nullptr;
  29760. OTL_THROW((OTLException(otl_error_msg_19, otl_error_code_19)));
  29761. }
  29762. out_vars_ = str_->describe_out_vars(out_vars_len_);
  29763. if (!out_vars_) {
  29764. OTL_THROW((OTLException(otl_error_msg_21, otl_error_code_21)));
  29765. }
  29766. lob_stream_mode_flag_ = str_->get_lob_stream_flag();
  29767. allocate_arrays();
  29768. }
  29769. void reattach() {
  29770. if (!str_->good()) {
  29771. reset();
  29772. OTL_THROW((OTLException(otl_error_msg_19, otl_error_code_19)));
  29773. }
  29774. out_vars_ = str_->describe_out_vars(out_vars_len_);
  29775. if (!out_vars_) {
  29776. reset();
  29777. OTL_THROW((OTLException(otl_error_msg_21, otl_error_code_21)));
  29778. } else {
  29779. #if defined(OTL_STL)
  29780. var_name2pos_map_.clear();
  29781. for (int i = 0; i < out_vars_len_; ++i) {
  29782. const otl_var_desc &curr_var = out_vars_[i];
  29783. var_name2pos_map_[curr_var.name] = i;
  29784. }
  29785. #endif
  29786. #if defined(OTL_ACE)
  29787. var_name2pos_map_.close();
  29788. for (int i = 0; i < out_vars_len_; ++i) {
  29789. const otl_var_desc &curr_var = out_vars_[i];
  29790. var_name2pos_map_.bind(curr_var.name, i);
  29791. }
  29792. #endif
  29793. }
  29794. lob_stream_mode_flag_ = str_->get_lob_stream_flag();
  29795. }
  29796. void detach(void) { reset(); }
  29797. OTL_NODISCARD const otl_var_desc *describe(int &var_desc_len) {
  29798. var_desc_len = out_vars_len_;
  29799. return out_vars_;
  29800. }
  29801. OTL_NODISCARD bool next_row(void) {
  29802. if (str_->eof()){
  29803. last_eof_=true;
  29804. return false;
  29805. }
  29806. for (int i = 0; i < out_vars_len_; ++i) {
  29807. otl_var_desc &curr_var = out_vars_[i];
  29808. unsigned char *curr_ptr = out_vars_arr_[i];
  29809. switch (curr_var.ftype) {
  29810. case otl_var_char:
  29811. (*str_) >> OTL_RCAST(char *, curr_ptr);
  29812. break;
  29813. case otl_var_double:
  29814. (*str_) >> *OTL_RCAST(double *, curr_ptr);
  29815. break;
  29816. case otl_var_float:
  29817. (*str_) >> *OTL_RCAST(float *, curr_ptr);
  29818. break;
  29819. case otl_var_int:
  29820. (*str_) >> *OTL_RCAST(int *, curr_ptr);
  29821. break;
  29822. case otl_var_unsigned_int:
  29823. (*str_) >> *OTL_RCAST(unsigned *, curr_ptr);
  29824. break;
  29825. case otl_var_short:
  29826. (*str_) >> *OTL_RCAST(short int *, curr_ptr);
  29827. break;
  29828. case otl_var_long_int:
  29829. (*str_) >> *OTL_RCAST(long int *, curr_ptr);
  29830. break;
  29831. case otl_var_raw:
  29832. (*str_) >> *OTL_RCAST(otl_long_string *, curr_ptr);
  29833. break;
  29834. case otl_var_timestamp:
  29835. case otl_var_db2time:
  29836. case otl_var_db2date:
  29837. case otl_var_tz_timestamp:
  29838. case otl_var_ltz_timestamp:
  29839. (*str_) >> *OTL_RCAST(otl_datetime *, curr_ptr);
  29840. break;
  29841. case otl_var_varchar_long:
  29842. case otl_var_raw_long:
  29843. case otl_var_clob:
  29844. case otl_var_blob:
  29845. if (lob_stream_mode_flag_)
  29846. (*str_) >> *OTL_RCAST(OTLLobStream *, curr_ptr);
  29847. else
  29848. (*str_) >> *OTL_RCAST(otl_long_string *, curr_ptr);
  29849. break;
  29850. #if defined(OTL_BIGINT)
  29851. case otl_var_bigint:
  29852. (*str_) >> *OTL_RCAST(OTL_BIGINT *, curr_ptr);
  29853. break;
  29854. #endif
  29855. #if defined(OTL_UBIGINT)
  29856. case otl_var_ubigint:
  29857. (*str_) >> *OTL_RCAST(OTL_UBIGINT *, curr_ptr);
  29858. break;
  29859. #endif
  29860. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  29861. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  29862. case otl_var_numeric_type_1:
  29863. (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_1 *, curr_ptr);
  29864. break;
  29865. #endif
  29866. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  29867. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  29868. case otl_var_numeric_type_2:
  29869. (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_2 *, curr_ptr);
  29870. break;
  29871. #endif
  29872. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  29873. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  29874. case otl_var_numeric_type_3:
  29875. (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_3 *, curr_ptr);
  29876. break;
  29877. #endif
  29878. }
  29879. out_vars_null_arr_[i] = str_->is_null() == 1;
  29880. }
  29881. last_eof_=false;
  29882. return true;
  29883. }
  29884. void get(const int pos, OTLLobStream *&s) {
  29885. check_pos(pos);
  29886. check_type(pos, otl_var_long_string, true);
  29887. if (!lob_stream_mode_flag_) {
  29888. char var_info[255];
  29889. otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype,
  29890. otl_var_lob_stream, var_info, sizeof(var_info));
  29891. OTL_THROW((OTLException(otl_error_msg_25, otl_error_code_25,
  29892. str_->get_stm_text(), var_info)));
  29893. }
  29894. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  29895. s = OTL_RCAST(OTLLobStream *, curr_ptr);
  29896. }
  29897. #if defined(OTL_STL)
  29898. void get(const char *var_name, OTLLobStream *&n) {
  29899. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  29900. check_name(it, var_name);
  29901. get((*it).second + 1, n);
  29902. }
  29903. #endif
  29904. #if defined(OTL_ACE)
  29905. void get(const char *var_name, OTLLobStream *&n) {
  29906. var_name2pos_map_type::ENTRY *it = nullptr;
  29907. var_name2pos_map_.find(var_name, it);
  29908. check_name(it, var_name);
  29909. get(it->item() + 1, n);
  29910. }
  29911. #endif
  29912. void get(const int pos, char &c) {
  29913. check_pos(pos);
  29914. check_type(pos, otl_var_char);
  29915. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  29916. c = OTL_SCAST(char, *curr_ptr);
  29917. }
  29918. #if defined(OTL_STL)
  29919. void get(const char *var_name, char &n) {
  29920. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  29921. check_name(it, var_name);
  29922. get((*it).second + 1, n);
  29923. }
  29924. #endif
  29925. #if defined(OTL_ACE)
  29926. void get(const char *var_name, char &n) {
  29927. var_name2pos_map_type::ENTRY *it = nullptr;
  29928. var_name2pos_map_.find(var_name, it);
  29929. check_name(it, var_name);
  29930. get(it->item() + 1, n);
  29931. }
  29932. #endif
  29933. void get(const int pos, unsigned char &c) {
  29934. check_pos(pos);
  29935. check_type(pos, otl_var_char);
  29936. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  29937. c = *curr_ptr;
  29938. }
  29939. #if defined(OTL_STL)
  29940. void get(const char *var_name, unsigned char &n) {
  29941. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  29942. check_name(it, var_name);
  29943. get((*it).second + 1, n);
  29944. }
  29945. #endif
  29946. #if defined(OTL_ACE)
  29947. void get(const char *var_name, unsigned char &n) {
  29948. var_name2pos_map_type::ENTRY *it = nullptr;
  29949. var_name2pos_map_.find(var_name, it);
  29950. check_name(it, var_name);
  29951. get(it->item() + 1, n);
  29952. }
  29953. #endif
  29954. void get(const int pos, char *s) {
  29955. check_pos(pos);
  29956. check_type(pos, otl_var_char);
  29957. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  29958. otl_strcpy(OTL_RCAST(unsigned char *, s),
  29959. OTL_RCAST(const unsigned char *, curr_ptr));
  29960. }
  29961. #if defined(OTL_STL)
  29962. void get(const char *var_name, char *n) {
  29963. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  29964. check_name(it, var_name);
  29965. get((*it).second + 1, n);
  29966. }
  29967. #endif
  29968. #if defined(OTL_ACE)
  29969. void get(const char *var_name, char *n) {
  29970. var_name2pos_map_type::ENTRY *it = nullptr;
  29971. var_name2pos_map_.find(var_name, it);
  29972. check_name(it, var_name);
  29973. get(it->item() + 1, n);
  29974. }
  29975. #endif
  29976. void get(const int pos, unsigned char *s) {
  29977. check_pos(pos);
  29978. check_type(pos, otl_var_char);
  29979. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  29980. otl_strcpy(OTL_RCAST(unsigned char *, s),
  29981. OTL_RCAST(const unsigned char *, curr_ptr));
  29982. }
  29983. #if defined(OTL_STL)
  29984. void get(const char *var_name, unsigned char *n) {
  29985. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  29986. check_name(it, var_name);
  29987. get((*it).second + 1, n);
  29988. }
  29989. #endif
  29990. #if defined(OTL_ACE)
  29991. void get(const char *var_name, unsigned char *n) {
  29992. var_name2pos_map_type::ENTRY *it = nullptr;
  29993. var_name2pos_map_.find(var_name, it);
  29994. check_name(it, var_name);
  29995. get(it->item() + 1, n);
  29996. }
  29997. #endif
  29998. void get(const int pos, unsigned int &n) {
  29999. check_pos(pos);
  30000. void *curr_ptr = out_vars_arr_[pos - 1];
  30001. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30002. int match_found = otl_numeric_convert_T<unsigned, otl_var_unsigned_int>(
  30003. out_vars_[pos - 1].ftype, curr_ptr, n);
  30004. #else
  30005. int match_found =
  30006. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30007. #endif
  30008. if (match_found)
  30009. return;
  30010. check_type(pos, otl_var_unsigned_int);
  30011. }
  30012. #if defined(OTL_STL)
  30013. void get(const char *var_name, unsigned int &n) {
  30014. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30015. check_name(it, var_name);
  30016. get((*it).second + 1, n);
  30017. }
  30018. #endif
  30019. #if defined(OTL_ACE)
  30020. void get(const char *var_name, unsigned int &n) {
  30021. var_name2pos_map_type::ENTRY *it = nullptr;
  30022. var_name2pos_map_.find(var_name, it);
  30023. check_name(it, var_name);
  30024. get(it->item() + 1, n);
  30025. }
  30026. #endif
  30027. void get(const int pos, int &n) {
  30028. check_pos(pos);
  30029. void *curr_ptr = out_vars_arr_[pos - 1];
  30030. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30031. int match_found = otl_numeric_convert_T<int, otl_var_int>(
  30032. out_vars_[pos - 1].ftype, curr_ptr, n);
  30033. #else
  30034. int match_found =
  30035. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30036. #endif
  30037. if (match_found)
  30038. return;
  30039. check_type(pos, otl_var_unsigned_int);
  30040. }
  30041. #if defined(OTL_STL)
  30042. void get(const char *var_name, int &n) {
  30043. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30044. check_name(it, var_name);
  30045. get((*it).second + 1, n);
  30046. }
  30047. #endif
  30048. #if defined(OTL_ACE)
  30049. void get(const char *var_name, int &n) {
  30050. var_name2pos_map_type::ENTRY *it = nullptr;
  30051. var_name2pos_map_.find(var_name, it);
  30052. check_name(it, var_name);
  30053. get(it->item() + 1, n);
  30054. }
  30055. #endif
  30056. void get(const int pos, short int &n) {
  30057. check_pos(pos);
  30058. void *curr_ptr = out_vars_arr_[pos - 1];
  30059. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30060. int match_found = otl_numeric_convert_T<short, otl_var_short>(
  30061. out_vars_[pos - 1].ftype, curr_ptr, n);
  30062. #else
  30063. int match_found =
  30064. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30065. #endif
  30066. if (match_found)
  30067. return;
  30068. check_type(pos, otl_var_short);
  30069. }
  30070. #if defined(OTL_STL)
  30071. void get(const char *var_name, short int &n) {
  30072. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30073. check_name(it, var_name);
  30074. get((*it).second + 1, n);
  30075. }
  30076. #endif
  30077. #if defined(OTL_ACE)
  30078. void get(const char *var_name, short int &n) {
  30079. var_name2pos_map_type::ENTRY *it = nullptr;
  30080. var_name2pos_map_.find(var_name, it);
  30081. check_name(it, var_name);
  30082. get(it->item() + 1, n);
  30083. }
  30084. #endif
  30085. void get(const int pos, long int &n) {
  30086. check_pos(pos);
  30087. void *curr_ptr = out_vars_arr_[pos - 1];
  30088. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30089. int match_found = otl_numeric_convert_T<long int, otl_var_long_int>(
  30090. out_vars_[pos - 1].ftype, curr_ptr, n);
  30091. #else
  30092. int match_found =
  30093. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30094. #endif
  30095. if (match_found)
  30096. return;
  30097. check_type(pos, otl_var_long_int);
  30098. }
  30099. #if defined(OTL_STL)
  30100. void get(const char *var_name, long int &n) {
  30101. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30102. check_name(it, var_name);
  30103. get((*it).second + 1, n);
  30104. }
  30105. #endif
  30106. #if defined(OTL_ACE)
  30107. void get(const char *var_name, long int &n) {
  30108. var_name2pos_map_type::ENTRY *it = nullptr;
  30109. var_name2pos_map_.find(var_name, it);
  30110. check_name(it, var_name);
  30111. get(it->item() + 1, n);
  30112. }
  30113. #endif
  30114. void get(const int pos, float &n) {
  30115. check_pos(pos);
  30116. void *curr_ptr = out_vars_arr_[pos - 1];
  30117. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30118. int match_found = otl_numeric_convert_T<float, otl_var_float>(
  30119. out_vars_[pos - 1].ftype, curr_ptr, n);
  30120. #else
  30121. int match_found =
  30122. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30123. #endif
  30124. if (match_found)
  30125. return;
  30126. check_type(pos, otl_var_double);
  30127. }
  30128. #if defined(OTL_STL)
  30129. void get(const char *var_name, float &n) {
  30130. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30131. check_name(it, var_name);
  30132. get((*it).second + 1, n);
  30133. }
  30134. #endif
  30135. #if defined(OTL_ACE)
  30136. void get(const char *var_name, float &n) {
  30137. var_name2pos_map_type::ENTRY *it = nullptr;
  30138. var_name2pos_map_.find(var_name, it);
  30139. check_name(it, var_name);
  30140. get(it->item() + 1, n);
  30141. }
  30142. #endif
  30143. void get(const int pos, double &n) {
  30144. check_pos(pos);
  30145. void *curr_ptr = out_vars_arr_[pos - 1];
  30146. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30147. int match_found = otl_numeric_convert_T<double, otl_var_double>(
  30148. out_vars_[pos - 1].ftype, curr_ptr, n);
  30149. #else
  30150. int match_found =
  30151. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30152. #endif
  30153. if (match_found)
  30154. return;
  30155. check_type(pos, otl_var_double);
  30156. }
  30157. #if defined(OTL_STL)
  30158. void get(const char *var_name, double &n) {
  30159. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30160. check_name(it, var_name);
  30161. get((*it).second + 1, n);
  30162. }
  30163. #endif
  30164. #if defined(OTL_ACE)
  30165. void get(const char *var_name, double &n) {
  30166. var_name2pos_map_type::ENTRY *it = nullptr;
  30167. var_name2pos_map_.find(var_name, it);
  30168. check_name(it, var_name);
  30169. get(it->item() + 1, n);
  30170. }
  30171. #endif
  30172. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  30173. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  30174. void get(const int pos, OTL_NUMERIC_TYPE_1 &n) {
  30175. check_pos(pos);
  30176. void *curr_ptr = out_vars_arr_[pos - 1];
  30177. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30178. int match_found =
  30179. otl_numeric_convert_T<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(
  30180. out_vars_[pos - 1].ftype, curr_ptr, n);
  30181. #else
  30182. int match_found =
  30183. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30184. #endif
  30185. if (match_found)
  30186. return;
  30187. #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR)
  30188. if (out_vars_[pos - 1].ftype == otl_var_char) {
  30189. char *temp_val = OTL_RCAST(char *, curr_ptr);
  30190. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  30191. if (is_null(pos)) {
  30192. n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  30193. return;
  30194. }
  30195. #endif
  30196. OTL_STR_TO_NUMERIC_TYPE_1(temp_val, n);
  30197. return;
  30198. }
  30199. check_type(pos, otl_var_numeric_type_1);
  30200. #else
  30201. check_type(pos, otl_var_numeric_type_1);
  30202. #endif
  30203. }
  30204. #if defined(OTL_STL)
  30205. void get(const char *var_name, OTL_NUMERIC_TYPE_1 &n) {
  30206. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30207. check_name(it, var_name);
  30208. get((*it).second + 1, n);
  30209. }
  30210. #endif
  30211. #if defined(OTL_ACE)
  30212. void get(const char *var_name, OTL_NUMERIC_TYPE_1 &n) {
  30213. var_name2pos_map_type::ENTRY *it = nullptr;
  30214. var_name2pos_map_.find(var_name, it);
  30215. check_name(it, var_name);
  30216. get(it->item() + 1, n);
  30217. }
  30218. #endif
  30219. #endif
  30220. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  30221. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  30222. void get(const int pos, OTL_NUMERIC_TYPE_2 &n) {
  30223. check_pos(pos);
  30224. void *curr_ptr = out_vars_arr_[pos - 1];
  30225. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30226. int match_found =
  30227. otl_numeric_convert_T<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(
  30228. out_vars_[pos - 1].ftype, curr_ptr, n);
  30229. #else
  30230. int match_found =
  30231. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30232. #endif
  30233. if (match_found)
  30234. return;
  30235. #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR)
  30236. if (out_vars_[pos - 1].ftype == otl_var_char) {
  30237. char *temp_val = OTL_RCAST(char *, curr_ptr);
  30238. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  30239. if (is_null(pos)) {
  30240. n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  30241. return;
  30242. }
  30243. #endif
  30244. OTL_STR_TO_NUMERIC_TYPE_2(temp_val, n);
  30245. return;
  30246. }
  30247. check_type(pos, otl_var_numeric_type_2);
  30248. #else
  30249. check_type(pos, otl_var_numeric_type_2);
  30250. #endif
  30251. }
  30252. #if defined(OTL_STL)
  30253. void get(const char *var_name, OTL_NUMERIC_TYPE_2 &n) {
  30254. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30255. check_name(it, var_name);
  30256. get((*it).second + 1, n);
  30257. }
  30258. #endif
  30259. #if defined(OTL_ACE)
  30260. void get(const char *var_name, OTL_NUMERIC_TYPE_2 &n) {
  30261. var_name2pos_map_type::ENTRY *it = nullptr;
  30262. var_name2pos_map_.find(var_name, it);
  30263. check_name(it, var_name);
  30264. get(it->item() + 1, n);
  30265. }
  30266. #endif
  30267. #endif
  30268. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  30269. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  30270. void get(const int pos, OTL_NUMERIC_TYPE_3 &n) {
  30271. check_pos(pos);
  30272. void *curr_ptr = out_vars_arr_[pos - 1];
  30273. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30274. int match_found =
  30275. otl_numeric_convert_T<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(
  30276. out_vars_[pos - 1].ftype, curr_ptr, n);
  30277. #else
  30278. int match_found =
  30279. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30280. #endif
  30281. if (match_found)
  30282. return;
  30283. #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR)
  30284. if (out_vars_[pos - 1].ftype == otl_var_char) {
  30285. char *temp_val = OTL_RCAST(char *, curr_ptr);
  30286. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  30287. if (is_null(pos)) {
  30288. n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  30289. return;
  30290. }
  30291. #endif
  30292. OTL_STR_TO_NUMERIC_TYPE_3(temp_val, n);
  30293. return;
  30294. }
  30295. check_type(pos, otl_var_numeric_type_3);
  30296. #else
  30297. check_type(pos, otl_var_numeric_type_3);
  30298. #endif
  30299. }
  30300. #if defined(OTL_STL)
  30301. void get(const char *var_name, OTL_NUMERIC_TYPE_3 &n) {
  30302. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30303. check_name(it, var_name);
  30304. get((*it).second + 1, n);
  30305. }
  30306. #endif
  30307. #if defined(OTL_ACE)
  30308. void get(const char *var_name, OTL_NUMERIC_TYPE_3 &n) {
  30309. var_name2pos_map_type::ENTRY *it = nullptr;
  30310. var_name2pos_map_.find(var_name, it);
  30311. check_name(it, var_name);
  30312. get(it->item() + 1, n);
  30313. }
  30314. #endif
  30315. #endif
  30316. #if defined(OTL_BIGINT)
  30317. void get(const int pos, OTL_BIGINT &n) {
  30318. check_pos(pos);
  30319. void *curr_ptr = out_vars_arr_[pos - 1];
  30320. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30321. int match_found = otl_numeric_convert_T<OTL_BIGINT, otl_var_bigint>(
  30322. out_vars_[pos - 1].ftype, curr_ptr, n);
  30323. #else
  30324. int match_found =
  30325. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30326. #endif
  30327. if (match_found)
  30328. return;
  30329. #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR)
  30330. if (out_vars_[pos - 1].ftype == otl_var_char) {
  30331. char *temp_val = OTL_RCAST(char *, curr_ptr);
  30332. #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL)
  30333. if (is_null(pos)) {
  30334. n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL);
  30335. return;
  30336. }
  30337. #endif
  30338. OTL_STR_TO_BIGINT(temp_val, n);
  30339. return;
  30340. }
  30341. check_type(pos, otl_var_bigint);
  30342. #else
  30343. check_type(pos, otl_var_bigint);
  30344. #endif
  30345. }
  30346. #if defined(OTL_STL)
  30347. void get(const char *var_name, OTL_BIGINT &n) {
  30348. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30349. check_name(it, var_name);
  30350. get((*it).second + 1, n);
  30351. }
  30352. #endif
  30353. #if defined(OTL_ACE)
  30354. void get(const char *var_name, OTL_BIGINT &n) {
  30355. var_name2pos_map_type::ENTRY *it = nullptr;
  30356. var_name2pos_map_.find(var_name, it);
  30357. check_name(it, var_name);
  30358. get(it->item() + 1, n);
  30359. }
  30360. #endif
  30361. #endif
  30362. #if defined(OTL_UBIGINT)
  30363. void get(const int pos, OTL_UBIGINT &n) {
  30364. check_pos(pos);
  30365. void *curr_ptr = out_vars_arr_[pos - 1];
  30366. #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT)
  30367. int match_found = otl_numeric_convert_T<OTL_UBIGINT, otl_var_ubigint>(
  30368. out_vars_[pos - 1].ftype, curr_ptr, n);
  30369. #else
  30370. int match_found =
  30371. otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n);
  30372. #endif
  30373. if (match_found)
  30374. return;
  30375. check_type(pos, otl_var_ubigint);
  30376. }
  30377. #if defined(OTL_STL)
  30378. void get(const char *var_name, OTL_UBIGINT &n) {
  30379. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30380. check_name(it, var_name);
  30381. get((*it).second + 1, n);
  30382. }
  30383. #endif
  30384. #if defined(OTL_ACE)
  30385. void get(const char *var_name, OTL_UBIGINT &n) {
  30386. var_name2pos_map_type::ENTRY *it = nullptr;
  30387. var_name2pos_map_.find(var_name, it);
  30388. check_name(it, var_name);
  30389. get(it->item() + 1, n);
  30390. }
  30391. #endif
  30392. #endif
  30393. OTL_NODISCARD bool is_null(const int pos) {
  30394. check_pos(pos);
  30395. return out_vars_null_arr_[pos - 1];
  30396. }
  30397. #if defined(OTL_STL)
  30398. OTL_NODISCARD bool is_null(const char *var_name) {
  30399. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30400. check_name(it, var_name);
  30401. return is_null((*it).second + 1);
  30402. }
  30403. #endif
  30404. #if defined(OTL_ACE)
  30405. OTL_NODISCARD bool is_null(const char *var_name) {
  30406. var_name2pos_map_type::ENTRY *it = nullptr;
  30407. var_name2pos_map_.find(var_name, it);
  30408. check_name(it, var_name);
  30409. return is_null(it->item() + 1);
  30410. }
  30411. #endif
  30412. #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)
  30413. void get(const int pos, OTL_STRING_CONTAINER &s) {
  30414. check_pos(pos);
  30415. otl_var_desc &curr_var = out_vars_[pos - 1];
  30416. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  30417. switch (curr_var.ftype) {
  30418. case otl_var_varchar_long:
  30419. case otl_var_raw_long:
  30420. case otl_var_clob:
  30421. case otl_var_blob: {
  30422. otl_long_string *ls = OTL_RCAST(otl_long_string *, curr_ptr);
  30423. int len = ls->len();
  30424. #if defined(OTL_STL) && !defined(USER_DEFINED_STRING_CLASS)
  30425. s.assign(OTL_RCAST(char *, ls->v), OTL_SCAST(size_t, len));
  30426. #else
  30427. s.assign(OTL_RCAST(char *, ls->v), len);
  30428. #endif
  30429. } break;
  30430. case otl_var_char:
  30431. s = OTL_RCAST(char *, curr_ptr);
  30432. break;
  30433. default: {
  30434. char var_info[255];
  30435. otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype,
  30436. otl_var_char, var_info, sizeof(var_info));
  30437. OTL_THROW((OTLException(otl_error_msg_23, otl_error_code_23,
  30438. str_->get_stm_text(), var_info)));
  30439. }
  30440. }
  30441. }
  30442. #endif
  30443. #if defined(OTL_STL)
  30444. void get(const char *var_name, OTL_STRING_CONTAINER &n) {
  30445. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30446. check_name(it, var_name);
  30447. get((*it).second + 1, n);
  30448. }
  30449. #endif
  30450. #if defined(OTL_ACE)
  30451. void get(const char *var_name, OTL_STRING_CONTAINER &n) {
  30452. var_name2pos_map_type::ENTRY *it = nullptr;
  30453. var_name2pos_map_.find(var_name, it);
  30454. check_name(it, var_name);
  30455. get(it->item() + 1, n);
  30456. }
  30457. #endif
  30458. void get(const int pos, otl_long_string &s) {
  30459. check_pos(pos);
  30460. check_type(pos, otl_var_long_string);
  30461. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  30462. s = *OTL_RCAST(otl_long_string *, curr_ptr);
  30463. }
  30464. #if defined(OTL_STL)
  30465. void get(const char *var_name, otl_long_string &n) {
  30466. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30467. check_name(it, var_name);
  30468. get((*it).second + 1, n);
  30469. }
  30470. #endif
  30471. #if defined(OTL_ACE)
  30472. void get(const char *var_name, otl_long_string &n) {
  30473. var_name2pos_map_type::ENTRY *it = nullptr;
  30474. var_name2pos_map_.find(var_name, it);
  30475. check_name(it, var_name);
  30476. get(it->item() + 1, n);
  30477. }
  30478. #endif
  30479. void get(const int pos, otl_long_string *&s) {
  30480. check_pos(pos);
  30481. check_type(pos, otl_var_long_string);
  30482. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  30483. s = OTL_RCAST(otl_long_string *, curr_ptr);
  30484. }
  30485. #if defined(OTL_STL)
  30486. void get(const char *var_name, otl_long_string *&n) {
  30487. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30488. check_name(it, var_name);
  30489. get((*it).second + 1, n);
  30490. }
  30491. #endif
  30492. #if defined(OTL_ACE)
  30493. void get(const char *var_name, otl_long_string *&n) {
  30494. var_name2pos_map_type::ENTRY *it = nullptr;
  30495. var_name2pos_map_.find(var_name, it);
  30496. check_name(it, var_name);
  30497. get(it->item() + 1, n);
  30498. }
  30499. #endif
  30500. void get(const int pos, otl_datetime &s) {
  30501. check_pos(pos);
  30502. check_type(pos, otl_var_timestamp);
  30503. unsigned char *curr_ptr = out_vars_arr_[pos - 1];
  30504. s = *OTL_RCAST(otl_datetime *, curr_ptr);
  30505. }
  30506. #if defined(OTL_STL)
  30507. void get(const char *var_name, otl_datetime &n) {
  30508. var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name);
  30509. check_name(it, var_name);
  30510. get((*it).second + 1, n);
  30511. }
  30512. #endif
  30513. #if defined(OTL_ACE)
  30514. void get(const char *var_name, otl_datetime &n) {
  30515. var_name2pos_map_type::ENTRY *it = nullptr;
  30516. var_name2pos_map_.find(var_name, it);
  30517. check_name(it, var_name);
  30518. get(it->item() + 1, n);
  30519. }
  30520. #endif
  30521. OTL_NODISCARD bool get_last_eof(){
  30522. return last_eof_;
  30523. }
  30524. protected:
  30525. otl_var_desc *out_vars_;
  30526. int out_vars_len_;
  30527. OTLStream *str_;
  30528. unsigned char **out_vars_arr_;
  30529. bool *out_vars_null_arr_;
  30530. bool out_vars_constructed_;
  30531. bool lob_stream_mode_flag_;
  30532. bool last_eof_;
  30533. #if defined(OTL_STL)
  30534. typedef STD_NAMESPACE_PREFIX map<const char *, int, otl_ltcharstar>
  30535. var_name2pos_map_type;
  30536. var_name2pos_map_type var_name2pos_map_;
  30537. #endif
  30538. #if defined(OTL_ACE)
  30539. typedef ACE_RB_Tree<const char *, int, otl_ltcharstar, ACE_Null_Mutex>
  30540. var_name2pos_map_type;
  30541. var_name2pos_map_type var_name2pos_map_;
  30542. #endif
  30543. void check_pos(const int pos) {
  30544. int actual_pos = pos - 1;
  30545. if (actual_pos < 0 || actual_pos > out_vars_len_ - 1) {
  30546. OTL_THROW((OTLException(otl_error_msg_22, otl_error_code_22,
  30547. str_->get_stm_text())));
  30548. }
  30549. }
  30550. #if defined(OTL_STL)
  30551. void check_name(var_name2pos_map_type::iterator &it, const char *var_name) {
  30552. if (it == var_name2pos_map_.end())
  30553. OTL_THROW((OTLException(otl_error_msg_26, otl_error_code_26,
  30554. str_->get_stm_text(), var_name)));
  30555. }
  30556. #endif
  30557. #if defined(OTL_ACE)
  30558. void check_name(var_name2pos_map_type::ENTRY *it, const char *var_name) {
  30559. if (!it) {
  30560. OTL_THROW((OTLException(otl_error_msg_26, otl_error_code_26,
  30561. str_->get_stm_text(), var_name)));
  30562. }
  30563. }
  30564. #endif
  30565. void check_type(const int pos, const int type_code,
  30566. const bool lob_stream_arg = false) {
  30567. switch (out_vars_[pos - 1].ftype) {
  30568. case otl_var_timestamp:
  30569. case otl_var_tz_timestamp:
  30570. case otl_var_ltz_timestamp:
  30571. if (type_code == otl_var_timestamp)
  30572. return;
  30573. break;
  30574. case otl_var_varchar_long:
  30575. case otl_var_raw_long:
  30576. case otl_var_clob:
  30577. case otl_var_blob:
  30578. if (type_code == otl_var_long_string)
  30579. return;
  30580. break;
  30581. case otl_var_raw:
  30582. if (type_code == otl_var_long_string && lob_stream_mode_flag_ &&
  30583. lob_stream_arg) {
  30584. char var_info1[255];
  30585. otl_var_info_var4(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype,
  30586. otl_var_lob_stream, var_info1, sizeof(var_info1));
  30587. OTL_THROW((OTLException(otl_error_msg_28, otl_error_code_28,
  30588. str_->get_stm_text(), var_info1)));
  30589. } else
  30590. return;
  30591. default:
  30592. if (out_vars_[pos - 1].ftype == type_code)
  30593. return;
  30594. break;
  30595. }
  30596. char var_info2[255];
  30597. otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype,
  30598. type_code, var_info2, sizeof(var_info2));
  30599. OTL_THROW((OTLException(otl_error_msg_23, otl_error_code_23,
  30600. str_->get_stm_text(), var_info2)));
  30601. }
  30602. void set(void) {
  30603. out_vars_ = nullptr;
  30604. out_vars_len_ = 0;
  30605. str_ = nullptr;
  30606. out_vars_arr_ = nullptr;
  30607. out_vars_null_arr_ = nullptr;
  30608. out_vars_constructed_ = false;
  30609. lob_stream_mode_flag_ = false;
  30610. }
  30611. void reset(void) {
  30612. if (out_vars_constructed_) {
  30613. for (int i = 0; i < out_vars_len_; ++i) {
  30614. switch (out_vars_[i].ftype) {
  30615. case otl_var_char:
  30616. delete[] OTL_RCAST(char *, out_vars_arr_[i]);
  30617. break;
  30618. case otl_var_double:
  30619. delete OTL_RCAST(double *, out_vars_arr_[i]);
  30620. break;
  30621. case otl_var_float:
  30622. delete OTL_RCAST(float *, out_vars_arr_[i]);
  30623. break;
  30624. case otl_var_int:
  30625. delete OTL_RCAST(int *, out_vars_arr_[i]);
  30626. break;
  30627. case otl_var_unsigned_int:
  30628. delete OTL_RCAST(unsigned *, out_vars_arr_[i]);
  30629. break;
  30630. case otl_var_short:
  30631. delete OTL_RCAST(short int *, out_vars_arr_[i]);
  30632. break;
  30633. case otl_var_long_int:
  30634. delete OTL_RCAST(long int *, out_vars_arr_[i]);
  30635. break;
  30636. #if defined(OTL_BIGINT)
  30637. case otl_var_bigint:
  30638. delete OTL_RCAST(OTL_BIGINT *, out_vars_arr_[i]);
  30639. break;
  30640. #endif
  30641. #if defined(OTL_UBIGINT)
  30642. case otl_var_ubigint:
  30643. delete OTL_RCAST(OTL_UBIGINT *, out_vars_arr_[i]);
  30644. break;
  30645. #endif
  30646. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  30647. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  30648. case otl_var_numeric_type_1:
  30649. delete OTL_RCAST(OTL_NUMERIC_TYPE_1 *, out_vars_arr_[i]);
  30650. break;
  30651. #endif
  30652. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  30653. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  30654. case otl_var_numeric_type_2:
  30655. delete OTL_RCAST(OTL_NUMERIC_TYPE_2 *, out_vars_arr_[i]);
  30656. break;
  30657. #endif
  30658. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  30659. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  30660. case otl_var_numeric_type_3:
  30661. delete OTL_RCAST(OTL_NUMERIC_TYPE_3 *, out_vars_arr_[i]);
  30662. break;
  30663. #endif
  30664. case otl_var_raw:
  30665. delete OTL_RCAST(otl_long_string *, out_vars_arr_[i]);
  30666. break;
  30667. case otl_var_varchar_long:
  30668. case otl_var_raw_long:
  30669. case otl_var_clob:
  30670. case otl_var_blob:
  30671. if (lob_stream_mode_flag_)
  30672. delete OTL_RCAST(OTLLobStream *, out_vars_arr_[i]);
  30673. else
  30674. delete OTL_RCAST(otl_long_string *, out_vars_arr_[i]);
  30675. break;
  30676. case otl_var_timestamp:
  30677. delete OTL_RCAST(otl_datetime *, out_vars_arr_[i]);
  30678. break;
  30679. default:
  30680. break;
  30681. }
  30682. out_vars_arr_[i] = nullptr;
  30683. }
  30684. out_vars_constructed_ = false;
  30685. }
  30686. delete[] out_vars_arr_;
  30687. delete[] out_vars_null_arr_;
  30688. #if defined(OTL_STL) || defined(OTL_ACE)
  30689. var_name2pos_map_.clear();
  30690. #endif
  30691. set();
  30692. }
  30693. OTL_NODISCARD int calculate_buffer_size(const otl_var_desc *var, const int vars_len) {
  30694. for (int i = 0; i < vars_len; ++i) {
  30695. const otl_var_desc &curr_var = var[i];
  30696. if (curr_var.ftype == otl_var_refcur || curr_var.pl_tab_flag)
  30697. OTL_THROW((OTLException(otl_error_msg_20, otl_error_code_20)));
  30698. }
  30699. return vars_len;
  30700. }
  30701. void allocate_arrays(void) {
  30702. if (out_vars_) {
  30703. out_vars_null_arr_ = new bool[OTL_SCAST(size_t,out_vars_len_)];
  30704. int buf_size = calculate_buffer_size(out_vars_, out_vars_len_);
  30705. out_vars_arr_ = new unsigned char *[OTL_SCAST(size_t,buf_size)];
  30706. construct_elements();
  30707. }
  30708. }
  30709. void construct_elements(void) {
  30710. for (int i = 0; i < out_vars_len_; ++i) {
  30711. out_vars_null_arr_[i] = true;
  30712. const otl_var_desc &curr_var = out_vars_[i];
  30713. switch (curr_var.ftype) {
  30714. case otl_var_char: {
  30715. char *ptr = new char[OTL_SCAST(size_t,curr_var.elem_size)];
  30716. *ptr = 0;
  30717. out_vars_arr_[i] = OTL_RCAST(unsigned char *, ptr);
  30718. } break;
  30719. case otl_var_raw:
  30720. out_vars_arr_[i] =
  30721. OTL_RCAST(unsigned char *, new otl_long_string(curr_var.elem_size));
  30722. break;
  30723. case otl_var_double:
  30724. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new double(0));
  30725. break;
  30726. case otl_var_float:
  30727. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new float(0));
  30728. break;
  30729. case otl_var_int:
  30730. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new int(0));
  30731. break;
  30732. case otl_var_unsigned_int:
  30733. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new unsigned(0));
  30734. break;
  30735. case otl_var_short:
  30736. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new short(0));
  30737. break;
  30738. case otl_var_long_int:
  30739. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new long(0));
  30740. break;
  30741. case otl_var_timestamp:
  30742. case otl_var_db2time:
  30743. case otl_var_db2date:
  30744. case otl_var_tz_timestamp:
  30745. case otl_var_ltz_timestamp:
  30746. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new otl_datetime);
  30747. break;
  30748. case otl_var_varchar_long:
  30749. case otl_var_raw_long:
  30750. case otl_var_clob:
  30751. case otl_var_blob:
  30752. if (lob_stream_mode_flag_)
  30753. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTLLobStream());
  30754. else
  30755. out_vars_arr_[i] =
  30756. OTL_RCAST(unsigned char *,
  30757. new otl_long_string(str_->get_adb_max_long_size()));
  30758. break;
  30759. #if defined(OTL_BIGINT)
  30760. case otl_var_bigint:
  30761. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_BIGINT(0));
  30762. break;
  30763. #endif
  30764. #if defined(OTL_UBIGINT)
  30765. case otl_var_ubigint:
  30766. out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_UBIGINT(0));
  30767. break;
  30768. #endif
  30769. #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \
  30770. defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID)
  30771. case otl_var_numeric_type_1:
  30772. out_vars_arr_[i] =
  30773. OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_1(0));
  30774. break;
  30775. #endif
  30776. #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \
  30777. defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID)
  30778. case otl_var_numeric_type_2:
  30779. out_vars_arr_[i] =
  30780. OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_2(0));
  30781. break;
  30782. #endif
  30783. #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \
  30784. defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID)
  30785. case otl_var_numeric_type_3:
  30786. out_vars_arr_[i] =
  30787. OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_3(0));
  30788. break;
  30789. #endif
  30790. }
  30791. #if defined(OTL_STL)
  30792. var_name2pos_map_[curr_var.name] = i;
  30793. #endif
  30794. #if defined(OTL_ACE)
  30795. var_name2pos_map_.bind(curr_var.name, i);
  30796. #endif
  30797. }
  30798. out_vars_constructed_ = true;
  30799. }
  30800. private:
  30801. #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT)
  30802. public:
  30803. otl_stream_read_iterator(const otl_stream_read_iterator &) = delete;
  30804. otl_stream_read_iterator &operator=(const otl_stream_read_iterator &) =
  30805. delete;
  30806. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  30807. otl_stream_read_iterator(otl_stream_read_iterator &&) = delete;
  30808. otl_stream_read_iterator &operator=(otl_stream_read_iterator &&) = delete;
  30809. #endif
  30810. private:
  30811. #else
  30812. otl_stream_read_iterator(const otl_stream_read_iterator &)
  30813. : out_vars_(nullptr), out_vars_len_(0), str_(nullptr),
  30814. out_vars_arr_(nullptr), out_vars_null_arr_(nullptr),
  30815. out_vars_constructed_(nullptr), lob_stream_mode_flag_(false)
  30816. #if defined(OTL_STL)
  30817. ,
  30818. var_name2pos_map_()
  30819. #endif
  30820. #if defined(OTL_ACE)
  30821. ,
  30822. var_name2pos_map_()
  30823. #endif
  30824. {
  30825. }
  30826. otl_stream_read_iterator &operator=(const otl_stream_read_iterator &) {
  30827. return *this;
  30828. }
  30829. #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
  30830. otl_stream_read_iterator(otl_stream_read_iterator &&)
  30831. : out_vars_(nullptr), out_vars_len_(0), str_(nullptr),
  30832. out_vars_arr_(nullptr), out_vars_null_arr_(nullptr),
  30833. out_vars_constructed_(false), lob_stream_mode_flag_(false)
  30834. #if defined(OTL_STL)
  30835. ,
  30836. var_name2pos_map_()
  30837. #endif
  30838. #if defined(OTL_ACE)
  30839. ,
  30840. var_name2pos_map_()
  30841. #endif
  30842. {
  30843. }
  30844. otl_stream_read_iterator &operator=(otl_stream_read_iterator &&) {
  30845. return *this;
  30846. }
  30847. #endif
  30848. #endif
  30849. };
  30850. #endif
  30851. template <OTL_TYPE_NAME OTLStreamType, OTL_TYPE_NAME OutputIterator>
  30852. inline void otl_read_from_stream
  30853. (OTLStreamType &s,
  30854. OutputIterator result,
  30855. size_t max_number_of_rows_to_read=0) OTL_THROWS_OTL_EXCEPTION {
  30856. typename OutputIterator::container_type::value_type v;
  30857. if(max_number_of_rows_to_read == 0){
  30858. while (!s.eof()) {
  30859. s >> v;
  30860. #if defined(OTL_CPP_11_ON)
  30861. *result++ = std::move(v);
  30862. #else
  30863. *result++ = v;
  30864. #endif
  30865. }
  30866. }else{
  30867. size_t rpc=0;
  30868. while (!s.eof()) {
  30869. s >> v;
  30870. ++rpc;
  30871. if(rpc > max_number_of_rows_to_read)
  30872. return;
  30873. #if defined(OTL_CPP_11_ON)
  30874. *result++ = std::move(v);
  30875. #else
  30876. *result++ = v;
  30877. #endif
  30878. }
  30879. }
  30880. }
  30881. template <OTL_TYPE_NAME OTLStreamType, OTL_TYPE_NAME InputIterator>
  30882. inline void otl_write_to_stream(InputIterator first, InputIterator last,
  30883. OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION {
  30884. while (first != last) {
  30885. s << (*first++);
  30886. }
  30887. }
  30888. #if defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES)
  30889. #if defined(OTL_ANSI_CPP_17_FOLD_EXPRESSIONS) && defined(OTL_ANSI_CPP_17_CONSTEXPR_IF)
  30890. template<typename OTLStreamType, typename Arg1, typename...Args>
  30891. inline void otl_read_row(OTLStreamType &s, Arg1& arg1, Args&...args) OTL_THROWS_OTL_EXCEPTION {
  30892. s>>arg1;
  30893. if constexpr(sizeof...(args)>0) (s>>...>>args);
  30894. s.check_end_of_row();
  30895. }
  30896. template<typename OTLStreamType, typename Arg1, typename... Args>
  30897. inline void otl_write_row(OTLStreamType &s, Arg1&& arg1, Args&&...args) OTL_THROWS_OTL_EXCEPTION {
  30898. s<<std::forward<Arg1>(arg1);
  30899. if constexpr(sizeof...(args)>0) (s<<...<<std::forward<Args>(args));
  30900. s.check_end_of_row();
  30901. }
  30902. #else
  30903. template <typename OTLStreamType>
  30904. inline void __otl_read_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION {
  30905. s.check_end_of_row();
  30906. }
  30907. template <typename OTLStreamType, typename Arg1, typename... Args>
  30908. inline void __otl_read_row(OTLStreamType &s, Arg1 &arg1,
  30909. Args &... args) OTL_THROWS_OTL_EXCEPTION {
  30910. s >> arg1;
  30911. __otl_read_row(s, args...);
  30912. }
  30913. template <typename OTLStreamType, typename Arg1, typename... Args>
  30914. inline void otl_read_row(OTLStreamType &s, Arg1 &arg1,
  30915. Args &... args) OTL_THROWS_OTL_EXCEPTION {
  30916. s >> arg1;
  30917. __otl_read_row(s, args...);
  30918. }
  30919. template <typename OTLStreamType>
  30920. inline void __otl_write_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION {
  30921. s.check_end_of_row();
  30922. }
  30923. template <typename OTLStreamType, typename Arg1, typename... Args>
  30924. inline void __otl_write_row(OTLStreamType &s, Arg1 &&arg1,
  30925. Args &&... args) OTL_THROWS_OTL_EXCEPTION {
  30926. s << std::forward<Arg1>(arg1);
  30927. __otl_write_row(s, std::forward<Args>(args)...);
  30928. }
  30929. template <typename OTLStreamType, typename Arg1, typename... Args>
  30930. inline void otl_write_row(OTLStreamType &s, Arg1 &&arg1,
  30931. Args &&... args) OTL_THROWS_OTL_EXCEPTION {
  30932. s << std::forward<Arg1>(arg1);
  30933. __otl_write_row(s, std::forward<Args>(args)...);
  30934. }
  30935. #endif
  30936. #else
  30937. template <typename S, typename T1>
  30938. inline void otl_read_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION {
  30939. s >> t1;
  30940. s.check_end_of_row();
  30941. }
  30942. template <typename S, typename T1, typename T2>
  30943. inline void otl_read_row(S &s, T1 &t1, T2 &t2) OTL_THROWS_OTL_EXCEPTION {
  30944. s >> t1;
  30945. s >> t2;
  30946. s.check_end_of_row();
  30947. }
  30948. template <typename S, typename T1, typename T2, typename T3>
  30949. inline void otl_read_row(S &s, T1 &t1, T2 &t2,
  30950. T3 &t3) OTL_THROWS_OTL_EXCEPTION {
  30951. s >> t1;
  30952. s >> t2;
  30953. s >> t3;
  30954. s.check_end_of_row();
  30955. }
  30956. template <typename S, typename T1, typename T2, typename T3, typename T4>
  30957. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3,
  30958. T4 &t4) OTL_THROWS_OTL_EXCEPTION {
  30959. s >> t1;
  30960. s >> t2;
  30961. s >> t3;
  30962. s >> t4;
  30963. s.check_end_of_row();
  30964. }
  30965. template <typename S, typename T1, typename T2, typename T3, typename T4,
  30966. typename T5>
  30967. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4,
  30968. T5 &t5) OTL_THROWS_OTL_EXCEPTION {
  30969. s >> t1;
  30970. s >> t2;
  30971. s >> t3;
  30972. s >> t4;
  30973. s >> t5;
  30974. s.check_end_of_row();
  30975. }
  30976. template <typename S, typename T1, typename T2, typename T3, typename T4,
  30977. typename T5, typename T6>
  30978. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5,
  30979. T6 &t6) OTL_THROWS_OTL_EXCEPTION {
  30980. s >> t1;
  30981. s >> t2;
  30982. s >> t3;
  30983. s >> t4;
  30984. s >> t5;
  30985. s >> t6;
  30986. s.check_end_of_row();
  30987. }
  30988. template <typename S, typename T1, typename T2, typename T3, typename T4,
  30989. typename T5, typename T6, typename T7>
  30990. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  30991. T7 &t7) OTL_THROWS_OTL_EXCEPTION {
  30992. s >> t1;
  30993. s >> t2;
  30994. s >> t3;
  30995. s >> t4;
  30996. s >> t5;
  30997. s >> t6;
  30998. s >> t7;
  30999. s.check_end_of_row();
  31000. }
  31001. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31002. typename T5, typename T6, typename T7, typename T8>
  31003. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31004. T7 &t7, T8 &t8) OTL_THROWS_OTL_EXCEPTION {
  31005. s >> t1;
  31006. s >> t2;
  31007. s >> t3;
  31008. s >> t4;
  31009. s >> t5;
  31010. s >> t6;
  31011. s >> t7;
  31012. s >> t8;
  31013. s.check_end_of_row();
  31014. }
  31015. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31016. typename T5, typename T6, typename T7, typename T8, typename T9>
  31017. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31018. T7 &t7, T8 &t8, T9 &t9) OTL_THROWS_OTL_EXCEPTION {
  31019. s >> t1;
  31020. s >> t2;
  31021. s >> t3;
  31022. s >> t4;
  31023. s >> t5;
  31024. s >> t6;
  31025. s >> t7;
  31026. s >> t8;
  31027. s >> t9;
  31028. s.check_end_of_row();
  31029. }
  31030. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31031. typename T5, typename T6, typename T7, typename T8, typename T9,
  31032. typename T10>
  31033. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31034. T7 &t7, T8 &t8, T9 &t9,
  31035. T10 &t10) OTL_THROWS_OTL_EXCEPTION {
  31036. s >> t1;
  31037. s >> t2;
  31038. s >> t3;
  31039. s >> t4;
  31040. s >> t5;
  31041. s >> t6;
  31042. s >> t7;
  31043. s >> t8;
  31044. s >> t9;
  31045. s >> t10;
  31046. s.check_end_of_row();
  31047. }
  31048. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31049. typename T5, typename T6, typename T7, typename T8, typename T9,
  31050. typename T10, typename T11>
  31051. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31052. T7 &t7, T8 &t8, T9 &t9, T10 &t10,
  31053. T11 &t11) OTL_THROWS_OTL_EXCEPTION {
  31054. s >> t1;
  31055. s >> t2;
  31056. s >> t3;
  31057. s >> t4;
  31058. s >> t5;
  31059. s >> t6;
  31060. s >> t7;
  31061. s >> t8;
  31062. s >> t9;
  31063. s >> t10;
  31064. s >> t11;
  31065. s.check_end_of_row();
  31066. }
  31067. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31068. typename T5, typename T6, typename T7, typename T8, typename T9,
  31069. typename T10, typename T11, typename T12>
  31070. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31071. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11,
  31072. T12 &t12) OTL_THROWS_OTL_EXCEPTION {
  31073. s >> t1;
  31074. s >> t2;
  31075. s >> t3;
  31076. s >> t4;
  31077. s >> t5;
  31078. s >> t6;
  31079. s >> t7;
  31080. s >> t8;
  31081. s >> t9;
  31082. s >> t10;
  31083. s >> t11;
  31084. s >> t12;
  31085. s.check_end_of_row();
  31086. }
  31087. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31088. typename T5, typename T6, typename T7, typename T8, typename T9,
  31089. typename T10, typename T11, typename T12, typename T13>
  31090. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31091. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31092. T13 &t13) OTL_THROWS_OTL_EXCEPTION {
  31093. s >> t1;
  31094. s >> t2;
  31095. s >> t3;
  31096. s >> t4;
  31097. s >> t5;
  31098. s >> t6;
  31099. s >> t7;
  31100. s >> t8;
  31101. s >> t9;
  31102. s >> t10;
  31103. s >> t11;
  31104. s >> t12;
  31105. s >> t13;
  31106. s.check_end_of_row();
  31107. }
  31108. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31109. typename T5, typename T6, typename T7, typename T8, typename T9,
  31110. typename T10, typename T11, typename T12, typename T13, typename T14>
  31111. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31112. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31113. T13 &t13, T14 &t14) OTL_THROWS_OTL_EXCEPTION {
  31114. s >> t1;
  31115. s >> t2;
  31116. s >> t3;
  31117. s >> t4;
  31118. s >> t5;
  31119. s >> t6;
  31120. s >> t7;
  31121. s >> t8;
  31122. s >> t9;
  31123. s >> t10;
  31124. s >> t11;
  31125. s >> t12;
  31126. s >> t13;
  31127. s >> t14;
  31128. s.check_end_of_row();
  31129. }
  31130. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31131. typename T5, typename T6, typename T7, typename T8, typename T9,
  31132. typename T10, typename T11, typename T12, typename T13, typename T14,
  31133. typename T15>
  31134. inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31135. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31136. T13 &t13, T14 &t14,
  31137. T15 &t15) OTL_THROWS_OTL_EXCEPTION {
  31138. s >> t1;
  31139. s >> t2;
  31140. s >> t3;
  31141. s >> t4;
  31142. s >> t5;
  31143. s >> t6;
  31144. s >> t7;
  31145. s >> t8;
  31146. s >> t9;
  31147. s >> t10;
  31148. s >> t11;
  31149. s >> t12;
  31150. s >> t13;
  31151. s >> t14;
  31152. s >> t15;
  31153. s.check_end_of_row();
  31154. }
  31155. #if defined(_MSC_VER) && ((_MSC_VER == 1600) || (_MSC_VER == 1700))
  31156. // VC++ 2010, VC++ 2012: universal references are supported
  31157. template <typename S, typename T1>
  31158. inline void otl_write_row(S &s, T1 &&t1) OTL_THROWS_OTL_EXCEPTION {
  31159. s << std::forward<T1>(t1);
  31160. s.check_end_of_row();
  31161. }
  31162. template <typename S, typename T1, typename T2>
  31163. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2) OTL_THROWS_OTL_EXCEPTION {
  31164. s << std::forward<T1>(t1);
  31165. s << std::forward<T2>(t2);
  31166. s.check_end_of_row();
  31167. }
  31168. template <typename S, typename T1, typename T2, typename T3>
  31169. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2,
  31170. T3 &&t3) OTL_THROWS_OTL_EXCEPTION {
  31171. s << std::forward<T1>(t1);
  31172. s << std::forward<T2>(t2);
  31173. s << std::forward<T3>(t3);
  31174. s.check_end_of_row();
  31175. }
  31176. template <typename S, typename T1, typename T2, typename T3, typename T4>
  31177. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3,
  31178. T4 &&t4) OTL_THROWS_OTL_EXCEPTION {
  31179. s << std::forward<T1>(t1);
  31180. s << std::forward<T2>(t2);
  31181. s << std::forward<T3>(t3);
  31182. s << std::forward<T4>(t4);
  31183. s.check_end_of_row();
  31184. }
  31185. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31186. typename T5>
  31187. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4,
  31188. T5 &&t5) OTL_THROWS_OTL_EXCEPTION {
  31189. s << std::forward<T1>(t1);
  31190. s << std::forward<T2>(t2);
  31191. s << std::forward<T3>(t3);
  31192. s << std::forward<T4>(t4);
  31193. s << std::forward<T5>(t5);
  31194. s.check_end_of_row();
  31195. }
  31196. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31197. typename T5, typename T6>
  31198. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31199. T6 &&t6) OTL_THROWS_OTL_EXCEPTION {
  31200. s << std::forward<T1>(t1);
  31201. s << std::forward<T2>(t2);
  31202. s << std::forward<T3>(t3);
  31203. s << std::forward<T4>(t4);
  31204. s << std::forward<T5>(t5);
  31205. s << std::forward<T6>(t6);
  31206. s.check_end_of_row();
  31207. }
  31208. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31209. typename T5, typename T6, typename T7>
  31210. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31211. T6 &&t6, T7 &&t7) OTL_THROWS_OTL_EXCEPTION {
  31212. s << std::forward<T1>(t1);
  31213. s << std::forward<T2>(t2);
  31214. s << std::forward<T3>(t3);
  31215. s << std::forward<T4>(t4);
  31216. s << std::forward<T5>(t5);
  31217. s << std::forward<T6>(t6);
  31218. s << std::forward<T7>(t7);
  31219. s.check_end_of_row();
  31220. }
  31221. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31222. typename T5, typename T6, typename T7, typename T8>
  31223. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31224. T6 &&t6, T7 &&t7, T8 &&t8) OTL_THROWS_OTL_EXCEPTION {
  31225. s << std::forward<T1>(t1);
  31226. s << std::forward<T2>(t2);
  31227. s << std::forward<T3>(t3);
  31228. s << std::forward<T4>(t4);
  31229. s << std::forward<T5>(t5);
  31230. s << std::forward<T6>(t6);
  31231. s << std::forward<T7>(t7);
  31232. s << std::forward<T8>(t8);
  31233. s.check_end_of_row();
  31234. }
  31235. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31236. typename T5, typename T6, typename T7, typename T8, typename T9>
  31237. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31238. T6 &&t6, T7 &&t7, T8 &&t8,
  31239. T9 &&t9) OTL_THROWS_OTL_EXCEPTION {
  31240. s << std::forward<T1>(t1);
  31241. s << std::forward<T2>(t2);
  31242. s << std::forward<T3>(t3);
  31243. s << std::forward<T4>(t4);
  31244. s << std::forward<T5>(t5);
  31245. s << std::forward<T6>(t6);
  31246. s << std::forward<T7>(t7);
  31247. s << std::forward<T8>(t8);
  31248. s << std::forward<T9>(t9);
  31249. s.check_end_of_row();
  31250. }
  31251. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31252. typename T5, typename T6, typename T7, typename T8, typename T9,
  31253. typename T10>
  31254. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31255. T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9,
  31256. T10 &&t10) OTL_THROWS_OTL_EXCEPTION {
  31257. s << std::forward<T1>(t1);
  31258. s << std::forward<T2>(t2);
  31259. s << std::forward<T3>(t3);
  31260. s << std::forward<T4>(t4);
  31261. s << std::forward<T5>(t5);
  31262. s << std::forward<T6>(t6);
  31263. s << std::forward<T7>(t7);
  31264. s << std::forward<T8>(t8);
  31265. s << std::forward<T9>(t9);
  31266. s << std::forward<T10>(t10);
  31267. s.check_end_of_row();
  31268. }
  31269. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31270. typename T5, typename T6, typename T7, typename T8, typename T9,
  31271. typename T10, typename T11>
  31272. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31273. T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10,
  31274. T11 &&t11) OTL_THROWS_OTL_EXCEPTION {
  31275. s << std::forward<T1>(t1);
  31276. s << std::forward<T2>(t2);
  31277. s << std::forward<T3>(t3);
  31278. s << std::forward<T4>(t4);
  31279. s << std::forward<T5>(t5);
  31280. s << std::forward<T6>(t6);
  31281. s << std::forward<T7>(t7);
  31282. s << std::forward<T8>(t8);
  31283. s << std::forward<T9>(t9);
  31284. s << std::forward<T10>(t10);
  31285. s << std::forward<T11>(t11);
  31286. s.check_end_of_row();
  31287. }
  31288. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31289. typename T5, typename T6, typename T7, typename T8, typename T9,
  31290. typename T10, typename T11, typename T12>
  31291. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31292. T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10,
  31293. T11 &&t11, T12 &&t12) OTL_THROWS_OTL_EXCEPTION {
  31294. s << std::forward<T1>(t1);
  31295. s << std::forward<T2>(t2);
  31296. s << std::forward<T3>(t3);
  31297. s << std::forward<T4>(t4);
  31298. s << std::forward<T5>(t5);
  31299. s << std::forward<T6>(t6);
  31300. s << std::forward<T7>(t7);
  31301. s << std::forward<T8>(t8);
  31302. s << std::forward<T9>(t9);
  31303. s << std::forward<T10>(t10);
  31304. s << std::forward<T11>(t11);
  31305. s << std::forward<T12>(t12);
  31306. s.check_end_of_row();
  31307. }
  31308. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31309. typename T5, typename T6, typename T7, typename T8, typename T9,
  31310. typename T10, typename T11, typename T12, typename T13>
  31311. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31312. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31313. T13 &t13) OTL_THROWS_OTL_EXCEPTION {
  31314. s << std::forward<T1>(t1);
  31315. s << std::forward<T2>(t2);
  31316. s << std::forward<T3>(t3);
  31317. s << std::forward<T4>(t4);
  31318. s << std::forward<T5>(t5);
  31319. s << std::forward<T6>(t6);
  31320. s << std::forward<T7>(t7);
  31321. s << std::forward<T8>(t8);
  31322. s << std::forward<T9>(t9);
  31323. s << std::forward<T10>(t10);
  31324. s << std::forward<T11>(t11);
  31325. s << std::forward<T12>(t12);
  31326. s << std::forward<T13>(t13);
  31327. s.check_end_of_row();
  31328. }
  31329. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31330. typename T5, typename T6, typename T7, typename T8, typename T9,
  31331. typename T10, typename T11, typename T12, typename T13, typename T14>
  31332. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31333. T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10,
  31334. T11 &&t11, T12 &&t12, T13 &&t13,
  31335. T14 &&t14) OTL_THROWS_OTL_EXCEPTION {
  31336. s << std::forward<T1>(t1);
  31337. s << std::forward<T2>(t2);
  31338. s << std::forward<T3>(t3);
  31339. s << std::forward<T4>(t4);
  31340. s << std::forward<T5>(t5);
  31341. s << std::forward<T6>(t6);
  31342. s << std::forward<T7>(t7);
  31343. s << std::forward<T8>(t8);
  31344. s << std::forward<T9>(t9);
  31345. s << std::forward<T10>(t10);
  31346. s << std::forward<T11>(t11);
  31347. s << std::forward<T12>(t12);
  31348. s << std::forward<T13>(t13);
  31349. s << std::forward<T14>(t14);
  31350. s.check_end_of_row();
  31351. }
  31352. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31353. typename T5, typename T6, typename T7, typename T8, typename T9,
  31354. typename T10, typename T11, typename T12, typename T13, typename T14,
  31355. typename T15>
  31356. inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5,
  31357. T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10,
  31358. T11 &&t11, T12 &&t12, T13 &&t13, T14 &&t14,
  31359. T15 &&t15) OTL_THROWS_OTL_EXCEPTION {
  31360. s << std::forward<T1>(t1);
  31361. s << std::forward<T2>(t2);
  31362. s << std::forward<T3>(t3);
  31363. s << std::forward<T4>(t4);
  31364. s << std::forward<T5>(t5);
  31365. s << std::forward<T6>(t6);
  31366. s << std::forward<T7>(t7);
  31367. s << std::forward<T8>(t8);
  31368. s << std::forward<T9>(t9);
  31369. s << std::forward<T10>(t10);
  31370. s << std::forward<T11>(t11);
  31371. s << std::forward<T12>(t12);
  31372. s << std::forward<T13>(t13);
  31373. s << std::forward<T14>(t14);
  31374. s << std::forward<T15>(t15);
  31375. s.check_end_of_row();
  31376. }
  31377. #else
  31378. template <typename S, typename T1>
  31379. inline void otl_write_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION {
  31380. s << t1;
  31381. s.check_end_of_row();
  31382. }
  31383. template <typename S, typename T1, typename T2>
  31384. inline void otl_write_row(S &s, T1 &t1, T2 &t2) OTL_THROWS_OTL_EXCEPTION {
  31385. s << t1;
  31386. s << t2;
  31387. s.check_end_of_row();
  31388. }
  31389. template <typename S, typename T1, typename T2, typename T3>
  31390. inline void otl_write_row(S &s, T1 &t1, T2 &t2,
  31391. T3 &t3) OTL_THROWS_OTL_EXCEPTION {
  31392. s << t1;
  31393. s << t2;
  31394. s << t3;
  31395. s.check_end_of_row();
  31396. }
  31397. template <typename S, typename T1, typename T2, typename T3, typename T4>
  31398. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3,
  31399. T4 &t4) OTL_THROWS_OTL_EXCEPTION {
  31400. s << t1;
  31401. s << t2;
  31402. s << t3;
  31403. s << t4;
  31404. s.check_end_of_row();
  31405. }
  31406. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31407. typename T5>
  31408. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4,
  31409. T5 &t5) OTL_THROWS_OTL_EXCEPTION {
  31410. s << t1;
  31411. s << t2;
  31412. s << t3;
  31413. s << t4;
  31414. s << t5;
  31415. s.check_end_of_row();
  31416. }
  31417. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31418. typename T5, typename T6>
  31419. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5,
  31420. T6 &t6) OTL_THROWS_OTL_EXCEPTION {
  31421. s << t1;
  31422. s << t2;
  31423. s << t3;
  31424. s << t4;
  31425. s << t5;
  31426. s << t6;
  31427. s.check_end_of_row();
  31428. }
  31429. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31430. typename T5, typename T6, typename T7>
  31431. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31432. T7 &t7) OTL_THROWS_OTL_EXCEPTION {
  31433. s << t1;
  31434. s << t2;
  31435. s << t3;
  31436. s << t4;
  31437. s << t5;
  31438. s << t6;
  31439. s << t7;
  31440. s.check_end_of_row();
  31441. }
  31442. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31443. typename T5, typename T6, typename T7, typename T8>
  31444. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31445. T7 &t7, T8 &t8) OTL_THROWS_OTL_EXCEPTION {
  31446. s << t1;
  31447. s << t2;
  31448. s << t3;
  31449. s << t4;
  31450. s << t5;
  31451. s << t6;
  31452. s << t7;
  31453. s << t8;
  31454. s.check_end_of_row();
  31455. }
  31456. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31457. typename T5, typename T6, typename T7, typename T8, typename T9>
  31458. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31459. T7 &t7, T8 &t8, T9 &t9) OTL_THROWS_OTL_EXCEPTION {
  31460. s << t1;
  31461. s << t2;
  31462. s << t3;
  31463. s << t4;
  31464. s << t5;
  31465. s << t6;
  31466. s << t7;
  31467. s << t8;
  31468. s << t9;
  31469. s.check_end_of_row();
  31470. }
  31471. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31472. typename T5, typename T6, typename T7, typename T8, typename T9,
  31473. typename T10>
  31474. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31475. T7 &t7, T8 &t8, T9 &t9,
  31476. T10 &t10) OTL_THROWS_OTL_EXCEPTION {
  31477. s << t1;
  31478. s << t2;
  31479. s << t3;
  31480. s << t4;
  31481. s << t5;
  31482. s << t6;
  31483. s << t7;
  31484. s << t8;
  31485. s << t9;
  31486. s << t10;
  31487. s.check_end_of_row();
  31488. }
  31489. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31490. typename T5, typename T6, typename T7, typename T8, typename T9,
  31491. typename T10, typename T11>
  31492. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31493. T7 &t7, T8 &t8, T9 &t9, T10 &t10,
  31494. T11 &t11) OTL_THROWS_OTL_EXCEPTION {
  31495. s << t1;
  31496. s << t2;
  31497. s << t3;
  31498. s << t4;
  31499. s << t5;
  31500. s << t6;
  31501. s << t7;
  31502. s << t8;
  31503. s << t9;
  31504. s << t10;
  31505. s << t11;
  31506. s.check_end_of_row();
  31507. }
  31508. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31509. typename T5, typename T6, typename T7, typename T8, typename T9,
  31510. typename T10, typename T11, typename T12>
  31511. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31512. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11,
  31513. T12 &t12) OTL_THROWS_OTL_EXCEPTION {
  31514. s << t1;
  31515. s << t2;
  31516. s << t3;
  31517. s << t4;
  31518. s << t5;
  31519. s << t6;
  31520. s << t7;
  31521. s << t8;
  31522. s << t9;
  31523. s << t10;
  31524. s << t11;
  31525. s << t12;
  31526. s.check_end_of_row();
  31527. }
  31528. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31529. typename T5, typename T6, typename T7, typename T8, typename T9,
  31530. typename T10, typename T11, typename T12, typename T13>
  31531. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31532. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31533. T13 &t13) OTL_THROWS_OTL_EXCEPTION {
  31534. s << t1;
  31535. s << t2;
  31536. s << t3;
  31537. s << t4;
  31538. s << t5;
  31539. s << t6;
  31540. s << t7;
  31541. s << t8;
  31542. s << t9;
  31543. s << t10;
  31544. s << t11;
  31545. s << t12;
  31546. s << t13;
  31547. s.check_end_of_row();
  31548. }
  31549. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31550. typename T5, typename T6, typename T7, typename T8, typename T9,
  31551. typename T10, typename T11, typename T12, typename T13, typename T14>
  31552. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31553. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31554. T13 &t13, T14 &t14) OTL_THROWS_OTL_EXCEPTION {
  31555. s << t1;
  31556. s << t2;
  31557. s << t3;
  31558. s << t4;
  31559. s << t5;
  31560. s << t6;
  31561. s << t7;
  31562. s << t8;
  31563. s << t9;
  31564. s << t10;
  31565. s << t11;
  31566. s << t12;
  31567. s << t13;
  31568. s << t14;
  31569. s.check_end_of_row();
  31570. }
  31571. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31572. typename T5, typename T6, typename T7, typename T8, typename T9,
  31573. typename T10, typename T11, typename T12, typename T13, typename T14,
  31574. typename T15>
  31575. inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6,
  31576. T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12,
  31577. T13 &t13, T14 &t14,
  31578. T15 &t15) OTL_THROWS_OTL_EXCEPTION {
  31579. s << t1;
  31580. s << t2;
  31581. s << t3;
  31582. s << t4;
  31583. s << t5;
  31584. s << t6;
  31585. s << t7;
  31586. s << t8;
  31587. s << t9;
  31588. s << t10;
  31589. s << t11;
  31590. s << t12;
  31591. s << t13;
  31592. s << t14;
  31593. s << t15;
  31594. s.check_end_of_row();
  31595. }
  31596. template <typename S, typename T1>
  31597. inline void otl_write_row(S &s, const T1 &t1) OTL_THROWS_OTL_EXCEPTION {
  31598. s << t1;
  31599. s.check_end_of_row();
  31600. }
  31601. template <typename S, typename T1, typename T2>
  31602. inline void otl_write_row(S &s, const T1 &t1,
  31603. const T2 &t2) OTL_THROWS_OTL_EXCEPTION {
  31604. s << t1;
  31605. s << t2;
  31606. s.check_end_of_row();
  31607. }
  31608. template <typename S, typename T1, typename T2, typename T3>
  31609. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2,
  31610. const T3 &t3) OTL_THROWS_OTL_EXCEPTION {
  31611. s << t1;
  31612. s << t2;
  31613. s << t3;
  31614. s.check_end_of_row();
  31615. }
  31616. template <typename S, typename T1, typename T2, typename T3, typename T4>
  31617. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31618. const T4 &t4) OTL_THROWS_OTL_EXCEPTION {
  31619. s << t1;
  31620. s << t2;
  31621. s << t3;
  31622. s << t4;
  31623. s.check_end_of_row();
  31624. }
  31625. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31626. typename T5>
  31627. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31628. const T4 &t4, const T5 &t5) OTL_THROWS_OTL_EXCEPTION {
  31629. s << t1;
  31630. s << t2;
  31631. s << t3;
  31632. s << t4;
  31633. s << t5;
  31634. s.check_end_of_row();
  31635. }
  31636. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31637. typename T5, typename T6>
  31638. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31639. const T4 &t4, const T5 &t5,
  31640. const T6 &t6) OTL_THROWS_OTL_EXCEPTION {
  31641. s << t1;
  31642. s << t2;
  31643. s << t3;
  31644. s << t4;
  31645. s << t5;
  31646. s << t6;
  31647. s.check_end_of_row();
  31648. }
  31649. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31650. typename T5, typename T6, typename T7>
  31651. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31652. const T4 &t4, const T5 &t5, const T6 &t6,
  31653. const T7 &t7) OTL_THROWS_OTL_EXCEPTION {
  31654. s << t1;
  31655. s << t2;
  31656. s << t3;
  31657. s << t4;
  31658. s << t5;
  31659. s << t6;
  31660. s << t7;
  31661. s.check_end_of_row();
  31662. }
  31663. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31664. typename T5, typename T6, typename T7, typename T8>
  31665. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31666. const T4 &t4, const T5 &t5, const T6 &t6,
  31667. const T7 &t7, const T8 &t8) OTL_THROWS_OTL_EXCEPTION {
  31668. s << t1;
  31669. s << t2;
  31670. s << t3;
  31671. s << t4;
  31672. s << t5;
  31673. s << t6;
  31674. s << t7;
  31675. s << t8;
  31676. s.check_end_of_row();
  31677. }
  31678. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31679. typename T5, typename T6, typename T7, typename T8, typename T9>
  31680. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31681. const T4 &t4, const T5 &t5, const T6 &t6,
  31682. const T7 &t7, const T8 &t8,
  31683. const T9 &t9) OTL_THROWS_OTL_EXCEPTION {
  31684. s << t1;
  31685. s << t2;
  31686. s << t3;
  31687. s << t4;
  31688. s << t5;
  31689. s << t6;
  31690. s << t7;
  31691. s << t8;
  31692. s << t9;
  31693. s.check_end_of_row();
  31694. }
  31695. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31696. typename T5, typename T6, typename T7, typename T8, typename T9,
  31697. typename T10>
  31698. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31699. const T4 &t4, const T5 &t5, const T6 &t6,
  31700. const T7 &t7, const T8 &t8, const T9 &t9,
  31701. const T10 &t10) OTL_THROWS_OTL_EXCEPTION {
  31702. s << t1;
  31703. s << t2;
  31704. s << t3;
  31705. s << t4;
  31706. s << t5;
  31707. s << t6;
  31708. s << t7;
  31709. s << t8;
  31710. s << t9;
  31711. s << t10;
  31712. s.check_end_of_row();
  31713. }
  31714. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31715. typename T5, typename T6, typename T7, typename T8, typename T9,
  31716. typename T10, typename T11>
  31717. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31718. const T4 &t4, const T5 &t5, const T6 &t6,
  31719. const T7 &t7, const T8 &t8, const T9 &t9,
  31720. const T10 &t10,
  31721. const T11 &t11) OTL_THROWS_OTL_EXCEPTION {
  31722. s << t1;
  31723. s << t2;
  31724. s << t3;
  31725. s << t4;
  31726. s << t5;
  31727. s << t6;
  31728. s << t7;
  31729. s << t8;
  31730. s << t9;
  31731. s << t10;
  31732. s << t11;
  31733. s.check_end_of_row();
  31734. }
  31735. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31736. typename T5, typename T6, typename T7, typename T8, typename T9,
  31737. typename T10, typename T11, typename T12>
  31738. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31739. const T4 &t4, const T5 &t5, const T6 &t6,
  31740. const T7 &t7, const T8 &t8, const T9 &t9,
  31741. const T10 &t10, const T11 &t11,
  31742. const T12 &t12) OTL_THROWS_OTL_EXCEPTION {
  31743. s << t1;
  31744. s << t2;
  31745. s << t3;
  31746. s << t4;
  31747. s << t5;
  31748. s << t6;
  31749. s << t7;
  31750. s << t8;
  31751. s << t9;
  31752. s << t10;
  31753. s << t11;
  31754. s << t12;
  31755. s.check_end_of_row();
  31756. }
  31757. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31758. typename T5, typename T6, typename T7, typename T8, typename T9,
  31759. typename T10, typename T11, typename T12, typename T13>
  31760. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31761. const T4 &t4, const T5 &t5, const T6 &t6,
  31762. const T7 &t7, const T8 &t8, const T9 &t9,
  31763. const T10 &t10, const T11 &t11, const T12 &t12,
  31764. const T13 &t13) OTL_THROWS_OTL_EXCEPTION {
  31765. s << t1;
  31766. s << t2;
  31767. s << t3;
  31768. s << t4;
  31769. s << t5;
  31770. s << t6;
  31771. s << t7;
  31772. s << t8;
  31773. s << t9;
  31774. s << t10;
  31775. s << t11;
  31776. s << t12;
  31777. s << t13;
  31778. s.check_end_of_row();
  31779. }
  31780. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31781. typename T5, typename T6, typename T7, typename T8, typename T9,
  31782. typename T10, typename T11, typename T12, typename T13, typename T14>
  31783. inline void
  31784. otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
  31785. const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8,
  31786. const T9 &t9, const T10 &t10, const T11 &t11, const T12 &t12,
  31787. const T13 &t13, const T14 &t14) OTL_THROWS_OTL_EXCEPTION {
  31788. s << t1;
  31789. s << t2;
  31790. s << t3;
  31791. s << t4;
  31792. s << t5;
  31793. s << t6;
  31794. s << t7;
  31795. s << t8;
  31796. s << t9;
  31797. s << t10;
  31798. s << t11;
  31799. s << t12;
  31800. s << t13;
  31801. s << t14;
  31802. s.check_end_of_row();
  31803. }
  31804. template <typename S, typename T1, typename T2, typename T3, typename T4,
  31805. typename T5, typename T6, typename T7, typename T8, typename T9,
  31806. typename T10, typename T11, typename T12, typename T13, typename T14,
  31807. typename T15>
  31808. inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3,
  31809. const T4 &t4, const T5 &t5, const T6 &t6,
  31810. const T7 &t7, const T8 &t8, const T9 &t9,
  31811. const T10 &t10, const T11 &t11, const T12 &t12,
  31812. const T13 &t13, const T14 &t14,
  31813. const T15 &t15) OTL_THROWS_OTL_EXCEPTION {
  31814. s << t1;
  31815. s << t2;
  31816. s << t3;
  31817. s << t4;
  31818. s << t5;
  31819. s << t6;
  31820. s << t7;
  31821. s << t8;
  31822. s << t9;
  31823. s << t10;
  31824. s << t11;
  31825. s << t12;
  31826. s << t13;
  31827. s << t14;
  31828. s << t15;
  31829. s.check_end_of_row();
  31830. }
  31831. #endif
  31832. #endif
  31833. #if (defined(OTL_CPP_11_ON) || defined(_MSC_VER) && (_MSC_VER >= 1700)) && \
  31834. defined(OTL_CONNECT_POOL_ON)
  31835. #include <mutex>
  31836. #include <memory>
  31837. #include <vector>
  31838. #if defined(OTL_CLANG_THREAD_SAFETY_ON)
  31839. #define OTL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x))
  31840. #else
  31841. #define OTL_THREAD_ANNOTATION_ATTRIBUTE(x)
  31842. #endif
  31843. #define OTL_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(capability(x))
  31844. #define OTL_SCOPED_CAPABILITY OTL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable)
  31845. #define OTL_GUARDED_BY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x))
  31846. #define OTL_PT_GUARDED_BY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x))
  31847. #define OTL_ACQUIRED_BEFORE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__))
  31848. #define OTL_ACQUIRED_AFTER(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__))
  31849. #define OTL_REQUIRES(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(requires_capability(__VA_ARGS__))
  31850. #define OTL_REQUIRES_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(requires_shared_capability(__VA_ARGS__))
  31851. #define OTL_ACQUIRE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquire_capability(__VA_ARGS__))
  31852. #define OTL_ACQUIRE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquire_shared_capability(__VA_ARGS__))
  31853. #define OTL_RELEASE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(release_capability(__VA_ARGS__))
  31854. #define OTL_RELEASE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(release_shared_capability(__VA_ARGS__))
  31855. #define OTL_TRY_ACQUIRE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_capability(__VA_ARGS__))
  31856. #define OTL_TRY_ACQUIRE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_shared_capability(__VA_ARGS__))
  31857. #define OTL_EXCLUDES(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__))
  31858. #define OTL_ASSERT_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(assert_capability(x))
  31859. #define OTL_ASSERT_SHARED_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_capability(x))
  31860. #define OTL_RETURN_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x))
  31861. #define OTL_NO_THREAD_SAFETY_ANALYSIS OTL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis)
  31862. class OTL_CAPABILITY("mutex") otl_recursive_mutex{
  31863. private:
  31864. std::recursive_mutex mutex_;
  31865. public:
  31866. otl_recursive_mutex(): mutex_(){}
  31867. ~otl_recursive_mutex(){}
  31868. void lock() OTL_ACQUIRE(){mutex_.lock();}
  31869. void unlock() OTL_RELEASE(){mutex_.unlock();}
  31870. std::recursive_mutex& get_mutex(){return mutex_;}
  31871. const otl_recursive_mutex& operator!() const {return *this;}
  31872. };
  31873. class OTL_SCOPED_CAPABILITY otl_recursive_mutex_guard {
  31874. public:
  31875. otl_recursive_mutex_guard(otl_recursive_mutex* mut) OTL_ACQUIRE(mut) : mutex_ptr_(mut)
  31876. {
  31877. mutex_ptr_->lock();
  31878. }
  31879. ~otl_recursive_mutex_guard() OTL_RELEASE()
  31880. {
  31881. mutex_ptr_->unlock();
  31882. }
  31883. otl_recursive_mutex_guard(const otl_recursive_mutex_guard& src) : mutex_ptr_(src.mutex_ptr_){}
  31884. otl_recursive_mutex_guard(otl_recursive_mutex_guard&& src) : mutex_ptr_(src.mutex_ptr_){}
  31885. otl_recursive_mutex_guard& operator=(const otl_recursive_mutex_guard& src)
  31886. {
  31887. mutex_ptr_=src.mutex_ptr_;
  31888. return *this;
  31889. }
  31890. otl_recursive_mutex_guard& operator=(otl_recursive_mutex_guard&& src)
  31891. {
  31892. mutex_ptr_=src.mutex_ptr_;
  31893. return *this;
  31894. }
  31895. private:
  31896. otl_recursive_mutex* mutex_ptr_;
  31897. };
  31898. template<class OTLConnect, class OTLException>
  31899. class otl_connect_pool{
  31900. public:
  31901. typedef std::unique_ptr<OTLConnect> connect_ptr;
  31902. // Default constructor
  31903. otl_connect_pool() OTL_NO_THROW
  31904. : pool_open_(false), min_pool_size_(0), max_pool_size_(0),
  31905. connects_in_use_(0), auto_commit_(false), connect_str_(nullptr),
  31906. grow_pool_in_increments_(1), pool_(), mutex_(){
  31907. }
  31908. // Prepopulate the pool to the specified minimum size.
  31909. otl_connect_pool
  31910. (const char* connect_str,
  31911. const bool auto_commit=false,
  31912. const size_t new_min_pool_size=8,
  31913. const size_t new_max_pool_size=32,
  31914. const size_t grow_pool_in_increments=1)
  31915. OTL_THROWS_OTL_EXCEPTION : otl_connect_pool(){
  31916. open(connect_str,
  31917. auto_commit,
  31918. new_min_pool_size,
  31919. new_max_pool_size,
  31920. grow_pool_in_increments);
  31921. }
  31922. // Open the pool and prepopulate it to the specified minimum
  31923. // size. If the pool was already opened, close it first
  31924. void open(const char* connect_str,
  31925. const bool auto_commit=false,
  31926. const size_t new_min_pool_size=8,
  31927. const size_t new_max_pool_size=32,
  31928. const size_t grow_pool_in_increments=1)
  31929. OTL_THROWS_OTL_EXCEPTION{
  31930. otl_recursive_mutex_guard guard(&mutex_);
  31931. if(pool_open_)close(true);
  31932. pool_open_=true;
  31933. connects_in_use_=0;
  31934. min_pool_size_=new_min_pool_size;
  31935. max_pool_size_=new_max_pool_size;
  31936. grow_pool_in_increments_=grow_pool_in_increments;
  31937. pool_.clear();
  31938. size_t connect_str_len=strlen(connect_str);
  31939. connect_str_=new char[connect_str_len+1];
  31940. OTL_STRCPY_S(connect_str_,connect_str_len+1,connect_str);
  31941. auto_commit_=auto_commit;
  31942. for(size_t i=0;i<min_pool_size_;++i){
  31943. #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  31944. pool_.push_back(std::make_unique<OTLConnect>());
  31945. #else
  31946. pool_.push_back(connect_ptr(new OTLConnect()));
  31947. #endif
  31948. pool_.back()->rlogon(connect_str,auto_commit);
  31949. }
  31950. }
  31951. // Get a connect object from the pool. The ownership of the
  31952. // connect object is transferred / moved to the caller. If the
  31953. // pool is empty / already at its maximum size or closed, return
  31954. // an empty unique pointer.
  31955. connect_ptr get(const bool ignore_errors=true) OTL_THROWS_OTL_EXCEPTION{
  31956. connect_ptr ptr;
  31957. otl_recursive_mutex_guard guard(&mutex_);
  31958. if(pool_open_ && pool_.size()==0){
  31959. // populate connects in the pool to the maximum size
  31960. exception_ptr ret_exc;
  31961. size_t iters=grow_pool_in_increments_;
  31962. size_t total_allowed_connects=max_pool_size_-connects_in_use_;
  31963. if(iters>total_allowed_connects)
  31964. iters=total_allowed_connects;
  31965. for(size_t i=0;
  31966. i<iters;
  31967. ++i){
  31968. #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  31969. pool_.push_back(std::make_unique<OTLConnect>());
  31970. #else
  31971. pool_.push_back(connect_ptr(new OTLConnect()));
  31972. #endif
  31973. try{
  31974. pool_.back()->rlogon(connect_str_,auto_commit_);
  31975. }catch(const OTLException& ex){
  31976. // save the first error and throw it as an exception at
  31977. // the end of the function if ignore_errors is set to
  31978. // false
  31979. if(!ret_exc)
  31980. #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  31981. ret_exc=std::make_unique<OTLException>(ex);
  31982. #else
  31983. ret_exc.reset(new OTLException(ex));
  31984. #endif
  31985. }
  31986. }
  31987. if(!ignore_errors && ret_exc)
  31988. OTL_THROW(*ret_exc);
  31989. }
  31990. if(pool_open_ && pool_.size()>0){
  31991. // if the pool is not empty, return an element from the
  31992. // the end of the pool.
  31993. ptr=std::move(pool_.back());
  31994. pool_.pop_back();
  31995. ++connects_in_use_;
  31996. }
  31997. return ptr;
  31998. }
  31999. // Put a connect object into the pool. The ownership of the object
  32000. // is transferred / moved from the caller to the pool. Return
  32001. // false if the pool is full or closed.
  32002. bool put(connect_ptr&& p) OTL_NO_THROW{
  32003. otl_recursive_mutex_guard guard(&mutex_);
  32004. if(!pool_open_)return false;
  32005. if(pool_.size()<max_pool_size_){
  32006. // if the pool is not filled up to its maximum size, add the
  32007. // object to the pool.
  32008. pool_.push_back(std::move(p));
  32009. --connects_in_use_;
  32010. return true;
  32011. }else
  32012. // pool is full, return false
  32013. return false;
  32014. }
  32015. // Shrink the pool to the new min_pool_size. This function can be
  32016. // called from a timer to reduce the number of idle database
  32017. // connections.
  32018. void shrink_pool(const size_t new_min_pool_size,
  32019. const bool ignore_errors=false) OTL_THROWS_OTL_EXCEPTION{
  32020. otl_recursive_mutex_guard guard(&mutex_);
  32021. if(!pool_open_)return;
  32022. if(pool_.size()<new_min_pool_size)
  32023. // if the pool size is already smaller than the specified
  32024. // minimum size, there is nothing to do, returning...
  32025. return;
  32026. exception_ptr ret_exc;
  32027. while(pool_.size()>new_min_pool_size && pool_.size()>0){
  32028. auto& last_element=pool_.back();
  32029. if(last_element){
  32030. try{
  32031. last_element->logoff();
  32032. }catch(const OTLException& ex){
  32033. // save the first error and throw it as an exception at
  32034. // the end of the function if ignore_errors is set to
  32035. // false
  32036. if(!ret_exc)
  32037. #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  32038. ret_exc=std::make_unique<OTLException>(ex);
  32039. #else
  32040. ret_exc.reset(new OTLException(ex));
  32041. #endif
  32042. }
  32043. last_element.reset(nullptr);
  32044. }
  32045. pool_.pop_back();
  32046. }
  32047. min_pool_size_=new_min_pool_size;
  32048. if(!ignore_errors && ret_exc)
  32049. OTL_THROW(*ret_exc);
  32050. }
  32051. // change max pool size
  32052. void change_max_pool_size(const size_t new_max_pool_size) OTL_THROWS_OTL_EXCEPTION {
  32053. otl_recursive_mutex_guard guard(&mutex_);
  32054. if(max_pool_size_<new_max_pool_size){
  32055. max_pool_size_=new_max_pool_size;
  32056. }else if(max_pool_size_>new_max_pool_size){
  32057. // if new_max_pool_size is smaller than the current pool size,
  32058. // then shrink the pool to the new max size.
  32059. if(pool_.size()>new_max_pool_size)
  32060. shrink_pool(new_max_pool_size);
  32061. max_pool_size_=new_max_pool_size;
  32062. }
  32063. }
  32064. // Close the pool
  32065. void close(const bool ignore_errors=false) OTL_THROWS_OTL_EXCEPTION{
  32066. otl_recursive_mutex_guard guard(&mutex_);
  32067. if(!pool_open_)return;
  32068. exception_ptr ret_exc;
  32069. for(auto& i:pool_){
  32070. if(i){
  32071. try{
  32072. i->logoff();
  32073. }catch(const OTLException& ex){
  32074. if(!ret_exc)
  32075. #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
  32076. ret_exc=std::make_unique<OTLException>(ex);
  32077. #else
  32078. ret_exc.reset(new OTLException(ex));
  32079. #endif
  32080. }
  32081. }
  32082. i.reset(nullptr);
  32083. }
  32084. pool_.clear();
  32085. pool_open_=false;
  32086. min_pool_size_=0;
  32087. max_pool_size_=0;
  32088. delete[] connect_str_;
  32089. connect_str_=nullptr;
  32090. if(!ignore_errors && ret_exc)
  32091. OTL_THROW(*ret_exc);
  32092. }
  32093. // Destructor. Disconnect all idle database connections first, and
  32094. // then destroy the pool.
  32095. ~otl_connect_pool() OTL_NO_THROW{
  32096. close(true);
  32097. }
  32098. // Get the maximum pool size
  32099. size_t max_pool_size() const OTL_NO_THROW{
  32100. otl_recursive_mutex_guard guard(&mutex_);
  32101. return max_pool_size_;
  32102. }
  32103. // Get the minimum pool size
  32104. size_t min_pool_size() const OTL_NO_THROW{
  32105. otl_recursive_mutex_guard guard(&mutex_);
  32106. return min_pool_size_;
  32107. }
  32108. // Get the current / dynamic pool size
  32109. size_t current_pool_size() const OTL_NO_THROW{
  32110. otl_recursive_mutex_guard guard(&mutex_);
  32111. return pool_.size();
  32112. }
  32113. // Return "pool is open" flag
  32114. bool is_open() const OTL_NO_THROW{
  32115. otl_recursive_mutex_guard guard(&mutex_);
  32116. return pool_open_;
  32117. }
  32118. // Get the underlying mutex when a sequence of more than one call
  32119. // needs to be done under a single mutex lock for consistency.
  32120. std::recursive_mutex& get_mutex() OTL_NO_THROW{
  32121. return mutex_.get_mutex();
  32122. }
  32123. private:
  32124. typedef std::unique_ptr<OTLException> exception_ptr;
  32125. bool pool_open_ OTL_GUARDED_BY(mutex_);
  32126. size_t min_pool_size_ OTL_GUARDED_BY(mutex_);
  32127. size_t max_pool_size_ OTL_GUARDED_BY(mutex_);
  32128. size_t connects_in_use_ OTL_GUARDED_BY(mutex_);
  32129. bool auto_commit_ OTL_GUARDED_BY(mutex_);
  32130. char* connect_str_ OTL_GUARDED_BY(mutex_);
  32131. size_t grow_pool_in_increments_ OTL_GUARDED_BY(mutex_);
  32132. std::vector<connect_ptr> pool_ OTL_GUARDED_BY(mutex_);
  32133. mutable otl_recursive_mutex mutex_;
  32134. };
  32135. #endif
  32136. #if defined(OTL_ORA_TEXT_ON) && defined(text)
  32137. #undef text
  32138. #endif
  32139. #endif