sqldb.pp 53 KB

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