sqldb.pp 53 KB

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