sqldb.pp 52 KB

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