sqldb.pp 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000
  1. {
  2. Copyright (c) 2004 by Joost van der Sluis
  3. SQL database & dataset
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit sqldb;
  11. {$mode objfpc}
  12. {$H+}
  13. {$M+} // ### remove this!!!
  14. interface
  15. uses SysUtils, Classes, DB, bufdataset, sqlscript;
  16. type TSchemaType = (stNoSchema, stTables, stSysTables, stProcedures, stColumns, stProcedureParams, stIndexes, stPackages);
  17. TConnOption = (sqSupportParams,sqEscapeSlash,sqEscapeRepeat,sqQuoteFieldnames);
  18. TConnOptions= set of TConnOption;
  19. TRowsCount = LargeInt;
  20. type
  21. TSQLConnection = class;
  22. TSQLTransaction = class;
  23. TCustomSQLQuery = class;
  24. TSQLQuery = class;
  25. TSQLScript = class;
  26. TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete,
  27. stDDL, stGetSegment, stPutSegment, stExecProcedure,
  28. stStartTrans, stCommit, stRollback, stSelectForUpd);
  29. TSQLHandle = Class(TObject)
  30. end;
  31. { TSQLCursor }
  32. TSQLCursor = Class(TSQLHandle)
  33. public
  34. FPrepared : Boolean;
  35. FInitFieldDef : Boolean;
  36. FStatementType : TStatementType;
  37. end;
  38. const
  39. StatementTokens : Array[TStatementType] of string = ('(none)', 'select',
  40. 'insert', 'update', 'delete',
  41. 'create', 'get', 'put', 'execute',
  42. 'start','commit','rollback', '?'
  43. );
  44. type
  45. { TServerIndexDefs }
  46. TServerIndexDefs = class(TIndexDefs)
  47. Private
  48. public
  49. constructor Create(ADataSet: TDataSet); override;
  50. procedure Update; override;
  51. end;
  52. { TSQLConnection }
  53. type
  54. { TSQLConnection }
  55. TSQLConnection = class (TDatabase)
  56. private
  57. FPassword : string;
  58. FTransaction : TSQLTransaction;
  59. FUserName : string;
  60. FHostName : string;
  61. FCharSet : string;
  62. FRole : String;
  63. function GetPort: cardinal;
  64. procedure Setport(const AValue: cardinal);
  65. protected
  66. FConnOptions : TConnOptions;
  67. procedure GetDBInfo(const SchemaType : TSchemaType; const SchemaObjectName, ReturnField : string; List: TStrings);
  68. procedure SetTransaction(Value : TSQLTransaction);virtual;
  69. function StrToStatementType(s : string) : TStatementType; virtual;
  70. procedure DoInternalConnect; override;
  71. procedure DoInternalDisconnect; override;
  72. function GetAsSQLText(Field : TField) : string; overload; virtual;
  73. function GetAsSQLText(Param : TParam) : string; overload; virtual;
  74. function GetHandle : pointer; virtual; virtual;
  75. Function AllocateCursorHandle : TSQLCursor; virtual; abstract;
  76. Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); virtual; abstract;
  77. Function AllocateTransactionHandle : TSQLHandle; virtual; abstract;
  78. procedure PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLTransaction;buf : string; AParams : TParams); virtual; abstract;
  79. procedure Execute(cursor: TSQLCursor;atransaction:tSQLtransaction; AParams : TParams); virtual; abstract;
  80. function Fetch(cursor : TSQLCursor) : boolean; virtual; abstract;
  81. procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); virtual; abstract;
  82. procedure UnPrepareStatement(cursor : TSQLCursor); virtual; abstract;
  83. procedure FreeFldBuffers(cursor : TSQLCursor); virtual;
  84. function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; abstract;
  85. function GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract;
  86. function Commit(trans : TSQLHandle) : boolean; virtual; abstract;
  87. function RollBack(trans : TSQLHandle) : boolean; virtual; abstract;
  88. function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; virtual; abstract;
  89. procedure CommitRetaining(trans : TSQLHandle); virtual; abstract;
  90. procedure RollBackRetaining(trans : TSQLHandle); virtual; abstract;
  91. procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); virtual;
  92. function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; virtual;
  93. procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
  94. function RowsAffected(cursor: TSQLCursor): TRowsCount; virtual;
  95. property port: cardinal read GetPort write Setport;
  96. public
  97. property Handle: Pointer read GetHandle;
  98. destructor Destroy; override;
  99. procedure StartTransaction; override;
  100. procedure EndTransaction; override;
  101. property ConnOptions: TConnOptions read FConnOptions;
  102. procedure ExecuteDirect(SQL : String); overload; virtual;
  103. procedure ExecuteDirect(SQL : String; ATransaction : TSQLTransaction); overload; virtual;
  104. procedure GetTableNames(List : TStrings; SystemTables : Boolean = false); virtual;
  105. procedure GetProcedureNames(List : TStrings); virtual;
  106. procedure GetFieldNames(const TableName : string; List : TStrings); virtual;
  107. procedure CreateDB; virtual;
  108. procedure DropDB; virtual;
  109. published
  110. property Password : string read FPassword write FPassword;
  111. property Transaction : TSQLTransaction read FTransaction write SetTransaction;
  112. property UserName : string read FUserName write FUserName;
  113. property CharSet : string read FCharSet write FCharSet;
  114. property HostName : string Read FHostName Write FHostName;
  115. property Connected;
  116. Property Role : String read FRole write FRole;
  117. property DatabaseName;
  118. property KeepConnection;
  119. property LoginPrompt;
  120. property Params;
  121. property OnLogin;
  122. end;
  123. { TSQLTransaction }
  124. TCommitRollbackAction = (caNone, caCommit, caCommitRetaining, caRollback,
  125. caRollbackRetaining);
  126. TSQLTransaction = class (TDBTransaction)
  127. private
  128. FTrans : TSQLHandle;
  129. FAction : TCommitRollbackAction;
  130. FParams : TStringList;
  131. protected
  132. function GetHandle : Pointer; virtual;
  133. Procedure SetDatabase (Value : TDatabase); override;
  134. public
  135. procedure Commit; virtual;
  136. procedure CommitRetaining; virtual;
  137. procedure Rollback; virtual;
  138. procedure RollbackRetaining; virtual;
  139. procedure StartTransaction; override;
  140. constructor Create(AOwner : TComponent); override;
  141. destructor Destroy; override;
  142. property Handle: Pointer read GetHandle;
  143. procedure EndTransaction; override;
  144. published
  145. property Action : TCommitRollbackAction read FAction write FAction;
  146. property Database;
  147. property Params : TStringList read FParams write FParams;
  148. end;
  149. { TCustomSQLQuery }
  150. TCustomSQLQuery = class (Tbufdataset)
  151. private
  152. FCursor : TSQLCursor;
  153. FUpdateable : boolean;
  154. FTableName : string;
  155. FSQL : TStringList;
  156. FUpdateSQL,
  157. FInsertSQL,
  158. FDeleteSQL : TStringList;
  159. FIsEOF : boolean;
  160. FLoadingFieldDefs : boolean;
  161. FReadOnly : boolean;
  162. FUpdateMode : TUpdateMode;
  163. FParams : TParams;
  164. FusePrimaryKeyAsKey : Boolean;
  165. FSQLBuf : String;
  166. FWhereStartPos : integer;
  167. FWhereStopPos : integer;
  168. FParseSQL : boolean;
  169. FMasterLink : TMasterParamsDatalink;
  170. // FSchemaInfo : TSchemaInfo;
  171. FServerFilterText : string;
  172. FServerFiltered : Boolean;
  173. FServerIndexDefs : TServerIndexDefs;
  174. FUpdateQry,
  175. FDeleteQry,
  176. FInsertQry : TCustomSQLQuery;
  177. FOpenDidPrepare : Boolean;
  178. procedure FreeFldBuffers;
  179. function GetServerIndexDefs: TServerIndexDefs;
  180. function GetStatementType : TStatementType;
  181. procedure SetReadOnly(AValue : Boolean);
  182. procedure SetParseSQL(AValue : Boolean);
  183. procedure SetUsePrimaryKeyAsKey(AValue : Boolean);
  184. procedure SetUpdateMode(AValue : TUpdateMode);
  185. procedure OnChangeSQL(Sender : TObject);
  186. procedure OnChangeModifySQL(Sender : TObject);
  187. procedure Execute;
  188. Procedure SQLParser(var ASQL : string);
  189. procedure ApplyFilter;
  190. Function AddFilter(SQLstr : string) : string;
  191. protected
  192. // abstract & virtual methods of TBufDataset
  193. function Fetch : boolean; override;
  194. function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
  195. // abstract & virtual methods of TDataset
  196. procedure UpdateServerIndexDefs; virtual;
  197. procedure SetDatabase(Value : TDatabase); override;
  198. Procedure SetTransaction(Value : TDBTransaction); override;
  199. procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override;
  200. procedure InternalClose; override;
  201. procedure InternalInitFieldDefs; override;
  202. procedure InternalOpen; override;
  203. function GetCanModify: Boolean; override;
  204. procedure ApplyRecUpdate(UpdateKind : TUpdateKind); override;
  205. Function IsPrepared : Boolean; virtual;
  206. Procedure SetActive (Value : Boolean); override;
  207. procedure SetServerFiltered(Value: Boolean); virtual;
  208. procedure SetServerFilterText(const Value: string); virtual;
  209. Function GetDataSource : TDatasource; override;
  210. Procedure SetDataSource(AValue : TDatasource);
  211. procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); override;
  212. public
  213. procedure Prepare; virtual;
  214. procedure UnPrepare; virtual;
  215. procedure ExecSQL; virtual;
  216. constructor Create(AOwner : TComponent); override;
  217. destructor Destroy; override;
  218. procedure SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string); virtual;
  219. property Prepared : boolean read IsPrepared;
  220. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  221. function RowsAffected: TRowsCount; virtual;
  222. protected
  223. // redeclared data set properties
  224. property Active;
  225. property Filter;
  226. property Filtered;
  227. // property FilterOptions;
  228. property BeforeOpen;
  229. property AfterOpen;
  230. property BeforeClose;
  231. property AfterClose;
  232. property BeforeInsert;
  233. property AfterInsert;
  234. property BeforeEdit;
  235. property AfterEdit;
  236. property BeforePost;
  237. property AfterPost;
  238. property BeforeCancel;
  239. property AfterCancel;
  240. property BeforeDelete;
  241. property AfterDelete;
  242. property BeforeScroll;
  243. property AfterScroll;
  244. property OnCalcFields;
  245. property OnDeleteError;
  246. property OnEditError;
  247. property OnFilterRecord;
  248. property OnNewRecord;
  249. property OnPostError;
  250. property AutoCalcFields;
  251. property Database;
  252. // protected
  253. // property SchemaInfo : TSchemaInfo read FSchemaInfo default stNoSchema;
  254. property Transaction;
  255. property ReadOnly : Boolean read FReadOnly write SetReadOnly;
  256. property SQL : TStringlist read FSQL write FSQL;
  257. property UpdateSQL : TStringlist read FUpdateSQL;
  258. property InsertSQL : TStringlist read FInsertSQL;
  259. property DeleteSQL : TStringlist read FDeleteSQL;
  260. property Params : TParams read FParams write FParams;
  261. property UpdateMode : TUpdateMode read FUpdateMode write SetUpdateMode;
  262. property UsePrimaryKeyAsKey : boolean read FUsePrimaryKeyAsKey write SetUsePrimaryKeyAsKey default true;
  263. property StatementType : TStatementType read GetStatementType;
  264. property ParseSQL : Boolean read FParseSQL write SetParseSQL default true;
  265. Property DataSource : TDatasource Read GetDataSource Write SetDatasource;
  266. property ServerFilter: string read FServerFilterText write SetServerFilterText;
  267. property ServerFiltered: Boolean read FServerFiltered write SetServerFiltered default False;
  268. property ServerIndexDefs : TServerIndexDefs read GetServerIndexDefs;
  269. end;
  270. { TSQLQuery }
  271. TSQLQuery = Class(TCustomSQLQuery)
  272. Published
  273. // TDataset stuff
  274. Property Active;
  275. Property AutoCalcFields;
  276. Property Filter;
  277. Property Filtered;
  278. Property AfterCancel;
  279. Property AfterClose;
  280. Property AfterDelete;
  281. Property AfterEdit;
  282. Property AfterInsert;
  283. Property AfterOpen;
  284. Property AfterPost;
  285. Property AfterScroll;
  286. Property BeforeCancel;
  287. Property BeforeClose;
  288. Property BeforeDelete;
  289. Property BeforeEdit;
  290. Property BeforeInsert;
  291. Property BeforeOpen;
  292. Property BeforePost;
  293. Property BeforeScroll;
  294. Property OnCalcFields;
  295. Property OnDeleteError;
  296. Property OnEditError;
  297. Property OnFilterRecord;
  298. Property OnNewRecord;
  299. Property OnPostError;
  300. // property SchemaInfo default stNoSchema;
  301. property Database;
  302. property Transaction;
  303. property ReadOnly;
  304. property SQL;
  305. property UpdateSQL;
  306. property InsertSQL;
  307. property DeleteSQL;
  308. property IndexDefs;
  309. property Params;
  310. property UpdateMode;
  311. property UsePrimaryKeyAsKey;
  312. property ParseSQL;
  313. Property DataSource;
  314. property ServerFilter;
  315. property ServerFiltered;
  316. property ServerIndexDefs;
  317. end;
  318. { TSQLScript }
  319. TSQLScript = class (TCustomSQLscript)
  320. private
  321. FOnDirective: TSQLScriptDirectiveEvent;
  322. FQuery : TCustomSQLQuery;
  323. FDatabase : TDatabase;
  324. FTransaction : TDBTransaction;
  325. protected
  326. procedure ExecuteStatement (SQLStatement: TStrings; var StopExecution: Boolean); override;
  327. procedure ExecuteDirective (Directive, Argument: String; var StopExecution: Boolean); override;
  328. procedure ExecuteCommit; override;
  329. Procedure SetDatabase (Value : TDatabase); virtual;
  330. Procedure SetTransaction(Value : TDBTransaction); virtual;
  331. Procedure CheckDatabase;
  332. public
  333. constructor Create(AOwner : TComponent); override;
  334. destructor Destroy; override;
  335. procedure Execute; override;
  336. procedure ExecuteScript;
  337. published
  338. Property DataBase : TDatabase Read FDatabase Write SetDatabase;
  339. Property Transaction : TDBTransaction Read FTransaction Write SetTransaction;
  340. property OnDirective: TSQLScriptDirectiveEvent read FOnDirective write FOnDirective;
  341. property Directives;
  342. property Defines;
  343. property Script;
  344. property Terminator;
  345. property CommentsinSQL;
  346. property UseSetTerm;
  347. property UseCommit;
  348. property UseDefines;
  349. property OnException;
  350. end;
  351. { TSQLConnector }
  352. TSQLConnector = Class(TSQLConnection)
  353. private
  354. FProxy : TSQLConnection;
  355. FConnectorType: String;
  356. procedure SetConnectorType(const AValue: String);
  357. protected
  358. procedure SetTransaction(Value : TSQLTransaction);override;
  359. procedure DoInternalConnect; override;
  360. procedure DoInternalDisconnect; override;
  361. Procedure CheckProxy;
  362. Procedure CreateProxy; virtual;
  363. Procedure FreeProxy; virtual;
  364. function StrToStatementType(s : string) : TStatementType; override;
  365. function GetAsSQLText(Field : TField) : string; overload; override;
  366. function GetAsSQLText(Param : TParam) : string; overload; override;
  367. function GetHandle : pointer; override;
  368. Function AllocateCursorHandle : TSQLCursor; override;
  369. Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override;
  370. Function AllocateTransactionHandle : TSQLHandle; override;
  371. procedure PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLTransaction;buf : string; AParams : TParams); override;
  372. procedure Execute(cursor: TSQLCursor;atransaction:tSQLtransaction; AParams : TParams); override;
  373. function Fetch(cursor : TSQLCursor) : boolean; override;
  374. procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); override;
  375. procedure UnPrepareStatement(cursor : TSQLCursor); override;
  376. procedure FreeFldBuffers(cursor : TSQLCursor); override;
  377. function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
  378. function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
  379. function GetTransactionHandle(trans : TSQLHandle): pointer; override;
  380. function Commit(trans : TSQLHandle) : boolean; override;
  381. function RollBack(trans : TSQLHandle) : boolean; override;
  382. function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; override;
  383. procedure CommitRetaining(trans : TSQLHandle); override;
  384. procedure RollBackRetaining(trans : TSQLHandle); override;
  385. procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
  386. function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
  387. procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
  388. Property Proxy : TSQLConnection Read FProxy;
  389. Published
  390. Property ConnectorType : String Read FConnectorType Write SetConnectorType;
  391. end;
  392. TSQLConnectionClass = Class of TSQLConnection;
  393. { TConnectionDef }
  394. TConnectionDef = Class(TPersistent)
  395. Class Function TypeName : String; virtual;
  396. Class Function ConnectionClass : TSQLConnectionClass; virtual;
  397. Class Function Description : String; virtual;
  398. Procedure ApplyParams(Params : TStrings; AConnection : TSQLConnection); virtual;
  399. end;
  400. TConnectionDefClass = class of TConnectionDef;
  401. Procedure RegisterConnection(Def : TConnectionDefClass);
  402. Procedure UnRegisterConnection(Def : TConnectionDefClass);
  403. Procedure UnRegisterConnection(ConnectionName : String);
  404. Function GetConnectionDef(ConnectorName : String) : TConnectionDef;
  405. Procedure GetConnectionList(List : TSTrings);
  406. implementation
  407. uses dbconst, strutils;
  408. { TSQLConnection }
  409. function TSQLConnection.StrToStatementType(s : string) : TStatementType;
  410. var T : TStatementType;
  411. begin
  412. S:=Lowercase(s);
  413. For t:=stselect to strollback do
  414. if (S=StatementTokens[t]) then
  415. Exit(t);
  416. end;
  417. procedure TSQLConnection.SetTransaction(Value : TSQLTransaction);
  418. begin
  419. if FTransaction<>value then
  420. begin
  421. if Assigned(FTransaction) and FTransaction.Active then
  422. DatabaseError(SErrAssTransaction);
  423. if Assigned(Value) then
  424. Value.Database := Self;
  425. FTransaction := Value;
  426. If Assigned(FTransaction) and (FTransaction.Database=Nil) then
  427. FTransaction.Database:=Self;
  428. end;
  429. end;
  430. procedure TSQLConnection.UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string);
  431. begin
  432. // Empty abstract
  433. end;
  434. procedure TSQLConnection.DoInternalConnect;
  435. begin
  436. if (DatabaseName = '') then
  437. DatabaseError(SErrNoDatabaseName,self);
  438. end;
  439. procedure TSQLConnection.DoInternalDisconnect;
  440. begin
  441. end;
  442. destructor TSQLConnection.Destroy;
  443. begin
  444. inherited Destroy;
  445. end;
  446. procedure TSQLConnection.StartTransaction;
  447. begin
  448. if not assigned(Transaction) then
  449. DatabaseError(SErrConnTransactionnSet)
  450. else
  451. Transaction.StartTransaction;
  452. end;
  453. procedure TSQLConnection.EndTransaction;
  454. begin
  455. if not assigned(Transaction) then
  456. DatabaseError(SErrConnTransactionnSet)
  457. else
  458. Transaction.EndTransaction;
  459. end;
  460. Procedure TSQLConnection.ExecuteDirect(SQL: String);
  461. begin
  462. ExecuteDirect(SQL,FTransaction);
  463. end;
  464. Procedure TSQLConnection.ExecuteDirect(SQL: String; ATransaction : TSQLTransaction);
  465. var Cursor : TSQLCursor;
  466. begin
  467. if not assigned(ATransaction) then
  468. DatabaseError(SErrTransactionnSet);
  469. if not Connected then Open;
  470. if not ATransaction.Active then ATransaction.StartTransaction;
  471. try
  472. Cursor := AllocateCursorHandle;
  473. SQL := TrimRight(SQL);
  474. if SQL = '' then
  475. DatabaseError(SErrNoStatement);
  476. Cursor.FStatementType := stNone;
  477. PrepareStatement(cursor,ATransaction,SQL,Nil);
  478. execute(cursor,ATransaction, Nil);
  479. UnPrepareStatement(Cursor);
  480. finally;
  481. DeAllocateCursorHandle(Cursor);
  482. end;
  483. end;
  484. function TSQLConnection.GetPort: cardinal;
  485. begin
  486. result := StrToIntDef(Params.Values['Port'],0);
  487. end;
  488. procedure TSQLConnection.Setport(const AValue: cardinal);
  489. begin
  490. if AValue<>0 then
  491. params.Values['Port']:=IntToStr(AValue)
  492. else with params do if IndexOfName('Port') > -1 then
  493. Delete(IndexOfName('Port'));
  494. end;
  495. procedure TSQLConnection.GetDBInfo(const SchemaType : TSchemaType; const SchemaObjectName, ReturnField : string; List: TStrings);
  496. var qry : TCustomSQLQuery;
  497. begin
  498. if not assigned(Transaction) then
  499. DatabaseError(SErrConnTransactionnSet);
  500. qry := TCustomSQLQuery.Create(nil);
  501. qry.transaction := Transaction;
  502. qry.database := Self;
  503. with qry do
  504. begin
  505. ParseSQL := False;
  506. SetSchemaInfo(SchemaType,SchemaObjectName,'');
  507. open;
  508. List.Clear;
  509. while not eof do
  510. begin
  511. List.Append(trim(fieldbyname(ReturnField).asstring));
  512. Next;
  513. end;
  514. end;
  515. qry.free;
  516. end;
  517. function TSQLConnection.RowsAffected(cursor: TSQLCursor): TRowsCount;
  518. begin
  519. Result := -1;
  520. end;
  521. procedure TSQLConnection.GetTableNames(List: TStrings; SystemTables: Boolean);
  522. begin
  523. if not systemtables then GetDBInfo(stTables,'','table_name',List)
  524. else GetDBInfo(stSysTables,'','table_name',List);
  525. end;
  526. procedure TSQLConnection.GetProcedureNames(List: TStrings);
  527. begin
  528. GetDBInfo(stProcedures,'','proc_name',List);
  529. end;
  530. procedure TSQLConnection.GetFieldNames(const TableName: string; List: TStrings);
  531. begin
  532. GetDBInfo(stColumns,TableName,'column_name',List);
  533. end;
  534. function TSQLConnection.GetAsSQLText(Field : TField) : string;
  535. begin
  536. if (not assigned(field)) or field.IsNull then Result := 'Null'
  537. else case field.DataType of
  538. ftString : Result := '''' + field.asstring + '''';
  539. ftDate : Result := '''' + FormatDateTime('yyyy-mm-dd',Field.AsDateTime) + '''';
  540. ftDateTime : Result := '''' + FormatDateTime('yyyy-mm-dd hh:mm:ss',Field.AsDateTime) + ''''
  541. else
  542. Result := field.asstring;
  543. end; {case}
  544. end;
  545. function TSQLConnection.GetAsSQLText(Param: TParam) : string;
  546. begin
  547. if (not assigned(param)) or param.IsNull then Result := 'Null'
  548. else case param.DataType of
  549. ftString : Result := '''' + param.asstring + '''';
  550. ftDate : Result := '''' + FormatDateTime('yyyy-mm-dd',Param.AsDateTime) + '''';
  551. ftDateTime : Result := '''' + FormatDateTime('yyyy-mm-dd hh:mm:ss',Param.AsDateTime) + ''''
  552. else
  553. Result := Param.asstring;
  554. end; {case}
  555. end;
  556. function TSQLConnection.GetHandle: pointer;
  557. begin
  558. Result := nil;
  559. end;
  560. procedure TSQLConnection.FreeFldBuffers(cursor: TSQLCursor);
  561. begin
  562. // empty
  563. end;
  564. function TSQLConnection.GetSchemaInfoSQL( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string;
  565. begin
  566. DatabaseError(SMetadataUnavailable);
  567. end;
  568. procedure TSQLConnection.CreateDB;
  569. begin
  570. DatabaseError(SNotSupported);
  571. end;
  572. procedure TSQLConnection.DropDB;
  573. begin
  574. DatabaseError(SNotSupported);
  575. end;
  576. { TSQLTransaction }
  577. procedure TSQLTransaction.EndTransaction;
  578. begin
  579. rollback;
  580. end;
  581. function TSQLTransaction.GetHandle: pointer;
  582. begin
  583. Result := TSQLConnection(Database).GetTransactionHandle(FTrans);
  584. end;
  585. procedure TSQLTransaction.Commit;
  586. begin
  587. if active then
  588. begin
  589. closedatasets;
  590. if TSQLConnection(Database).commit(FTrans) then
  591. begin
  592. closeTrans;
  593. FreeAndNil(FTrans);
  594. end;
  595. end;
  596. end;
  597. procedure TSQLTransaction.CommitRetaining;
  598. begin
  599. if active then
  600. TSQLConnection(Database).commitRetaining(FTrans);
  601. end;
  602. procedure TSQLTransaction.Rollback;
  603. begin
  604. if active then
  605. begin
  606. closedatasets;
  607. if TSQLConnection(Database).RollBack(FTrans) then
  608. begin
  609. CloseTrans;
  610. FreeAndNil(FTrans);
  611. end;
  612. end;
  613. end;
  614. procedure TSQLTransaction.RollbackRetaining;
  615. begin
  616. if active then
  617. TSQLConnection(Database).RollBackRetaining(FTrans);
  618. end;
  619. procedure TSQLTransaction.StartTransaction;
  620. var db : TSQLConnection;
  621. begin
  622. if Active then
  623. DatabaseError(SErrTransAlreadyActive);
  624. db := TSQLConnection(Database);
  625. if Db = nil then
  626. DatabaseError(SErrDatabasenAssigned);
  627. if not Db.Connected then
  628. Db.Open;
  629. if not assigned(FTrans) then FTrans := Db.AllocateTransactionHandle;
  630. if Db.StartdbTransaction(FTrans,FParams.CommaText) then OpenTrans;
  631. end;
  632. constructor TSQLTransaction.Create(AOwner : TComponent);
  633. begin
  634. inherited Create(AOwner);
  635. FParams := TStringList.Create;
  636. end;
  637. destructor TSQLTransaction.Destroy;
  638. begin
  639. Rollback;
  640. FreeAndNil(FParams);
  641. inherited Destroy;
  642. end;
  643. Procedure TSQLTransaction.SetDatabase(Value : TDatabase);
  644. begin
  645. If Value<>Database then
  646. begin
  647. if assigned(value) and not (Value is TSQLConnection) then
  648. DatabaseErrorFmt(SErrNotASQLConnection,[value.Name],self);
  649. CheckInactive;
  650. If Assigned(Database) then
  651. with TSQLConnection(DataBase) do
  652. if Transaction = self then Transaction := nil;
  653. inherited SetDatabase(Value);
  654. If Assigned(Database) then
  655. If (TSQLConnection(DataBase).Transaction=Nil) then
  656. TSQLConnection(DataBase).Transaction:=Self;
  657. end;
  658. end;
  659. { TCustomSQLQuery }
  660. procedure TCustomSQLQuery.OnChangeSQL(Sender : TObject);
  661. var ConnOptions : TConnOptions;
  662. begin
  663. UnPrepare;
  664. if (FSQL <> nil) then
  665. begin
  666. if assigned(DataBase) then
  667. ConnOptions := TSQLConnection(DataBase).ConnOptions
  668. else
  669. ConnOptions := [sqEscapeRepeat,sqEscapeSlash];
  670. Fparams.ParseSQL(FSQL.Text,True, sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psInterbase);
  671. If Assigned(FMasterLink) then
  672. FMasterLink.RefreshParamNames;
  673. end;
  674. end;
  675. procedure TCustomSQLQuery.OnChangeModifySQL(Sender : TObject);
  676. begin
  677. CheckInactive;
  678. end;
  679. Procedure TCustomSQLQuery.SetTransaction(Value : TDBTransaction);
  680. begin
  681. UnPrepare;
  682. inherited;
  683. If (Transaction<>Nil) and (Database=Nil) then
  684. Database:=TSQLTransaction(Transaction).Database;
  685. end;
  686. procedure TCustomSQLQuery.SetDatabase(Value : TDatabase);
  687. var db : tsqlconnection;
  688. begin
  689. if (Database <> Value) then
  690. begin
  691. if assigned(value) and not (Value is TSQLConnection) then
  692. DatabaseErrorFmt(SErrNotASQLConnection,[value.Name],self);
  693. UnPrepare;
  694. if assigned(FCursor) then TSQLConnection(DataBase).DeAllocateCursorHandle(FCursor);
  695. db := TSQLConnection(Value);
  696. inherited setdatabase(value);
  697. if assigned(value) and (Transaction = nil) and (Assigned(db.Transaction)) then
  698. transaction := Db.Transaction;
  699. OnChangeSQL(Self);
  700. end;
  701. end;
  702. Function TCustomSQLQuery.IsPrepared : Boolean;
  703. begin
  704. Result := Assigned(FCursor) and FCursor.FPrepared;
  705. end;
  706. Function TCustomSQLQuery.AddFilter(SQLstr : string) : string;
  707. begin
  708. if FWhereStartPos = 0 then
  709. SQLstr := SQLstr + ' where (' + Filter + ')'
  710. else if FWhereStopPos > 0 then
  711. system.insert(' and ('+ServerFilter+') ',SQLstr,FWhereStopPos+1)
  712. else
  713. system.insert(' where ('+ServerFilter+') ',SQLstr,FWhereStartPos);
  714. Result := SQLstr;
  715. end;
  716. procedure TCustomSQLQuery.ApplyFilter;
  717. var S : String;
  718. begin
  719. FreeFldBuffers;
  720. TSQLConnection(Database).UnPrepareStatement(FCursor);
  721. FIsEOF := False;
  722. inherited internalclose;
  723. s := FSQLBuf;
  724. if ServerFiltered then s := AddFilter(s);
  725. TSQLConnection(Database).PrepareStatement(Fcursor,(transaction as tsqltransaction),S,FParams);
  726. Execute;
  727. inherited InternalOpen;
  728. First;
  729. end;
  730. Procedure TCustomSQLQuery.SetActive (Value : Boolean);
  731. begin
  732. inherited SetActive(Value);
  733. // The query is UnPrepared, so that if a transaction closes all datasets
  734. // they also get unprepared
  735. if not Value and IsPrepared then UnPrepare;
  736. end;
  737. procedure TCustomSQLQuery.SetServerFiltered(Value: Boolean);
  738. begin
  739. if Value and not FParseSQL then DatabaseErrorFmt(SNoParseSQL,['Filtering ']);
  740. if (ServerFiltered <> Value) then
  741. begin
  742. FServerFiltered := Value;
  743. if active then ApplyFilter;
  744. end;
  745. end;
  746. procedure TCustomSQLQuery.SetServerFilterText(const Value: string);
  747. begin
  748. if Value <> ServerFilter then
  749. begin
  750. FServerFilterText := Value;
  751. if active then ApplyFilter;
  752. end;
  753. end;
  754. procedure TCustomSQLQuery.Prepare;
  755. var
  756. db : tsqlconnection;
  757. sqltr : tsqltransaction;
  758. begin
  759. if not IsPrepared then
  760. begin
  761. db := TSQLConnection(Database);
  762. sqltr := (transaction as tsqltransaction);
  763. if not assigned(Db) then
  764. DatabaseError(SErrDatabasenAssigned);
  765. if not assigned(sqltr) then
  766. DatabaseError(SErrTransactionnSet);
  767. if not Db.Connected then db.Open;
  768. if not sqltr.Active then sqltr.StartTransaction;
  769. // if assigned(fcursor) then FreeAndNil(fcursor);
  770. if not assigned(fcursor) then
  771. FCursor := Db.AllocateCursorHandle;
  772. FSQLBuf := TrimRight(FSQL.Text);
  773. if FSQLBuf = '' then
  774. DatabaseError(SErrNoStatement);
  775. SQLParser(FSQLBuf);
  776. if ServerFiltered then
  777. Db.PrepareStatement(Fcursor,sqltr,AddFilter(FSQLBuf),FParams)
  778. else
  779. Db.PrepareStatement(Fcursor,sqltr,FSQLBuf,FParams);
  780. if (FCursor.FStatementType = stSelect) then
  781. FCursor.FInitFieldDef := True;
  782. end;
  783. end;
  784. procedure TCustomSQLQuery.UnPrepare;
  785. begin
  786. CheckInactive;
  787. if IsPrepared then with TSQLConnection(DataBase) do
  788. UnPrepareStatement(FCursor);
  789. end;
  790. procedure TCustomSQLQuery.FreeFldBuffers;
  791. begin
  792. if assigned(FCursor) then TSQLConnection(Database).FreeFldBuffers(FCursor);
  793. end;
  794. function TCustomSQLQuery.GetServerIndexDefs: TServerIndexDefs;
  795. begin
  796. Result := FServerIndexDefs;
  797. end;
  798. function TCustomSQLQuery.Fetch : boolean;
  799. begin
  800. if not (Fcursor.FStatementType in [stSelect]) then
  801. Exit;
  802. if not FIsEof then FIsEOF := not TSQLConnection(Database).Fetch(Fcursor);
  803. Result := not FIsEOF;
  804. end;
  805. procedure TCustomSQLQuery.Execute;
  806. begin
  807. If (FParams.Count>0) and Assigned(FMasterLink) then
  808. FMasterLink.CopyParamsFromMaster(False);
  809. TSQLConnection(Database).execute(Fcursor,Transaction as tsqltransaction, FParams);
  810. end;
  811. function TCustomSQLQuery.LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
  812. begin
  813. result := TSQLConnection(Database).LoadField(FCursor,FieldDef,buffer, Createblob)
  814. end;
  815. function TCustomSQLQuery.RowsAffected: TRowsCount;
  816. begin
  817. Result := -1;
  818. if not Assigned(Database) then Exit;
  819. //assert(Database is TSQLConnection);
  820. Result := TSQLConnection(Database).RowsAffected(FCursor);
  821. end;
  822. procedure TCustomSQLQuery.InternalAddRecord(Buffer: Pointer; AAppend: Boolean);
  823. begin
  824. // not implemented - sql dataset
  825. end;
  826. procedure TCustomSQLQuery.InternalClose;
  827. begin
  828. if StatementType = stSelect then FreeFldBuffers;
  829. // Database and FCursor could be nil, for example if the database is not assigned, and .open is called
  830. if (FOpenDidPrepare) and (assigned(database)) and (assigned(FCursor)) then
  831. begin
  832. FOpenDidPrepare:=False;
  833. TSQLConnection(database).UnPrepareStatement(FCursor);
  834. end;
  835. if DefaultFields then
  836. DestroyFields;
  837. FIsEOF := False;
  838. if assigned(FUpdateQry) then FreeAndNil(FUpdateQry);
  839. if assigned(FInsertQry) then FreeAndNil(FInsertQry);
  840. if assigned(FDeleteQry) then FreeAndNil(FDeleteQry);
  841. // FRecordSize := 0;
  842. inherited internalclose;
  843. end;
  844. procedure TCustomSQLQuery.InternalInitFieldDefs;
  845. begin
  846. if FLoadingFieldDefs then
  847. Exit;
  848. FLoadingFieldDefs := True;
  849. try
  850. FieldDefs.Clear;
  851. TSQLConnection(Database).AddFieldDefs(fcursor,FieldDefs);
  852. finally
  853. FLoadingFieldDefs := False;
  854. FCursor.FInitFieldDef := false;
  855. end;
  856. end;
  857. procedure TCustomSQLQuery.SQLParser(var ASQL : string);
  858. type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppOrder,ppComment,ppGroup,ppBogus);
  859. Var
  860. PSQL,CurrentP,
  861. PhraseP, PStatementPart : pchar;
  862. S : string;
  863. ParsePart : TParsePart;
  864. StrLength : Integer;
  865. EndOfComment : Boolean;
  866. BracketCount : Integer;
  867. ConnOptions : TConnOptions;
  868. FFromPart : String;
  869. begin
  870. PSQL:=Pchar(ASQL);
  871. ParsePart := ppStart;
  872. CurrentP := PSQL-1;
  873. PhraseP := PSQL;
  874. FWhereStartPos := 0;
  875. FWhereStopPos := 0;
  876. ConnOptions := TSQLConnection(DataBase).ConnOptions;
  877. FUpdateable := False;
  878. repeat
  879. begin
  880. inc(CurrentP);
  881. EndOfComment := SkipComments(CurrentP,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions);
  882. if EndOfcomment then dec(currentp);
  883. if EndOfComment and (ParsePart = ppStart) then PhraseP := CurrentP;
  884. // skip everything between bracket, since it could be a sub-select, and
  885. // further nothing between brackets could be interesting for the parser.
  886. if currentp^='(' then
  887. begin
  888. inc(currentp);
  889. BracketCount := 0;
  890. while (currentp^ <> #0) and ((currentp^ <> ')') or (BracketCount > 0 )) do
  891. begin
  892. if currentp^ = '(' then inc(bracketcount)
  893. else if currentp^ = ')' then dec(bracketcount);
  894. inc(currentp);
  895. end;
  896. EndOfComment := True;
  897. end;
  898. if EndOfComment or (CurrentP^ in [' ',#13,#10,#9,#0,';']) then
  899. begin
  900. if (CurrentP-PhraseP > 0) or (CurrentP^ in [';',#0]) then
  901. begin
  902. strLength := CurrentP-PhraseP;
  903. Setlength(S,strLength);
  904. if strLength > 0 then Move(PhraseP^,S[1],(strLength));
  905. s := uppercase(s);
  906. case ParsePart of
  907. ppStart : begin
  908. FCursor.FStatementType := TSQLConnection(Database).StrToStatementType(s);
  909. if FCursor.FStatementType = stSelect then ParsePart := ppSelect
  910. else break;
  911. if not FParseSQL then break;
  912. PStatementPart := CurrentP;
  913. end;
  914. ppSelect : begin
  915. if s = 'FROM' then
  916. begin
  917. ParsePart := ppFrom;
  918. PhraseP := CurrentP;
  919. PStatementPart := CurrentP;
  920. end;
  921. end;
  922. ppFrom : begin
  923. if (s = 'WHERE') or (s = 'ORDER') or (s = 'GROUP') or (CurrentP^=#0) or (CurrentP^=';') then
  924. begin
  925. if (s = 'WHERE') then
  926. begin
  927. ParsePart := ppWhere;
  928. StrLength := PhraseP-PStatementPart;
  929. end
  930. else if (s = 'GROUP') then
  931. begin
  932. ParsePart := ppGroup;
  933. StrLength := PhraseP-PStatementPart;
  934. end
  935. else if (s = 'ORDER') then
  936. begin
  937. ParsePart := ppOrder;
  938. StrLength := PhraseP-PStatementPart
  939. end
  940. else
  941. begin
  942. ParsePart := ppBogus;
  943. StrLength := CurrentP-PStatementPart;
  944. end;
  945. if FCursor.FStatementType = stSelect then
  946. begin
  947. Setlength(FFromPart,StrLength);
  948. Move(PStatementPart^,FFromPart[1],(StrLength));
  949. FFrompart := trim(FFrompart);
  950. // select-statements from more then one table are not updateable
  951. if ExtractStrings([',',' '],[],pchar(FFromPart),nil) = 1 then
  952. begin
  953. FUpdateable := True;
  954. FTableName := FFromPart;
  955. end;
  956. end;
  957. FWhereStartPos := PStatementPart-PSQL+StrLength+1;
  958. PStatementPart := CurrentP;
  959. end;
  960. end;
  961. ppWhere : begin
  962. if (s = 'ORDER') or (s = 'GROUP') or (CurrentP^=#0) or (CurrentP^=';') then
  963. begin
  964. ParsePart := ppBogus;
  965. FWhereStartPos := PStatementPart-PSQL;
  966. if (s = 'ORDER') or (s = 'GROUP') then
  967. FWhereStopPos := PhraseP-PSQL+1
  968. else
  969. FWhereStopPos := CurrentP-PSQL+1;
  970. end
  971. else if (s = 'UNION') then
  972. begin
  973. ParsePart := ppBogus;
  974. FUpdateable := False;
  975. end;
  976. end;
  977. end; {case}
  978. end;
  979. PhraseP := CurrentP+1;
  980. end
  981. end;
  982. until CurrentP^=#0;
  983. if (FWhereStartPos > 0) and (FWhereStopPos > 0) then
  984. begin
  985. system.insert('(',ASQL,FWhereStartPos+1);
  986. inc(FWhereStopPos);
  987. system.insert(')',ASQL,FWhereStopPos);
  988. end
  989. end;
  990. procedure TCustomSQLQuery.InternalOpen;
  991. var tel, fieldc : integer;
  992. f : TField;
  993. s : string;
  994. IndexFields : TStrings;
  995. ReadFromFile: Boolean;
  996. begin
  997. try
  998. ReadFromFile:=IsReadFromPacket;
  999. FOpenDidPrepare:=Not Prepared;
  1000. If FOpenDidPrepare then
  1001. Prepare;
  1002. if FCursor.FStatementType in [stSelect] then
  1003. begin
  1004. if not ReadFromFile then
  1005. begin
  1006. Execute;
  1007. // InternalInitFieldDef is only called after a prepare. i.e. not twice if
  1008. // a dataset is opened - closed - opened.
  1009. if FCursor.FInitFieldDef then InternalInitFieldDefs;
  1010. if DefaultFields then
  1011. begin
  1012. CreateFields;
  1013. if FUpdateable then
  1014. begin
  1015. if FusePrimaryKeyAsKey then
  1016. begin
  1017. UpdateServerIndexDefs;
  1018. for tel := 0 to ServerIndexDefs.count-1 do
  1019. begin
  1020. if ixPrimary in ServerIndexDefs[tel].options then
  1021. begin
  1022. IndexFields := TStringList.Create;
  1023. ExtractStrings([';'],[' '],pchar(ServerIndexDefs[tel].fields),IndexFields);
  1024. for fieldc := 0 to IndexFields.Count-1 do
  1025. begin
  1026. F := Findfield(IndexFields[fieldc]);
  1027. if F <> nil then
  1028. F.ProviderFlags := F.ProviderFlags + [pfInKey];
  1029. end;
  1030. IndexFields.Free;
  1031. end;
  1032. end;
  1033. end;
  1034. end;
  1035. end
  1036. else
  1037. BindFields(True);
  1038. end
  1039. else
  1040. BindFields(True);
  1041. if not ReadOnly and not FUpdateable then
  1042. begin
  1043. if (trim(FDeleteSQL.Text) <> '') or (trim(FUpdateSQL.Text) <> '') or
  1044. (trim(FInsertSQL.Text) <> '') then FUpdateable := True;
  1045. end
  1046. end
  1047. else
  1048. DatabaseError(SErrNoSelectStatement,Self);
  1049. except
  1050. on E:Exception do
  1051. raise;
  1052. end;
  1053. inherited InternalOpen;
  1054. end;
  1055. // public part
  1056. procedure TCustomSQLQuery.ExecSQL;
  1057. Var
  1058. ExecDidPrepare : Boolean;
  1059. begin
  1060. try
  1061. ExecDidPrepare:=Not IsPrepared;
  1062. If ExecDidPrepare then
  1063. Prepare;
  1064. Execute;
  1065. finally
  1066. // FCursor has to be assigned, or else the prepare went wrong before PrepareStatment was
  1067. // called, so UnPrepareStatement shoudn't be called either
  1068. if (ExecDidPrepare) and (assigned(database)) and (assigned(FCursor)) then
  1069. TSQLConnection(database).UnPrepareStatement(Fcursor);
  1070. end;
  1071. end;
  1072. constructor TCustomSQLQuery.Create(AOwner : TComponent);
  1073. begin
  1074. inherited Create(AOwner);
  1075. FParams := TParams.create(self);
  1076. FSQL := TStringList.Create;
  1077. FSQL.OnChange := @OnChangeSQL;
  1078. FUpdateSQL := TStringList.Create;
  1079. FUpdateSQL.OnChange := @OnChangeModifySQL;
  1080. FInsertSQL := TStringList.Create;
  1081. FInsertSQL.OnChange := @OnChangeModifySQL;
  1082. FDeleteSQL := TStringList.Create;
  1083. FDeleteSQL.OnChange := @OnChangeModifySQL;
  1084. FServerIndexDefs := TServerIndexDefs.Create(Self);
  1085. FReadOnly := false;
  1086. FParseSQL := True;
  1087. FServerFiltered := False;
  1088. FServerFilterText := '';
  1089. // Delphi has upWhereAll as default, but since strings and oldvalue's don't work yet
  1090. // (variants) set it to upWhereKeyOnly
  1091. FUpdateMode := upWhereKeyOnly;
  1092. FUsePrimaryKeyAsKey := True;
  1093. end;
  1094. destructor TCustomSQLQuery.Destroy;
  1095. begin
  1096. if Active then Close;
  1097. UnPrepare;
  1098. if assigned(FCursor) then TSQLConnection(Database).DeAllocateCursorHandle(FCursor);
  1099. FreeAndNil(FMasterLink);
  1100. FreeAndNil(FParams);
  1101. FreeAndNil(FSQL);
  1102. FreeAndNil(FInsertSQL);
  1103. FreeAndNil(FDeleteSQL);
  1104. FreeAndNil(FUpdateSQL);
  1105. FServerIndexDefs.Free;
  1106. inherited Destroy;
  1107. end;
  1108. procedure TCustomSQLQuery.SetReadOnly(AValue : Boolean);
  1109. begin
  1110. CheckInactive;
  1111. FReadOnly:=AValue;
  1112. end;
  1113. procedure TCustomSQLQuery.SetParseSQL(AValue : Boolean);
  1114. begin
  1115. CheckInactive;
  1116. if not AValue then
  1117. begin
  1118. FServerFiltered := False;
  1119. FParseSQL := False;
  1120. end
  1121. else
  1122. FParseSQL := True;
  1123. end;
  1124. procedure TCustomSQLQuery.SetUsePrimaryKeyAsKey(AValue : Boolean);
  1125. begin
  1126. if not Active then FusePrimaryKeyAsKey := AValue
  1127. else
  1128. begin
  1129. // Just temporary, this should be possible in the future
  1130. DatabaseError(SActiveDataset);
  1131. end;
  1132. end;
  1133. Procedure TCustomSQLQuery.UpdateServerIndexDefs;
  1134. begin
  1135. FServerIndexDefs.Clear;
  1136. if assigned(DataBase) and (FTableName<>'') then
  1137. TSQLConnection(DataBase).UpdateIndexDefs(ServerIndexDefs,FTableName);
  1138. end;
  1139. Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
  1140. var FieldNamesQuoteChar : char;
  1141. procedure InitialiseModifyQuery(var qry : TCustomSQLQuery; aSQL: String);
  1142. begin
  1143. qry := TCustomSQLQuery.Create(nil);
  1144. with qry do
  1145. begin
  1146. ParseSQL := False;
  1147. DataBase := Self.DataBase;
  1148. Transaction := Self.Transaction;
  1149. SQL.text := aSQL;
  1150. end;
  1151. end;
  1152. procedure UpdateWherePart(var sql_where : string;x : integer);
  1153. begin
  1154. if (pfInKey in Fields[x].ProviderFlags) or
  1155. ((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
  1156. ((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
  1157. sql_where := sql_where + '(' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + '= :' + FieldNamesQuoteChar + 'OLD_' + fields[x].FieldName + FieldNamesQuoteChar +') and ';
  1158. end;
  1159. function ModifyRecQuery : string;
  1160. var x : integer;
  1161. sql_set : string;
  1162. sql_where : string;
  1163. begin
  1164. sql_set := '';
  1165. sql_where := '';
  1166. for x := 0 to Fields.Count -1 do
  1167. begin
  1168. UpdateWherePart(sql_where,x);
  1169. if (pfInUpdate in Fields[x].ProviderFlags) then
  1170. sql_set := sql_set +FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +'=:' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
  1171. end;
  1172. if length(sql_set) = 0 then DatabaseErrorFmt(sNoUpdateFields,['update'],self);
  1173. setlength(sql_set,length(sql_set)-1);
  1174. if length(sql_where) = 0 then DatabaseErrorFmt(sNoWhereFields,['update'],self);
  1175. setlength(sql_where,length(sql_where)-5);
  1176. result := 'update ' + FTableName + ' set ' + sql_set + ' where ' + sql_where;
  1177. end;
  1178. function InsertRecQuery : string;
  1179. var x : integer;
  1180. sql_fields : string;
  1181. sql_values : string;
  1182. begin
  1183. sql_fields := '';
  1184. sql_values := '';
  1185. for x := 0 to Fields.Count -1 do
  1186. begin
  1187. if (not fields[x].IsNull) and (pfInUpdate in Fields[x].ProviderFlags) then
  1188. begin
  1189. sql_fields := sql_fields + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
  1190. sql_values := sql_values + ':' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +',';
  1191. end;
  1192. end;
  1193. if length(sql_fields) = 0 then DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
  1194. setlength(sql_fields,length(sql_fields)-1);
  1195. setlength(sql_values,length(sql_values)-1);
  1196. result := 'insert into ' + FTableName + ' (' + sql_fields + ') values (' + sql_values + ')';
  1197. end;
  1198. function DeleteRecQuery : string;
  1199. var x : integer;
  1200. sql_where : string;
  1201. begin
  1202. sql_where := '';
  1203. for x := 0 to Fields.Count -1 do
  1204. UpdateWherePart(sql_where,x);
  1205. if length(sql_where) = 0 then DatabaseErrorFmt(sNoWhereFields,['delete'],self);
  1206. setlength(sql_where,length(sql_where)-5);
  1207. result := 'delete from ' + FTableName + ' where ' + sql_where;
  1208. end;
  1209. var qry : TCustomSQLQuery;
  1210. x : integer;
  1211. Fld : TField;
  1212. begin
  1213. if sqQuoteFieldnames in TSQLConnection(DataBase).ConnOptions then
  1214. FieldNamesQuoteChar := '"'
  1215. else
  1216. FieldNamesQuoteChar := ' ';
  1217. case UpdateKind of
  1218. ukModify : begin
  1219. if not assigned(FUpdateQry) then
  1220. begin
  1221. if (trim(FUpdateSQL.Text)<> '') then
  1222. InitialiseModifyQuery(FUpdateQry,FUpdateSQL.Text)
  1223. else
  1224. InitialiseModifyQuery(FUpdateQry,ModifyRecQuery);
  1225. end;
  1226. qry := FUpdateQry;
  1227. end;
  1228. ukInsert : begin
  1229. if not assigned(FInsertQry) and (trim(FInsertSQL.Text)<> '') then
  1230. InitialiseModifyQuery(FInsertQry,FInsertSQL.Text)
  1231. else
  1232. InitialiseModifyQuery(FInsertQry,InsertRecQuery);
  1233. qry := FInsertQry;
  1234. end;
  1235. ukDelete : begin
  1236. if not assigned(FDeleteQry) and (trim(FDeleteSQL.Text)<> '') then
  1237. InitialiseModifyQuery(FDeleteQry,FDeleteSQL.Text)
  1238. else
  1239. InitialiseModifyQuery(FDeleteQry,DeleteRecQuery);
  1240. qry := FDeleteQry;
  1241. end;
  1242. end;
  1243. assert(qry.sql.Text<>'');
  1244. with qry do
  1245. begin
  1246. for x := 0 to Params.Count-1 do with params[x] do if leftstr(name,4)='OLD_' then
  1247. begin
  1248. Fld := self.FieldByName(copy(name,5,length(name)-4));
  1249. AssignFieldValue(Fld,Fld.OldValue);
  1250. end
  1251. else
  1252. begin
  1253. Fld := self.FieldByName(name);
  1254. AssignFieldValue(Fld,Fld.Value);
  1255. end;
  1256. execsql;
  1257. end;
  1258. end;
  1259. Function TCustomSQLQuery.GetCanModify: Boolean;
  1260. begin
  1261. // the test for assigned(FCursor) is needed for the case that the dataset isn't opened
  1262. if assigned(FCursor) and (FCursor.FStatementType = stSelect) then
  1263. Result:= FUpdateable and (not FReadOnly)
  1264. else
  1265. Result := False;
  1266. end;
  1267. procedure TCustomSQLQuery.SetUpdateMode(AValue : TUpdateMode);
  1268. begin
  1269. FUpdateMode := AValue;
  1270. end;
  1271. procedure TCustomSQLQuery.SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string);
  1272. begin
  1273. ReadOnly := True;
  1274. SQL.Clear;
  1275. SQL.Add(TSQLConnection(DataBase).GetSchemaInfoSQL(SchemaType, SchemaObjectName, SchemaPattern));
  1276. end;
  1277. procedure TCustomSQLQuery.LoadBlobIntoBuffer(FieldDef: TFieldDef;
  1278. ABlobBuf: PBufBlobField);
  1279. begin
  1280. TSQLConnection(DataBase).LoadBlobIntoBuffer(FieldDef, ABlobBuf, FCursor,(Transaction as tsqltransaction));
  1281. end;
  1282. function TCustomSQLQuery.GetStatementType : TStatementType;
  1283. begin
  1284. if assigned(FCursor) then Result := FCursor.FStatementType
  1285. else Result := stNone;
  1286. end;
  1287. Procedure TCustomSQLQuery.SetDataSource(AVAlue : TDatasource);
  1288. Var
  1289. DS : TDatasource;
  1290. begin
  1291. DS:=DataSource;
  1292. If (AValue<>DS) then
  1293. begin
  1294. If Assigned(AValue) and (AValue.Dataset=Self) then
  1295. DatabaseError(SErrCircularDataSourceReferenceNotAllowed,Self);
  1296. If Assigned(DS) then
  1297. DS.RemoveFreeNotification(Self);
  1298. If Assigned(AValue) then
  1299. begin
  1300. AValue.FreeNotification(Self);
  1301. If (FMasterLink=Nil) then
  1302. FMasterLink:=TMasterParamsDataLink.Create(Self);
  1303. FMasterLink.Datasource:=AValue;
  1304. end
  1305. else
  1306. FreeAndNil(FMasterLink);
  1307. end;
  1308. end;
  1309. Function TCustomSQLQuery.GetDataSource : TDatasource;
  1310. begin
  1311. If Assigned(FMasterLink) then
  1312. Result:=FMasterLink.DataSource
  1313. else
  1314. Result:=Nil;
  1315. end;
  1316. procedure TCustomSQLQuery.Notification(AComponent: TComponent; Operation: TOperation);
  1317. begin
  1318. Inherited;
  1319. If (Operation=opRemove) and (AComponent=DataSource) then
  1320. DataSource:=Nil;
  1321. end;
  1322. { TSQLScript }
  1323. procedure TSQLScript.ExecuteStatement(SQLStatement: TStrings;
  1324. var StopExecution: Boolean);
  1325. begin
  1326. fquery.SQL.assign(SQLStatement);
  1327. fquery.ExecSQL;
  1328. end;
  1329. procedure TSQLScript.ExecuteDirective(Directive, Argument: String;
  1330. var StopExecution: Boolean);
  1331. begin
  1332. if assigned (FOnDirective) then
  1333. FOnDirective (Self, Directive, Argument, StopExecution);
  1334. end;
  1335. procedure TSQLScript.ExecuteCommit;
  1336. begin
  1337. if FTransaction is TSQLTransaction then
  1338. TSQLTransaction(FTransaction).CommitRetaining
  1339. else
  1340. begin
  1341. FTransaction.Active := false;
  1342. FTransaction.Active := true;
  1343. end;
  1344. end;
  1345. procedure TSQLScript.SetDatabase(Value: TDatabase);
  1346. begin
  1347. FDatabase := Value;
  1348. end;
  1349. procedure TSQLScript.SetTransaction(Value: TDBTransaction);
  1350. begin
  1351. FTransaction := Value;
  1352. end;
  1353. procedure TSQLScript.CheckDatabase;
  1354. begin
  1355. If (FDatabase=Nil) then
  1356. DatabaseError(SErrNoDatabaseAvailable,Self)
  1357. end;
  1358. constructor TSQLScript.Create(AOwner: TComponent);
  1359. begin
  1360. inherited Create(AOwner);
  1361. FQuery := TCustomSQLQuery.Create(nil);
  1362. end;
  1363. destructor TSQLScript.Destroy;
  1364. begin
  1365. FQuery.Free;
  1366. inherited Destroy;
  1367. end;
  1368. procedure TSQLScript.Execute;
  1369. begin
  1370. FQuery.DataBase := FDatabase;
  1371. FQuery.Transaction := FTransaction;
  1372. inherited Execute;
  1373. end;
  1374. procedure TSQLScript.ExecuteScript;
  1375. begin
  1376. Execute;
  1377. end;
  1378. { Connection definitions }
  1379. Var
  1380. ConnDefs : TStringList;
  1381. Procedure CheckDefs;
  1382. begin
  1383. If (ConnDefs=Nil) then
  1384. begin
  1385. ConnDefs:=TStringList.Create;
  1386. ConnDefs.Sorted:=True;
  1387. ConnDefs.Duplicates:=dupError;
  1388. end;
  1389. end;
  1390. Procedure DoneDefs;
  1391. Var
  1392. I : Integer;
  1393. begin
  1394. If Assigned(ConnDefs) then
  1395. begin
  1396. For I:=ConnDefs.Count-1 downto 0 do
  1397. begin
  1398. ConnDefs.Objects[i].Free;
  1399. ConnDefs.Delete(I);
  1400. end;
  1401. FreeAndNil(ConnDefs);
  1402. end;
  1403. end;
  1404. Function GetConnectionDef(ConnectorName : String) : TConnectionDef;
  1405. Var
  1406. I : Integer;
  1407. begin
  1408. CheckDefs;
  1409. I:=ConnDefs.IndexOf(ConnectorName);
  1410. If (I<>-1) then
  1411. Result:=TConnectionDef(ConnDefs.Objects[i])
  1412. else
  1413. Result:=Nil;
  1414. end;
  1415. procedure RegisterConnection(Def: TConnectionDefClass);
  1416. Var
  1417. I : Integer;
  1418. begin
  1419. CheckDefs;
  1420. I:=ConnDefs.IndexOf(Def.TypeName);
  1421. If (I=-1) then
  1422. ConnDefs.AddObject(Def.TypeName,Def.Create)
  1423. else
  1424. begin
  1425. ConnDefs.Objects[I].Free;
  1426. ConnDefs.Objects[I]:=Def.Create;
  1427. end;
  1428. end;
  1429. procedure UnRegisterConnection(Def: TConnectionDefClass);
  1430. begin
  1431. UnRegisterConnection(Def.TypeName);
  1432. end;
  1433. procedure UnRegisterConnection(ConnectionName: String);
  1434. Var
  1435. I : Integer;
  1436. begin
  1437. if (ConnDefs<>Nil) then
  1438. begin
  1439. I:=ConnDefs.IndexOf(ConnectionName);
  1440. If (I<>-1) then
  1441. begin
  1442. ConnDefs.Objects[I].Free;
  1443. ConnDefs.Delete(I);
  1444. end;
  1445. end;
  1446. end;
  1447. procedure GetConnectionList(List: TSTrings);
  1448. begin
  1449. CheckDefs;
  1450. List.Text:=ConnDefs.Text;
  1451. end;
  1452. { TSQLConnector }
  1453. procedure TSQLConnector.SetConnectorType(const AValue: String);
  1454. begin
  1455. if FConnectorType<>AValue then
  1456. begin
  1457. CheckDisconnected;
  1458. If Assigned(FProxy) then
  1459. FreeProxy;
  1460. FConnectorType:=AValue;
  1461. end;
  1462. end;
  1463. procedure TSQLConnector.SetTransaction(Value: TSQLTransaction);
  1464. begin
  1465. inherited SetTransaction(Value);
  1466. If Assigned(FProxy) and (FProxy.Transaction<>Value) then
  1467. FProxy.Transaction:=Value;
  1468. end;
  1469. procedure TSQLConnector.DoInternalConnect;
  1470. Var
  1471. D : TConnectionDef;
  1472. begin
  1473. inherited DoInternalConnect;
  1474. CreateProxy;
  1475. FProxy.DatabaseName:=Self.DatabaseName;
  1476. FProxy.HostName:=Self.HostName;
  1477. FProxy.UserName:=Self.UserName;
  1478. FProxy.Password:=Self.Password;
  1479. FProxy.Transaction:=Self.Transaction;
  1480. D:=GetConnectionDef(ConnectorType);
  1481. D.ApplyParams(Params,FProxy);
  1482. FProxy.Connected:=True;
  1483. end;
  1484. procedure TSQLConnector.DoInternalDisconnect;
  1485. begin
  1486. FProxy.Connected:=False;
  1487. inherited DoInternalDisconnect;
  1488. end;
  1489. procedure TSQLConnector.CheckProxy;
  1490. begin
  1491. If (FProxy=Nil) then
  1492. CreateProxy;
  1493. end;
  1494. procedure TSQLConnector.CreateProxy;
  1495. Var
  1496. D : TConnectionDef;
  1497. begin
  1498. D:=GetConnectionDef(ConnectorType);
  1499. If (D=Nil) then
  1500. DatabaseErrorFmt(SErrUnknownConnectorType,[ConnectorType],Self);
  1501. FProxy:=D.ConnectionClass.Create(Self);
  1502. end;
  1503. procedure TSQLConnector.FreeProxy;
  1504. begin
  1505. FProxy.Connected:=False;
  1506. FreeAndNil(FProxy);
  1507. end;
  1508. function TSQLConnector.StrToStatementType(s: string): TStatementType;
  1509. begin
  1510. CheckProxy;
  1511. Result:=FProxy.StrToStatementType(s);
  1512. end;
  1513. function TSQLConnector.GetAsSQLText(Field: TField): string;
  1514. begin
  1515. CheckProxy;
  1516. Result:=FProxy.GetAsSQLText(Field);
  1517. end;
  1518. function TSQLConnector.GetAsSQLText(Param: TParam): string;
  1519. begin
  1520. CheckProxy;
  1521. Result:=FProxy.GetAsSQLText(Param);
  1522. end;
  1523. function TSQLConnector.GetHandle: pointer;
  1524. begin
  1525. CheckProxy;
  1526. Result:=FProxy.GetHandle;
  1527. end;
  1528. function TSQLConnector.AllocateCursorHandle: TSQLCursor;
  1529. begin
  1530. CheckProxy;
  1531. Result:=FProxy.AllocateCursorHandle;
  1532. end;
  1533. procedure TSQLConnector.DeAllocateCursorHandle(var cursor: TSQLCursor);
  1534. begin
  1535. CheckProxy;
  1536. FProxy.DeAllocateCursorHandle(cursor);
  1537. end;
  1538. function TSQLConnector.AllocateTransactionHandle: TSQLHandle;
  1539. begin
  1540. CheckProxy;
  1541. Result:=FProxy.AllocateTransactionHandle;
  1542. end;
  1543. procedure TSQLConnector.PrepareStatement(cursor: TSQLCursor;
  1544. ATransaction: TSQLTransaction; buf: string; AParams: TParams);
  1545. begin
  1546. CheckProxy;
  1547. FProxy.PrepareStatement(cursor, ATransaction, buf, AParams);
  1548. end;
  1549. procedure TSQLConnector.Execute(cursor: TSQLCursor;
  1550. atransaction: tSQLtransaction; AParams: TParams);
  1551. begin
  1552. CheckProxy;
  1553. FProxy.Execute(cursor, atransaction, AParams);
  1554. end;
  1555. function TSQLConnector.Fetch(cursor: TSQLCursor): boolean;
  1556. begin
  1557. CheckProxy;
  1558. Result:=FProxy.Fetch(cursor);
  1559. end;
  1560. procedure TSQLConnector.AddFieldDefs(cursor: TSQLCursor; FieldDefs: TfieldDefs
  1561. );
  1562. begin
  1563. CheckProxy;
  1564. FProxy.AddFieldDefs(cursor, FieldDefs);
  1565. end;
  1566. procedure TSQLConnector.UnPrepareStatement(cursor: TSQLCursor);
  1567. begin
  1568. CheckProxy;
  1569. FProxy.UnPrepareStatement(cursor);
  1570. end;
  1571. procedure TSQLConnector.FreeFldBuffers(cursor: TSQLCursor);
  1572. begin
  1573. CheckProxy;
  1574. FProxy.FreeFldBuffers(cursor);
  1575. end;
  1576. function TSQLConnector.LoadField(cursor: TSQLCursor; FieldDef: TfieldDef;
  1577. buffer: pointer; out CreateBlob: boolean): boolean;
  1578. begin
  1579. CheckProxy;
  1580. Result:=FProxy.LoadField(cursor, FieldDef, buffer, CreateBlob);
  1581. end;
  1582. function TSQLConnector.RowsAffected(cursor: TSQLCursor): TRowsCount;
  1583. begin
  1584. CheckProxy;
  1585. Result := FProxy.RowsAffected(cursor);
  1586. end;
  1587. function TSQLConnector.GetTransactionHandle(trans: TSQLHandle): pointer;
  1588. begin
  1589. CheckProxy;
  1590. Result:=FProxy.GetTransactionHandle(trans);
  1591. end;
  1592. function TSQLConnector.Commit(trans: TSQLHandle): boolean;
  1593. begin
  1594. CheckProxy;
  1595. Result:=FProxy.Commit(trans);
  1596. end;
  1597. function TSQLConnector.RollBack(trans: TSQLHandle): boolean;
  1598. begin
  1599. CheckProxy;
  1600. Result:=FProxy.RollBack(trans);
  1601. end;
  1602. function TSQLConnector.StartdbTransaction(trans: TSQLHandle; aParams: string
  1603. ): boolean;
  1604. begin
  1605. CheckProxy;
  1606. Result:=FProxy.StartdbTransaction(trans, aParams);
  1607. end;
  1608. procedure TSQLConnector.CommitRetaining(trans: TSQLHandle);
  1609. begin
  1610. CheckProxy;
  1611. FProxy.CommitRetaining(trans);
  1612. end;
  1613. procedure TSQLConnector.RollBackRetaining(trans: TSQLHandle);
  1614. begin
  1615. CheckProxy;
  1616. FProxy.RollBackRetaining(trans);
  1617. end;
  1618. procedure TSQLConnector.UpdateIndexDefs(IndexDefs: TIndexDefs;
  1619. TableName: string);
  1620. begin
  1621. CheckProxy;
  1622. FProxy.UpdateIndexDefs(IndexDefs, TableName);
  1623. end;
  1624. function TSQLConnector.GetSchemaInfoSQL(SchemaType: TSchemaType;
  1625. SchemaObjectName, SchemaPattern: string): string;
  1626. begin
  1627. CheckProxy;
  1628. Result:=FProxy.GetSchemaInfoSQL(SchemaType, SchemaObjectName, SchemaPattern
  1629. );
  1630. end;
  1631. procedure TSQLConnector.LoadBlobIntoBuffer(FieldDef: TFieldDef;
  1632. ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction: TSQLTransaction);
  1633. begin
  1634. CheckProxy;
  1635. FProxy.LoadBlobIntoBuffer(FieldDef, ABlobBuf, cursor, ATransaction);
  1636. end;
  1637. { TConnectionDef }
  1638. class function TConnectionDef.TypeName: String;
  1639. begin
  1640. Result:='';
  1641. end;
  1642. class function TConnectionDef.ConnectionClass: TSQLConnectionClass;
  1643. begin
  1644. Result:=Nil;
  1645. end;
  1646. class function TConnectionDef.Description: String;
  1647. begin
  1648. Result:='';
  1649. end;
  1650. procedure TConnectionDef.ApplyParams(Params: TStrings;
  1651. AConnection: TSQLConnection);
  1652. begin
  1653. AConnection.Params.Assign(Params);
  1654. end;
  1655. { TServerIndexDefs }
  1656. constructor TServerIndexDefs.create(ADataset: TDataset);
  1657. begin
  1658. if not (ADataset is TCustomSQLQuery) then
  1659. DatabaseErrorFmt(SErrNotASQLQuery,[ADataset.Name]);
  1660. inherited create(ADataset);
  1661. end;
  1662. procedure TServerIndexDefs.Update;
  1663. begin
  1664. if (not updated) and assigned(Dataset) then
  1665. begin
  1666. TCustomSQLQuery(Dataset).UpdateServerIndexDefs;
  1667. updated := True;
  1668. end;
  1669. end;
  1670. Initialization
  1671. Finalization
  1672. DoneDefs;
  1673. end.