sqldb.pp 55 KB

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