Lua_DB (old).pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. //******************************************************************************
  2. //*** LUA SCRIPT FUNCTIONS ***
  3. //*** ***
  4. //*** (c) Massimo Magnano 2006 ***
  5. //*** ***
  6. //*** ***
  7. //******************************************************************************
  8. // File : Lua_DB.pas (rev. 2.0)
  9. //
  10. // Description : Access from Lua scripts to TDataset VCL Components
  11. // (at this time TQuery, TTable)
  12. //
  13. //******************************************************************************
  14. // Exported functions :
  15. //
  16. // Methods common to all TDataset classes
  17. // [descendent of TObject class (see Lua_object.pas)]
  18. // TDataset:Active(boolean newValue) return Status as boolean.
  19. // TDataset:First() return Status as boolean.
  20. // TDataset:Next() return Status as boolean.
  21. // TDataset:GetCount() return RecordCount as Int.
  22. // TDataset:GetField(string FieldName) return FieldValue as String.
  23. // TDataset:GetFieldSize(string FieldName) return FieldSize as Int.
  24. // TDataset:Modified() return Modified as boolean.
  25. // TDataset:SetField(string FieldName,
  26. // [int | boolean | string] newValue) return Status as boolean.
  27. // TDataset:Edit() return Status as boolean.
  28. // TDataset:Post() return Status as boolean.
  29. // CreateDBTable {Database=string, Table=string} return TTable object.
  30. // [descendent of TDataset class]
  31. // TTable:Query(string query) return Status as boolean.
  32. //
  33. // GetDBTable {Name=string} return Existing TTable object.
  34. // (same as TTable except that you cannot free it)
  35. //
  36. // CreateDBQuery {Database=string} return TQuery object.
  37. // [descendent of TDataset class]
  38. //
  39. // GetDBQuery {Name=string} return Existing TQuery object.
  40. // (same as TQuery except that you cannot free it)
  41. unit Lua_DB;
  42. interface
  43. uses Classes, DB, DBTables, Lua, Lua_Object;
  44. type
  45. TGetDataSetFunc = function (DataSetName :String) :TDataSet of object;
  46. procedure RegisterFunctions(L: Plua_State;
  47. AOwner :TComponent=Nil;
  48. AOnGetDataSetFunc :TGetDataSetFunc=Nil);
  49. procedure RegisterMethods_TDataset(L: Plua_State;
  50. AComponent :TDataset; CanFree :Boolean;
  51. PropsAccessRights :TLuaPROPSAccess);
  52. procedure RegisterMethods_TQuery(L: Plua_State;
  53. AComponent :TDataset; CanFree :Boolean;
  54. PropsAccessRights :TLuaPROPSAccess);
  55. procedure RegisterMethods_TTable(L: Plua_State;
  56. AComponent :TDataset; CanFree :Boolean;
  57. PropsAccessRights :TLuaPROPSAccess);
  58. implementation
  59. uses LuaUtils, SysUtils;
  60. const
  61. HANDLE_OWNER ='Lua_DB_OWNER';
  62. HANDLE_GETDATAFUNC ='Lua_DB_GETDATAFUNC';
  63. //========================== Lua Functions TTable ==============================
  64. function GetTDataset(L: Plua_State; Index: Integer): TDataSet;
  65. begin
  66. Result := TDataSet(LuaGetTableLightUserData(L, Index, OBJHANDLE_STR));
  67. end;
  68. function GetOwner(L: Plua_State): TComponent;
  69. begin
  70. Result := TComponent(LuaGetTableLightUserData(L, LUA_REGISTRYINDEX, HANDLE_OWNER));
  71. end;
  72. function GetOnGetDataSetFunc(L: Plua_State): TGetDataSetFunc;
  73. begin
  74. Result := TGetDataSetFunc(LuaGetTableTMethod(L, LUA_REGISTRYINDEX, HANDLE_GETDATAFUNC));
  75. end;
  76. //=== TDataset Methods =========================================================
  77. // TDataset:Active(boolean newValue) return Status as boolean.
  78. function Lua_TDataset_Active(L: Plua_State): Integer; cdecl;
  79. Var
  80. theTable :TDataset;
  81. NParams :Integer;
  82. oldState :Boolean;
  83. begin
  84. Result := 0;
  85. NParams := lua_gettop(L);
  86. if (NParams=2)
  87. then begin
  88. theTable :=Nil;
  89. oldState :=False;
  90. try
  91. theTable :=GetTDataset(L, 1);
  92. oldState :=theTable.Active;
  93. theTable.Active :=LuaToBoolean(L, 2);
  94. LuaPushBoolean(L, True);
  95. Result :=1;
  96. except
  97. On E:Exception do begin
  98. theTable.Active :=oldState;
  99. LuaError(L, ERR_Script+E.Message);
  100. end;
  101. end;
  102. end;
  103. end;
  104. // TDataset:First() return Status as boolean.
  105. function Lua_TDataset_First(L: Plua_State): Integer; cdecl;
  106. Var
  107. theTable :TDataset;
  108. NParams :Integer;
  109. begin
  110. Result := 0;
  111. NParams := lua_gettop(L);
  112. if (NParams=1)
  113. then begin
  114. try
  115. theTable :=GetTDataset(L, 1);
  116. theTable.First;
  117. LuaPushBoolean(L, True);
  118. Result :=1;
  119. except
  120. On E:Exception do begin
  121. LuaError(L, ERR_Script+E.Message);
  122. end;
  123. end;
  124. end;
  125. end;
  126. // TDataset:Next() return Status as boolean.
  127. function Lua_TDataset_Next(L: Plua_State): Integer; cdecl;
  128. Var
  129. theTable :TDataset;
  130. NParams :Integer;
  131. begin
  132. Result := 0;
  133. NParams := lua_gettop(L);
  134. if (NParams=1)
  135. then begin
  136. try
  137. theTable :=GetTDataset(L, 1);
  138. theTable.Next;
  139. LuaPushBoolean(L, True);
  140. Result :=1;
  141. except
  142. On E:Exception do begin
  143. LuaError(L, ERR_Script+E.Message);
  144. end;
  145. end;
  146. end;
  147. end;
  148. // TDataset:GetCount() return RecordCount as Int.
  149. function Lua_TDataset_GetCount(L: Plua_State): Integer; cdecl;
  150. Var
  151. theTable :TDataset;
  152. NParams :Integer;
  153. begin
  154. Result := 0;
  155. NParams := lua_gettop(L);
  156. if (NParams=1)
  157. then begin
  158. try
  159. theTable :=GetTDataset(L, 1);
  160. LuaPushInteger(L, theTable.RecordCount);
  161. Result := 1;
  162. except
  163. On E:Exception do begin
  164. LuaError(L, ERR_Script+E.Message);
  165. end;
  166. end;
  167. end;
  168. end;
  169. // TDataset:GetField(string FieldName) return FieldValue as String.
  170. function Lua_TDataset_GetField(L: Plua_State): Integer; cdecl;
  171. Var
  172. theTable :TDataset;
  173. NParams :Integer;
  174. FieldName :String;
  175. theField :TField;
  176. begin
  177. Result := 0;
  178. NParams := lua_gettop(L);
  179. if (NParams=2)
  180. then begin
  181. try
  182. theTable :=GetTDataset(L, 1);
  183. Fieldname :=LuaToString(L, 2);
  184. theField :=theTable.FindField(Fieldname);
  185. if (theField<>Nil)
  186. then begin
  187. if not(theField.IsNull)
  188. then begin
  189. LuaPushString(L, theField.AsString);
  190. Result := 1;
  191. end;
  192. end;
  193. except
  194. On E:Exception do begin
  195. LuaError(L, ERR_Script+E.Message);
  196. end;
  197. end;
  198. end;
  199. end;
  200. // TDataset:GetFieldSize(string FieldName) return FieldSize as Int.
  201. function Lua_TDataset_GetFieldSize(L: Plua_State): Integer; cdecl;
  202. Var
  203. theTable :TDataset;
  204. NParams :Integer;
  205. FieldName :String;
  206. theField :TField;
  207. begin
  208. Result := 0;
  209. NParams := lua_gettop(L);
  210. if (NParams=2)
  211. then begin
  212. try
  213. theTable :=GetTDataset(L, 1);
  214. Fieldname :=LuaToString(L, 2);
  215. theField :=theTable.FindField(Fieldname);
  216. if (theField<>Nil)
  217. then begin
  218. LuaPushInteger(L, theField.Size);
  219. Result := 1;
  220. end;
  221. except
  222. On E:Exception do begin
  223. LuaError(L, ERR_Script+E.Message);
  224. end;
  225. end;
  226. end;
  227. end;
  228. // TDataset:Modified() return Modified as boolean.
  229. function Lua_TDataset_Modified(L: Plua_State): Integer; cdecl;
  230. Var
  231. theTable :TDataset;
  232. NParams :Integer;
  233. begin
  234. Result := 0;
  235. NParams := lua_gettop(L);
  236. if (NParams=1)
  237. then begin
  238. try
  239. theTable :=GetTDataset(L, 1);
  240. LuaPushBoolean(L, theTable.Modified);
  241. Result :=1;
  242. except
  243. On E:Exception do begin
  244. LuaError(L, ERR_Script+E.Message);
  245. end;
  246. end;
  247. end;
  248. end;
  249. // TDataset:SetField(string FieldName,
  250. // [int | boolean | string] newValue) return Status as boolean.
  251. function Lua_TDataset_SetField(L: Plua_State): Integer; cdecl;
  252. Var
  253. theTable :TDataset;
  254. NParams :Integer;
  255. FieldName :String;
  256. theField :TField;
  257. valueNEW :Variant;
  258. begin
  259. Result := 0;
  260. NParams := lua_gettop(L);
  261. if (NParams=3)
  262. then begin
  263. try
  264. theTable :=GetTDataset(L, 1);
  265. Fieldname :=LuaToString(L, 2);
  266. theField :=theTable.FindField(Fieldname);
  267. if (theField<>Nil)
  268. then begin
  269. if (lua_isnumber(L, 3)<>0)
  270. then valueNEW := LuaToInteger(L, 3)
  271. else
  272. if lua_isboolean(L, 3)
  273. then valueNEW := LuaToBoolean(L, 3)
  274. else valueNEW := LuaToString(L, 3);
  275. if (valueNEW<>theField.Value)
  276. then begin
  277. theTable.Edit;
  278. theField.Value :=valueNEW;
  279. end;
  280. LuaPushBoolean(L, True);
  281. Result := 1;
  282. end;
  283. except
  284. On E:Exception do begin
  285. LuaError(L, ERR_Script+E.Message);
  286. end;
  287. end;
  288. end;
  289. end;
  290. // TDataset:Post() return Status as boolean.
  291. function Lua_TDataset_Post(L: Plua_State): Integer; cdecl;
  292. Var
  293. theTable :TDataset;
  294. NParams :Integer;
  295. begin
  296. Result := 0;
  297. NParams := lua_gettop(L);
  298. if (NParams=1)
  299. then begin
  300. try
  301. theTable :=GetTDataset(L, 1);
  302. if (theTable.State in [dsEdit, dsInsert])
  303. then theTable.Post;
  304. LuaPushBoolean(L, True);
  305. Result :=1;
  306. except
  307. On E:Exception do begin
  308. LuaError(L, ERR_Script+E.Message);
  309. end;
  310. end;
  311. end;
  312. end;
  313. // TDataset:Edit() return Status as boolean.
  314. function Lua_TDataset_Edit(L: Plua_State): Integer; cdecl;
  315. Var
  316. theTable :TDataset;
  317. NParams :Integer;
  318. begin
  319. Result := 0;
  320. NParams := lua_gettop(L);
  321. if (NParams=1)
  322. then begin
  323. try
  324. theTable :=GetTDataset(L, 1);
  325. theTable.Edit;
  326. LuaPushBoolean(L, True);
  327. Result :=1;
  328. except
  329. On E:Exception do begin
  330. LuaError(L, ERR_Script+E.Message);
  331. end;
  332. end;
  333. end;
  334. end;
  335. //=== TTable Methods ===========================================================
  336. // TTable:Query(string query) return Status as boolean.
  337. function Lua_TTable_Query(L: Plua_State): Integer; cdecl;
  338. Var
  339. theTable :TTable;
  340. NParams :Integer;
  341. xQuery :TQuery;
  342. myOwner :TComponent;
  343. begin
  344. Result := 0;
  345. NParams := lua_gettop(L);
  346. if (NParams=2)
  347. then begin
  348. try
  349. theTable :=TTable(GetTDataset(L, 1));
  350. myOwner :=GetOwner(L);
  351. xQuery :=TQuery.Create(myOwner);
  352. try
  353. xQuery.Active :=False;
  354. xQuery.DatabaseName :=theTable.DatabaseName;
  355. xQuery.SQL.Add(LuaToString(L, 2));
  356. xQuery.ExecSQL;
  357. LuaPushBoolean(L, True);
  358. Result :=1;
  359. finally
  360. xQuery.Free;
  361. end;
  362. except
  363. On E:Exception do begin
  364. LuaError(L, ERR_Script+E.Message);
  365. end;
  366. end;
  367. end;
  368. end;
  369. //=== RegisterMethods_XXX ======================================================
  370. procedure RegisterMethods_TDataset(L: Plua_State;
  371. AComponent :TDataset; CanFree :Boolean;
  372. PropsAccessRights :TLuaPROPSAccess);
  373. begin
  374. if CanFree
  375. then Lua_Object.RegisterMethods_TObject(L, AComponent, [LOMK_Free]);
  376. Lua_Object.RegisterProperties_TObject(L, AComponent, PropsAccessRights);
  377. LuaSetTableFunction(L, 1, 'Active', Lua_TDataset_Active);
  378. LuaSetTableFunction(L, 1, 'First', Lua_TDataset_First);
  379. LuaSetTableFunction(L, 1, 'Next', Lua_TDataset_Next);
  380. LuaSetTableFunction(L, 1, 'GetCount', Lua_TDataset_GetCount);
  381. LuaSetTableFunction(L, 1, 'GetField', Lua_TDataset_GetField);
  382. LuaSetTableFunction(L, 1, 'GetFieldSize', Lua_TDataset_GetFieldSize);
  383. LuaSetTableFunction(L, 1, 'SetField', Lua_TDataset_SetField);
  384. LuaSetTableFunction(L, 1, 'Edit', Lua_TDataset_Edit);
  385. LuaSetTableFunction(L, 1, 'Post', Lua_TDataset_Post);
  386. LuaSetTableFunction(L, 1, 'Modified', Lua_TDataset_Modified);
  387. end;
  388. procedure RegisterMethods_TQuery(L: Plua_State;
  389. AComponent :TDataset; CanFree :Boolean;
  390. PropsAccessRights :TLuaPROPSAccess);
  391. begin
  392. RegisterMethods_TDataset(L, AComponent, CanFree, PropsAccessRights);
  393. end;
  394. procedure RegisterMethods_TTable(L: Plua_State;
  395. AComponent :TDataset; CanFree :Boolean;
  396. PropsAccessRights :TLuaPROPSAccess);
  397. begin
  398. RegisterMethods_TDataset(L, AComponent, CanFree, PropsAccessRights);
  399. LuaSetTableFunction(L, 1, 'Query', Lua_TTable_Query);
  400. end;
  401. // CreateDBTable {Database=string, Table=string} return TTable object.
  402. function Lua_CreateDBTable(L: Plua_State): Integer; cdecl;
  403. Var
  404. DBPath,
  405. DBTableName :String;
  406. xResult :TTable;
  407. myOwner :TComponent;
  408. begin
  409. Result := 0;
  410. try
  411. myOwner :=GetOwner(L);
  412. DBPath :=LuaGetTableString(L, 1, 'Database');
  413. DBTableName :=LuaGetTableString(L, 1, 'Table');
  414. LuaSetTableNil(L, 1, 'Database');
  415. LuaSetTableNil(L, 1, 'Table');
  416. xResult := TTable.Create(myOwner);
  417. if (xResult=Nil)
  418. then raise Exception.Create('Unable to Create Tables');
  419. xResult.Active :=False;
  420. xResult.DatabaseName :=DBPath;
  421. xResult.TableName :=DBTableName;
  422. RegisterMethods_TTable(L, xResult, true, LUAPROPS_ACCESS_READWRITE);
  423. Result := 1;
  424. except
  425. On E:Exception do begin
  426. LuaError(L, ERR_Script+E.Message);
  427. end;
  428. end;
  429. end;
  430. // GetDBTable {Name=string} return Existing TTable object.
  431. function Lua_GetDBTable(L: Plua_State): Integer; cdecl;
  432. Var
  433. DBName :String;
  434. xResult :TDataSet;
  435. myOnGetDataSetFunc :TGetDataSetFunc;
  436. begin
  437. Result := 0;
  438. try
  439. myOnGetDataSetFunc :=GetOnGetDataSetFunc(L);
  440. DBName :=LuaGetTableString(L, 1, 'Name');
  441. LuaSetTableNil(L, 1, 'Name');
  442. if Assigned(myOnGetDataSetFunc)
  443. then begin
  444. xResult :=myOnGetDataSetFunc(DBName);
  445. if not(xResult is TTable)
  446. then xResult :=Nil;
  447. end
  448. else xResult :=Nil;
  449. if (xResult=Nil)
  450. then raise Exception.Create('Unable to Get Table '+DBName);
  451. RegisterMethods_TTable(L, xResult, false, LUAPROPS_ACCESS_READWRITE);
  452. Result := 1;
  453. except
  454. On E:Exception do begin
  455. LuaError(L, ERR_Script+E.Message);
  456. end;
  457. end;
  458. end;
  459. // CreateDBQuery {Database=string} return TQuery object.
  460. function Lua_CreateDBQuery(L: Plua_State): Integer; cdecl;
  461. Var
  462. DBPath :String;
  463. xResult :TQuery;
  464. myOwner :TComponent;
  465. begin
  466. Result := 0;
  467. try
  468. myOwner :=GetOwner(L);
  469. DBPath :=LuaGetTableString(L, 1, 'Database');
  470. LuaSetTableNil(L, 1, 'Database');
  471. xResult := TQuery.Create(myOwner);
  472. if (xResult=Nil)
  473. then raise Exception.Create('Unable to Create Queries');
  474. xResult.Active :=False;
  475. xResult.DatabaseName :=DBPath;
  476. RegisterMethods_TQuery(L, xResult, true, LUAPROPS_ACCESS_READWRITE);
  477. Result := 1;
  478. except
  479. On E:Exception do begin
  480. LuaError(L, ERR_Script+E.Message);
  481. end;
  482. end;
  483. end;
  484. // GetDBQuery {Name=string} return Existing TQuery object.
  485. function Lua_GetDBQuery(L: Plua_State): Integer; cdecl;
  486. Var
  487. DBName :String;
  488. xResult :TDataSet;
  489. myOnGetDataSetFunc :TGetDataSetFunc;
  490. begin
  491. Result := 0;
  492. try
  493. myOnGetDataSetFunc :=GetOnGetDataSetFunc(L);
  494. DBName :=LuaGetTableString(L, 1, 'Name');
  495. LuaSetTableNil(L, 1, 'Name');
  496. if Assigned(myOnGetDataSetFunc)
  497. then begin
  498. xResult :=myOnGetDataSetFunc(DBName);
  499. if not(xResult is TQuery)
  500. then xResult :=Nil;
  501. end
  502. else xResult :=Nil;
  503. if (xResult=Nil)
  504. then raise Exception.Create('Unable to Get Query '+DBName);
  505. RegisterMethods_TQuery(L, xResult, false, LUAPROPS_ACCESS_READWRITE);
  506. Result := 1;
  507. except
  508. On E:Exception do begin
  509. LuaError(L, ERR_Script+E.Message);
  510. end;
  511. end;
  512. end;
  513. procedure RegisterFunctions(L: Plua_State;
  514. AOwner :TComponent=Nil;
  515. AOnGetDataSetFunc :TGetDataSetFunc=Nil);
  516. begin
  517. //myOwner :=AOwner;
  518. //myOnGetDataSetFunc :=AOnGetDataSetFunc;
  519. LuaSetTableLightUserData(L, LUA_REGISTRYINDEX,
  520. HANDLE_OWNER, AOwner);
  521. LuaSetTableTMethod(L, LUA_REGISTRYINDEX,
  522. HANDLE_GETDATAFUNC, TMethod(AOnGetDataSetFunc));
  523. LuaRegister(L, 'CreateDBTable', Lua_CreateDBTable);
  524. LuaRegister(L, 'CreateDBQuery', Lua_CreateDBQuery);
  525. if Assigned(AOnGetDataSetFunc)
  526. then begin
  527. LuaRegister(L, 'GetDBTable', Lua_GetDBTable);
  528. LuaRegister(L, 'GetDBQuery', Lua_GetDBQuery);
  529. end;
  530. end;
  531. end.