2
0

sqlshell.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. {$mode objfpc}
  2. {$h+}
  3. uses
  4. custapp, sysutils, strutils, classes, db, sqldb, bufdataset, XMLDatapacketReader,
  5. sqlite3conn, pqconnection, ibconnection, mssqlconn, oracleconnection,mysql55conn,mysql40conn,mysql51conn,mysql50conn;
  6. Const
  7. CmdSep = [' ',#9,#10,#13,#12];
  8. type
  9. { TSQLShellApplication }
  10. TSQLShellApplication = class(TCustomApplication)
  11. Private
  12. FConn : TSQLConnection;
  13. FTR : TSQLTransaction;
  14. FQuery : TSQLQuery;
  15. FConnType : String;
  16. FCharset : String;
  17. FDatabaseName: String;
  18. FHostName : string;
  19. FUserName : String;
  20. FPassword : String;
  21. FPort : INteger;
  22. FAutoCommit : Boolean;
  23. procedure ConnectToDatabase;
  24. procedure DisconnectFromDatabase;
  25. procedure ExecuteCommand(const ASQL: UTF8String);
  26. procedure ExecuteSystemCommand(const S : UTF8String);
  27. procedure MaybeCommit;
  28. procedure MaybeRollBack;
  29. function ParseArgs: Boolean;
  30. procedure RunCommandLoop;
  31. procedure SaveLast(FN: String);
  32. procedure Usage(const Err: String);
  33. procedure WriteHelp;
  34. Protected
  35. procedure DoRun; override;
  36. Property Conn : TSQLConnection Read FConn;
  37. Property AutoCommit : Boolean Read FAutoCommit;
  38. end;
  39. Procedure TSQLShellApplication.ConnectToDatabase;
  40. begin
  41. FConn:=TSQLConnector.Create(Self);
  42. TSQLConnector(FConn).ConnectorType:=FConnType;
  43. FTR:=TSQLTransaction.Create(Self);
  44. Conn.Transaction:=FTR;
  45. Conn.DatabaseName:=FDatabaseName;
  46. Conn.HostName:=FHostName;
  47. Conn.UserName:=FUserName;
  48. Conn.Password:=FPassword;
  49. Conn.Connected:=True;
  50. if FCharset<>'' then
  51. Conn.CharSet:=FCharset;
  52. end;
  53. Procedure TSQLShellApplication.DisconnectFromDatabase;
  54. begin
  55. FreeAndNil(FTr);
  56. FreeAndNil(FConn);
  57. end;
  58. Procedure TSQLShellApplication.ExecuteCommand(Const ASQL : UTF8String);
  59. Var
  60. Q : TSQLQuery;
  61. F : TField;
  62. begin
  63. FreeAndNil(FQuery);
  64. Q:=TSQLQuery.Create(Conn);
  65. Q.Database:=Conn;
  66. Q.Transaction:=FTr;
  67. if not FTR.Active then
  68. FTR.StartTransaction;
  69. Q.SQL.Text:=aSQL;
  70. Q.Prepare;
  71. if Q.StatementType<>stSelect then
  72. begin
  73. Q.ExecSQL;
  74. Writeln('Rows affected : ',Q.RowsAffected);
  75. if AutoCommit then
  76. (Q.Transaction as TSQLTransaction).Commit;
  77. Q.Free;
  78. end
  79. else
  80. begin
  81. Q.Open;
  82. Write('|');
  83. For F in Q.Fields do
  84. Write(' ',F.FieldName,' |');
  85. Writeln;
  86. While not Q.EOF do
  87. begin
  88. Write('|');
  89. For F in Q.Fields do
  90. Write(F.AsString,' |');
  91. Writeln;
  92. Q.Next;
  93. end;
  94. FQuery:=Q;
  95. end;
  96. end;
  97. Procedure TSQLShellApplication.SaveLast(FN : String);
  98. begin
  99. FN:=Trim(FN);
  100. if FN='' then
  101. begin
  102. Write('Type filename to save data: ');
  103. Readln(fn);
  104. end;
  105. if (FN<>'') then
  106. FQuery.SaveToFile(FN,dfXML);
  107. end;
  108. Procedure TSQLShellApplication.MaybeCommit;
  109. begin
  110. if FTR.Active then
  111. FTR.Commit;
  112. end;
  113. Procedure TSQLShellApplication.MaybeRollBack;
  114. begin
  115. if FTR.Active then
  116. FTR.Commit;
  117. end;
  118. Procedure TSQLShellApplication.ExecuteSystemCommand(Const S : UTF8String);
  119. Var
  120. Cmd,Args : String;
  121. begin
  122. Cmd:=ExtractWord(1,S,CmdSep);
  123. Args:=S;
  124. Delete(Args,1,Length(Cmd)+Pos(Cmd,Args)-1);
  125. While (Length(Args)>0) and (Args[1] in CmdSep) do
  126. Delete(Args,1,1);
  127. case Cmd of
  128. 'a','autocommit' :
  129. FAutoCommit:=Not FAutoCommit;
  130. 'q','quit' :
  131. begin
  132. MaybeCommit;
  133. Terminate;
  134. end;
  135. 'x','exit' :
  136. begin
  137. MaybeRollBack;
  138. Terminate;
  139. end;
  140. 'c','commit' :
  141. MaybeCommit;
  142. 'r','collback':
  143. MaybeRollBack;
  144. 's',
  145. 'save' : SaveLast(Args);
  146. '?','h','help' : WriteHelp;
  147. end;
  148. end;
  149. Procedure TSQLShellApplication.WriteHelp;
  150. begin
  151. Writeln('Commands : ');
  152. Writeln('\a \autocommit Toggle autocommit (Current autocommit :',FAutoCommit,')');
  153. Writeln('\c \commit commit');
  154. Writeln('\h \help this help');
  155. Writeln('\q \quit commit and quit');
  156. Writeln('\r \rollback commit');
  157. Writeln('\x \exit RollBack and quit');
  158. Writeln('\s \save [FN] Save result of last select to XML file');
  159. end;
  160. Procedure TSQLShellApplication.RunCommandLoop;
  161. Var
  162. S : UTF8String;
  163. begin
  164. Writeln('Enter commands, end with \q. \?, \h or \help for help.');
  165. Repeat
  166. Write('SQL > ');
  167. Readln(S);
  168. try
  169. While (Length(S)>0) and (S[1] in CmdSep) do
  170. Delete(S,1,1);
  171. if Copy(S,1,1)='\' then
  172. begin
  173. Delete(S,1,1);
  174. ExecuteSystemCommand(S)
  175. end
  176. else
  177. ExecuteCommand(S)
  178. except
  179. On E : Exception do
  180. Writeln(Format('Error %s executing command : %s',[E.ClassName,E.Message]));
  181. end;
  182. until Terminated;
  183. Terminate;
  184. end;
  185. Procedure TSQLShellApplication.Usage(Const Err : String);
  186. Var
  187. L : TStrings;
  188. S : String;
  189. begin
  190. if (Err<>'') then
  191. Writeln('Error : ',Err);
  192. Writeln('Usage : ',ExtractFileName(Paramstr(0)),' [options]');
  193. Writeln('Where options is one or more of:');
  194. Writeln('-h --help This help text.');
  195. Writeln('-t --type=TYPE Set connection type.');
  196. Writeln('-d --database=DB Set database name.');
  197. Writeln('-H --hostname=DB Set database hostname.');
  198. Writeln('-u --username=NAME Set database user name.');
  199. Writeln('-p --password=PWD Set database user password.');
  200. Writeln('-c --charset=SET Set database character set.');
  201. Writeln('-P --port=N Set database connection port.');
  202. Writeln('Known connection types for this binary:');
  203. L:=TStringList.Create;
  204. try
  205. GetConnectionList(L);
  206. for S in L do
  207. Writeln(' ',S);
  208. finally
  209. L.Free;
  210. end;
  211. end;
  212. Function TSQLShellApplication.ParseArgs : Boolean;
  213. Var
  214. S : String;
  215. begin
  216. Result:=False;
  217. S:=CheckOptions('hH:d:t:u:p:c:P:',['help','hostname:','database:','type:','username:','password:','c:charset','port']);
  218. if (S<>'') or (HasOption('h','help')) then
  219. begin
  220. Usage(S);
  221. exit;
  222. end;
  223. FConnType:=GetOptionValue('t','type');
  224. FHostName:=GetOptionValue('H','hostname');
  225. FDatabaseName:=GetOptionValue('d','database');
  226. FUserName:=GetOptionValue('u','user');
  227. FPassword:=GetOptionValue('p','password');
  228. FCharset:=GetOptionValue('c','charset');
  229. if HasOption('P','port') then
  230. begin
  231. FPort:=StrToIntDef(GetOptionValue('P','port'),-1);
  232. if FPort=-1 then
  233. Usage('Databasename not supplied');
  234. exit;
  235. end;
  236. Result:=(FDatabaseName<>'');
  237. if not Result then
  238. Usage('Databasename not supplied');
  239. end;
  240. Procedure TSQLShellApplication.DoRun;
  241. begin
  242. StopOnException:=True;
  243. if Not ParseArgs then
  244. begin
  245. terminate;
  246. exit;
  247. end;
  248. ConnectToDatabase;
  249. RunCommandLoop;
  250. DisconnectFromDatabase;
  251. end;
  252. begin
  253. With TSQLShellApplication.Create(Nil) do
  254. try
  255. Initialize;
  256. Run;
  257. finally
  258. Free;
  259. end;
  260. end.