SqlSharpCli.cs 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906
  1. //
  2. // SqlSharpCli.cs - main driver for Mono SQL Query Command Line Interface
  3. // found in mcs/tools/SqlSharp
  4. //
  5. // This program is included in Mono and is licenced under the GPL.
  6. // http://www.fsf.org/licenses/gpl.html
  7. //
  8. // For more information about Mono,
  9. // visit http://www.mono-project.com/
  10. //
  11. // To build SqlSharpCli.cs
  12. // $ mcs /out:sqlsharp.exe SqlSharpCli.cs /r:System.Data.dll
  13. //
  14. // To run with mono:
  15. // $ mono sqlsharp.exe
  16. //
  17. // To run batch commands and get the output, do something like:
  18. // $ cat commands_example.txt | mono sqlsharp.exe -s > results.txt
  19. //
  20. // Author:
  21. // Daniel Morgan <[email protected]>
  22. //
  23. // (C)Copyright 2002-2004, 2008 Daniel Morgan
  24. //
  25. using System;
  26. using System.Collections;
  27. using System.Collections.Generic;
  28. using System.Configuration;
  29. using System.Data;
  30. using System.Data.Common;
  31. using System.Data.OleDb;
  32. using System.Data.SqlClient;
  33. using System.IO;
  34. using System.Reflection;
  35. using System.Runtime.Remoting;
  36. using System.Text;
  37. namespace Mono.Data.SqlSharp {
  38. public enum FileFormat {
  39. Html,
  40. Xml,
  41. CommaSeparatedValues,
  42. TabSeparated,
  43. Normal
  44. }
  45. // SQL Sharp - Command Line Interface
  46. public class SqlSharpCli
  47. {
  48. // provider supports
  49. private bool UseParameters = true;
  50. private bool UseSimpleReader = false;
  51. private IDbConnection conn = null;
  52. private string provider = ""; // name of internal provider
  53. // {OleDb,SqlClient,MySql,Odbc,Oracle,
  54. // PostgreSql,SqlLite,Sybase,Tds} however, it
  55. // can be set to LOADEXTPROVIDER to load an external provider
  56. private string providerAssembly = "";
  57. // filename of assembly
  58. // for example: "Mono.Data.MySql"
  59. private string providerConnectionClass = "";
  60. // Connection class
  61. // in the provider assembly that implements the IDbConnection
  62. // interface. for example: "Mono.Data.MySql.MySqlConnection"
  63. Type conType;
  64. private StringBuilder build = null; // SQL string to build
  65. private string buff = ""; // SQL string buffer
  66. private string connectionString = "";
  67. private string inputFilename = "";
  68. private string outputFilename = "";
  69. private StreamReader inputFilestream = null;
  70. private StreamWriter outputFilestream = null;
  71. private string factoryName = null;
  72. private DbProviderFactory factory = null;
  73. private FileFormat outputFileFormat = FileFormat.Html;
  74. private bool silent = false;
  75. private bool showHeader = true;
  76. private Hashtable internalVariables = new Hashtable();
  77. // DisplayResult - used to Read() display a result set
  78. // called by DisplayData()
  79. public bool DisplayResult (IDataReader reader, DataTable schemaTable)
  80. {
  81. StringBuilder column = null;
  82. StringBuilder line = null;
  83. StringBuilder hdrUnderline = null;
  84. string outData = "";
  85. int hdrLen = 0;
  86. int spacing = 0;
  87. int columnSize = 0;
  88. int c;
  89. char spacingChar = ' '; // a space
  90. char underlineChar = '='; // an equal sign
  91. string dataType; // .NET Type
  92. Type theType;
  93. DataRow row; // schema row
  94. line = new StringBuilder ();
  95. hdrUnderline = new StringBuilder ();
  96. OutputLine ("");
  97. for (c = 0; c < reader.FieldCount; c++) {
  98. try {
  99. DataRow schemaRow = schemaTable.Rows [c];
  100. string columnHeader = reader.GetName (c);
  101. if (columnHeader.Equals (""))
  102. columnHeader = "column";
  103. if (columnHeader.Length > 32)
  104. columnHeader = columnHeader.Substring (0,32);
  105. // spacing
  106. columnSize = (int) schemaRow ["ColumnSize"];
  107. theType = reader.GetFieldType (c);
  108. dataType = theType.ToString ();
  109. switch (dataType) {
  110. case "System.DateTime":
  111. columnSize = 25;
  112. break;
  113. case "System.Boolean":
  114. columnSize = 5;
  115. break;
  116. case "System.Byte":
  117. columnSize = 1;
  118. break;
  119. case "System.Single":
  120. columnSize = 12;
  121. break;
  122. case "System.Double":
  123. columnSize = 21;
  124. break;
  125. case "System.Int16":
  126. case "System.Unt16":
  127. columnSize = 5;
  128. break;
  129. case "System.Int32":
  130. case "System.UInt32":
  131. columnSize = 10;
  132. break;
  133. case "System.Int64":
  134. columnSize = 19;
  135. break;
  136. case "System.UInt64":
  137. columnSize = 20;
  138. break;
  139. case "System.Decimal":
  140. columnSize = 29;
  141. break;
  142. }
  143. if (columnSize < 0)
  144. columnSize = 32;
  145. if (columnSize > 32)
  146. columnSize = 32;
  147. hdrLen = columnHeader.Length;
  148. if (hdrLen < 0)
  149. hdrLen = 0;
  150. if (hdrLen > 32)
  151. hdrLen = 32;
  152. hdrLen = System.Math.Max (hdrLen, columnSize);
  153. line.Append (columnHeader);
  154. if (columnHeader.Length < hdrLen) {
  155. spacing = hdrLen - columnHeader.Length;
  156. line.Append (spacingChar, spacing);
  157. }
  158. hdrUnderline.Append (underlineChar, hdrLen);
  159. line.Append (" ");
  160. hdrUnderline.Append (" ");
  161. }
  162. catch (Exception e) {
  163. OutputLine ("Error: Unable to display header: " + e.Message);
  164. return false;
  165. }
  166. }
  167. OutputHeader (line.ToString ());
  168. line = null;
  169. OutputHeader (hdrUnderline.ToString ());
  170. OutputHeader ("");
  171. hdrUnderline = null;
  172. int numRows = 0;
  173. // column data
  174. try {
  175. while (reader.Read ()) {
  176. numRows++;
  177. line = new StringBuilder ();
  178. for(c = 0; c < reader.FieldCount; c++) {
  179. int dataLen = 0;
  180. string dataValue = "";
  181. column = new StringBuilder ();
  182. outData = "";
  183. row = schemaTable.Rows [c];
  184. string colhdr = (string) reader.GetName (c);
  185. if (colhdr.Equals (""))
  186. colhdr = "column";
  187. if (colhdr.Length > 32)
  188. colhdr = colhdr.Substring (0, 32);
  189. columnSize = (int) row ["ColumnSize"];
  190. theType = reader.GetFieldType (c);
  191. dataType = theType.ToString ();
  192. switch (dataType) {
  193. case "System.DateTime":
  194. columnSize = 25;
  195. break;
  196. case "System.Boolean":
  197. columnSize = 5;
  198. break;
  199. case "System.Byte":
  200. columnSize = 1;
  201. break;
  202. case "System.Single":
  203. columnSize = 12;
  204. break;
  205. case "System.Double":
  206. columnSize = 21;
  207. break;
  208. case "System.Int16":
  209. case "System.Unt16":
  210. columnSize = 5;
  211. break;
  212. case "System.Int32":
  213. case "System.UInt32":
  214. columnSize = 10;
  215. break;
  216. case "System.Int64":
  217. columnSize = 19;
  218. break;
  219. case "System.UInt64":
  220. columnSize = 20;
  221. break;
  222. case "System.Decimal":
  223. columnSize = 29;
  224. break;
  225. }
  226. if (columnSize < 0)
  227. columnSize = 32;
  228. if (columnSize > 32)
  229. columnSize = 32;
  230. hdrLen = colhdr.Length;
  231. if (hdrLen < 0)
  232. hdrLen = 0;
  233. if (hdrLen > 32)
  234. hdrLen = 32;
  235. columnSize = System.Math.Max (colhdr.Length, columnSize);
  236. dataValue = "";
  237. dataLen = 0;
  238. if (!reader.IsDBNull (c)) {
  239. object o = reader.GetValue (c);
  240. if (o.GetType ().ToString ().Equals ("System.Byte[]"))
  241. dataValue = GetHexString ( (byte[]) o);
  242. else
  243. dataValue = o.ToString ();
  244. dataLen = dataValue.Length;
  245. if (dataLen <= 0) {
  246. dataValue = "";
  247. dataLen = 0;
  248. }
  249. if (dataLen > 32) {
  250. dataValue = dataValue.Substring (0, 32);
  251. dataLen = 32;
  252. }
  253. if (dataValue.Equals(""))
  254. dataLen = 0;
  255. }
  256. columnSize = System.Math.Max (columnSize, dataLen);
  257. if (dataLen < columnSize) {
  258. switch (dataType) {
  259. case "System.Byte":
  260. case "System.SByte":
  261. case "System.Int16":
  262. case "System.UInt16":
  263. case "System.Int32":
  264. case "System.UInt32":
  265. case "System.Int64":
  266. case "System.UInt64":
  267. case "System.Single":
  268. case "System.Double":
  269. case "System.Decimal":
  270. outData = dataValue.PadLeft (columnSize);
  271. break;
  272. default:
  273. outData = dataValue.PadRight (columnSize);
  274. break;
  275. }
  276. }
  277. else
  278. outData = dataValue;
  279. line.Append (outData);
  280. line.Append (" ");
  281. }
  282. OutputData (line.ToString ());
  283. }
  284. }
  285. catch (Exception rr) {
  286. OutputLine ("Error: Unable to read next row: " + rr.Message);
  287. return false;
  288. }
  289. OutputLine ("\nRows retrieved: " + numRows.ToString ());
  290. return true; // return true - success
  291. }
  292. public static string GetHexString (byte[] bytes)
  293. {
  294. string bvalue = "";
  295. if (bytes.Length > 0) {
  296. StringBuilder sb = new StringBuilder ();
  297. for (int z = 0; z < bytes.Length; z++)
  298. sb.AppendFormat("{0:X2}", bytes [z]);
  299. bvalue = "0x" + sb.ToString ();
  300. }
  301. return bvalue;
  302. }
  303. public void OutputDataToHtmlFile (IDataReader rdr, DataTable dt)
  304. {
  305. StringBuilder strHtml = new StringBuilder ();
  306. strHtml.Append ("<html> \n <head> <title>");
  307. strHtml.Append ("Results");
  308. strHtml.Append ("</title> </head>");
  309. strHtml.Append ("<body>");
  310. strHtml.Append ("<h1> Results </h1>");
  311. strHtml.Append ("<table border=1>");
  312. outputFilestream.WriteLine (strHtml.ToString ());
  313. strHtml = new StringBuilder ();
  314. strHtml.Append ("<tr>");
  315. foreach (DataRow schemaRow in dt.Rows) {
  316. strHtml.Append ("<td> <b>");
  317. object dataObj = schemaRow ["ColumnName"];
  318. string sColumnName = dataObj.ToString ();
  319. strHtml.Append (sColumnName);
  320. strHtml.Append ("</b> </td>");
  321. }
  322. strHtml.Append ("</tr>");
  323. outputFilestream.WriteLine (strHtml.ToString ());
  324. strHtml = null;
  325. int col = 0;
  326. string dataValue = "";
  327. while (rdr.Read ()) {
  328. strHtml = new StringBuilder ();
  329. strHtml.Append ("<tr>");
  330. for (col = 0; col < rdr.FieldCount; col++) {
  331. // column data
  332. if (rdr.IsDBNull (col) == true)
  333. dataValue = "NULL";
  334. else {
  335. object obj = rdr.GetValue (col);
  336. dataValue = obj.ToString ();
  337. }
  338. strHtml.Append ("<td>");
  339. strHtml.Append (dataValue);
  340. strHtml.Append ("</td>");
  341. }
  342. strHtml.Append ("\t\t</tr>");
  343. outputFilestream.WriteLine (strHtml.ToString ());
  344. strHtml = null;
  345. }
  346. outputFilestream.WriteLine (" </table> </body> \n </html>");
  347. strHtml = null;
  348. }
  349. // DisplayData - used to display any Result Sets
  350. // from execution of SQL SELECT Query or Queries
  351. // called by DisplayData.
  352. // ExecuteSql() only calls this function
  353. // for a Query, it does not get
  354. // for a Command.
  355. public void DisplayData (IDataReader reader)
  356. {
  357. DataTable schemaTable = null;
  358. int ResultSet = 0;
  359. do {
  360. // by Default, SqlDataReader has the
  361. // first Result set if any
  362. ResultSet++;
  363. OutputLine ("Display the result set " + ResultSet);
  364. schemaTable = reader.GetSchemaTable ();
  365. if (reader.FieldCount > 0) {
  366. // SQL Query (SELECT)
  367. // RecordsAffected -1 and DataTable has a reference
  368. OutputQueryResult (reader, schemaTable);
  369. }
  370. else if (reader.RecordsAffected >= 0) {
  371. // SQL Command (INSERT, UPDATE, or DELETE)
  372. // RecordsAffected >= 0
  373. Console.WriteLine ("SQL Command Records Affected: " + reader.RecordsAffected);
  374. }
  375. else {
  376. // SQL Command (not INSERT, UPDATE, nor DELETE)
  377. // RecordsAffected -1 and DataTable has a null reference
  378. Console.WriteLine ("SQL Command Executed.");
  379. }
  380. // get next result set (if anymore is left)
  381. } while (reader.NextResult ());
  382. }
  383. // display the result in a simple way
  384. // new ADO.NET providers may have not certain
  385. // things implemented yet, such as, TableSchema
  386. // support
  387. public void DisplayDataSimple (IDataReader reader)
  388. {
  389. int row = 0;
  390. Console.WriteLine ("Reading Data using simple reader...");
  391. while (reader.Read ()){
  392. row++;
  393. Console.WriteLine ("Row: " + row);
  394. for (int col = 0; col < reader.FieldCount; col++) {
  395. int co = col + 1;
  396. Console.WriteLine (" Field: " + co);
  397. string dname = (string) reader.GetName (col);
  398. if (dname == null)
  399. dname = "?column?";
  400. if (dname.Equals (String.Empty))
  401. dname = "?column?";
  402. Console.WriteLine (" Name: " + dname);
  403. string dvalue = "";
  404. if (reader.IsDBNull (col))
  405. dvalue = "(null)";
  406. else
  407. dvalue = reader.GetValue (col).ToString ();
  408. Console.WriteLine (" Value: " + dvalue);
  409. }
  410. }
  411. Console.WriteLine ("\n" + row + " ROWS RETRIEVED\n");
  412. }
  413. public void OutputQueryResult (IDataReader dreader, DataTable dtable)
  414. {
  415. if (outputFilestream == null) {
  416. DisplayResult (dreader, dtable);
  417. }
  418. else {
  419. switch (outputFileFormat) {
  420. case FileFormat.Normal:
  421. DisplayResult (dreader, dtable);
  422. break;
  423. case FileFormat.Html:
  424. OutputDataToHtmlFile (dreader, dtable);
  425. break;
  426. default:
  427. Console.WriteLine ("Error: Output data file format not supported.");
  428. break;
  429. }
  430. }
  431. }
  432. public void BuildParameters (IDbCommand cmd)
  433. {
  434. if (UseParameters == true) {
  435. ParametersBuilder parmsBuilder = new ParametersBuilder (cmd, BindVariableCharacter.Colon);
  436. Console.WriteLine ("Get Parameters (if any)...");
  437. parmsBuilder.ParseParameters ();
  438. IList parms = (IList) cmd.Parameters;
  439. Console.WriteLine ("Print each parm...");
  440. for (int p = 0; p < parms.Count; p++) {
  441. string theParmName;
  442. IDataParameter prm = (IDataParameter) parms[p];
  443. theParmName = prm.ParameterName;
  444. string inValue = "";
  445. bool found;
  446. if (parmsBuilder.ParameterMarkerCharacter == '?') {
  447. Console.Write ("Enter Parameter " +
  448. (p + 1).ToString() +
  449. ": ");
  450. inValue = Console.ReadLine();
  451. prm.Value = inValue;
  452. }
  453. else {
  454. found = GetInternalVariable (theParmName, out inValue);
  455. if (found == true) {
  456. prm.Value = inValue;
  457. }
  458. else {
  459. Console.Write ("Enter Parameter " + (p + 1).ToString () +
  460. ": " + theParmName + ": ");
  461. inValue = Console.ReadLine ();
  462. prm.Value = inValue;
  463. }
  464. }
  465. }
  466. parmsBuilder = null;
  467. }
  468. }
  469. // ExecuteSql - Execute the SQL Command(s) and/or Query(ies)
  470. public void ExecuteSql (string sql)
  471. {
  472. string msg = "";
  473. IDbCommand cmd = null;
  474. IDataReader reader = null;
  475. cmd = conn.CreateCommand();
  476. // set command properties
  477. cmd.CommandType = CommandType.Text;
  478. cmd.CommandText = sql;
  479. cmd.Connection = conn;
  480. BuildParameters (cmd);
  481. try {
  482. reader = cmd.ExecuteReader ();
  483. if (UseSimpleReader == false)
  484. DisplayData (reader);
  485. else
  486. DisplayDataSimple (reader);
  487. reader.Close ();
  488. reader = null;
  489. }
  490. catch (Exception e) {
  491. msg = "Error: " + e.Message;
  492. Console.WriteLine (msg);
  493. reader = null;
  494. }
  495. finally {
  496. cmd = null;
  497. }
  498. }
  499. // ExecuteSql - Execute the SQL Commands (no SELECTs)
  500. public void ExecuteSqlNonQuery (string sql)
  501. {
  502. string msg = "";
  503. IDbCommand cmd = null;
  504. int rowsAffected = -1;
  505. cmd = conn.CreateCommand();
  506. // set command properties
  507. cmd.CommandType = CommandType.Text;
  508. cmd.CommandText = sql;
  509. cmd.Connection = conn;
  510. BuildParameters(cmd);
  511. try {
  512. rowsAffected = cmd.ExecuteNonQuery ();
  513. cmd = null;
  514. Console.WriteLine ("Rows affected: " + rowsAffected);
  515. }
  516. catch(Exception e) {
  517. msg = "Error: " + e.Message;
  518. Console.WriteLine (msg);
  519. }
  520. finally {
  521. cmd = null;
  522. }
  523. }
  524. public void ExecuteSqlScalar(string sql)
  525. {
  526. string msg = "";
  527. IDbCommand cmd = null;
  528. string retrievedValue = "";
  529. cmd = conn.CreateCommand ();
  530. // set command properties
  531. cmd.CommandType = CommandType.Text;
  532. cmd.CommandText = sql;
  533. cmd.Connection = conn;
  534. BuildParameters(cmd);
  535. try {
  536. retrievedValue = (string) cmd.ExecuteScalar ().ToString ();
  537. Console.WriteLine ("Retrieved value: " + retrievedValue);
  538. }
  539. catch(Exception e) {
  540. msg = "Error: " + e.Message;
  541. Console.WriteLine (msg);
  542. }
  543. finally {
  544. cmd = null;
  545. }
  546. }
  547. public void ExecuteSqlXml(string sql, string[] parms)
  548. {
  549. string filename = "";
  550. if (parms.Length != 2) {
  551. Console.WriteLine ("Error: wrong number of parameters");
  552. return;
  553. }
  554. try {
  555. filename = parms [1];
  556. }
  557. catch (Exception e) {
  558. Console.WriteLine ("Error: Unable to setup output results file. " + e.Message);
  559. return;
  560. }
  561. try {
  562. IDbCommand cmd = null;
  563. cmd = conn.CreateCommand ();
  564. // set command properties
  565. cmd.CommandType = CommandType.Text;
  566. cmd.CommandText = sql;
  567. cmd.Connection = conn;
  568. BuildParameters (cmd);
  569. DataSet dataSet = new DataSet ();
  570. DbDataAdapter adapter = CreateNewDataAdapter (cmd, conn);
  571. adapter.Fill (dataSet);
  572. dataSet.WriteXml (filename);
  573. OutputLine ("Data written to xml file: " + filename);
  574. }
  575. catch (Exception exexml) {
  576. Console.WriteLine ("Error: Execute SQL XML Failure: " + exexml);
  577. }
  578. }
  579. public DbDataAdapter CreateNewDataAdapter (IDbCommand command, IDbConnection connection)
  580. {
  581. DbDataAdapter adapter = null;
  582. if (factory != null) {
  583. adapter = factory.CreateDataAdapter();
  584. DbCommand cmd = (DbCommand) command;
  585. adapter.SelectCommand = cmd;
  586. }
  587. else {
  588. switch(provider) {
  589. case "OLEDB":
  590. adapter = (DbDataAdapter) new OleDbDataAdapter ();
  591. break;
  592. case "SQLCLIENT":
  593. adapter = (DbDataAdapter) new SqlDataAdapter ();
  594. break;
  595. case "LOADEXTPROVIDER":
  596. adapter = CreateExternalDataAdapter (command, connection);
  597. if (adapter == null)
  598. return null;
  599. break;
  600. default:
  601. Console.WriteLine("Error: Data Adapter not found in provider.");
  602. return null;
  603. }
  604. IDbDataAdapter dbAdapter = (IDbDataAdapter) adapter;
  605. dbAdapter.SelectCommand = command;
  606. }
  607. return adapter;
  608. }
  609. public DbDataAdapter CreateExternalDataAdapter (IDbCommand command, IDbConnection connection)
  610. {
  611. DbDataAdapter adapter = null;
  612. Assembly ass = Assembly.Load (providerAssembly);
  613. Type [] types = ass.GetTypes ();
  614. foreach (Type t in types) {
  615. if (t.IsSubclassOf (typeof (System.Data.Common.DbDataAdapter))) {
  616. if (t.Namespace.Equals (conType.Namespace))
  617. adapter = (DbDataAdapter) Activator.CreateInstance (t);
  618. }
  619. }
  620. return adapter;
  621. }
  622. // like ShowHelp - but only show at the beginning
  623. // only the most important commands are shown
  624. // like help and quit
  625. public void StartupHelp ()
  626. {
  627. OutputLine (@"Type: \Q to quit");
  628. OutputLine (@" \ConnectionString to set the ConnectionString");
  629. OutputLine (@" \Provider to set the Provider:");
  630. OutputLine (@" {OleDb,SqlClient,MySql,Odbc,DB2,");
  631. OutputLine (@" Oracle,PostgreSql,Sqlite,Sybase,Tds)");
  632. OutputLine (@" \Open to open the connection");
  633. OutputLine (@" \Close to close the connection");
  634. OutputLine (@" \e to execute SQL query (SELECT)");
  635. OutputLine (@" \h to show help (all commands).");
  636. OutputLine (@" \defaults to show default variables.");
  637. OutputLine ("");
  638. }
  639. // ShowHelp - show the help - command a user can enter
  640. public void ShowHelp ()
  641. {
  642. Console.WriteLine ("");
  643. Console.WriteLine (@"Type: \Q to quit");
  644. Console.WriteLine (@" \ListP or \ListProviders to get factory providers");
  645. Console.WriteLine (@" \CS or \ConnectionString to set the ConnectionString");
  646. Console.WriteLine (@" \BCS to Build Connection String");
  647. Console.WriteLine (@" \P or \Provider to set the Provider:");
  648. Console.WriteLine (@" {OleDb,SqlClient,MySql,Odbc,");
  649. Console.WriteLine (@" Oracle,PostgreSql,Sqlite,Sybase,Firebird}");
  650. Console.WriteLine (@" \Open to open the connection");
  651. Console.WriteLine (@" \Close to close the connection");
  652. Console.WriteLine (@" \e to execute SQL query (SELECT)");
  653. Console.WriteLine (@" \exenonquery to execute an SQL non query (not a SELECT).");
  654. Console.WriteLine (@" \exescalar to execute SQL to get a single row and single column.");
  655. Console.WriteLine (@" \exexml FILENAME to execute SQL and save output to XML file.");
  656. if (!WaitForEnterKey ())
  657. return;
  658. Console.WriteLine (@" \f FILENAME to read a batch of SQL# commands from file.");
  659. Console.WriteLine (@" \o FILENAME to write result of commands executed to file.");
  660. Console.WriteLine (@" \load FILENAME to load from file SQL commands into SQL buffer.");
  661. Console.WriteLine (@" \save FILENAME to save SQL commands from SQL buffer to file.");
  662. Console.WriteLine (@" \h to show help (all commands).");
  663. Console.WriteLine (@" \defaults to show default variables, such as,");
  664. Console.WriteLine (@" Provider and ConnectionString.");
  665. Console.WriteLine (@" \s {TRUE, FALSE} to silent messages.");
  666. Console.WriteLine (@" \r to reset or clear the query buffer.");
  667. if (!WaitForEnterKey ())
  668. return;
  669. Console.WriteLine (@" \set NAME VALUE to set an internal variable.");
  670. Console.WriteLine (@" \unset NAME to remove an internal variable.");
  671. Console.WriteLine (@" \variable NAME to display the value of an internal variable.");
  672. Console.WriteLine (@" \loadextprovider ASSEMBLY CLASS to load the provider");
  673. Console.WriteLine (@" use the complete name of its assembly and");
  674. Console.WriteLine (@" its Connection class.");
  675. Console.WriteLine (@" \print - show what's in the SQL buffer now.");
  676. Console.WriteLine (@" \UseParameters (TRUE,FALSE) to use parameters when executing SQL.");
  677. Console.WriteLine (@" \UseSimpleReader (TRUE,FALSE) to use simple reader when displaying results.");
  678. Console.WriteLine ();
  679. }
  680. public bool WaitForEnterKey ()
  681. {
  682. Console.Write("Waiting... Press Enter key to continue. ");
  683. string entry = Console.ReadLine();
  684. if (entry.ToUpper() == "Q")
  685. return false;
  686. return true;
  687. }
  688. // ShowDefaults - show defaults for connection variables
  689. public void ShowDefaults()
  690. {
  691. Console.WriteLine ();
  692. if (provider.Equals (String.Empty) && factory == null)
  693. Console.WriteLine ("Provider is not set.");
  694. else if(factory != null) {
  695. Console.WriteLine ("The default Provider is " + factoryName);
  696. }
  697. else {
  698. Console.WriteLine ("The default Provider is " + provider);
  699. if (provider.Equals ("LOADEXTPROVIDER")) {
  700. Console.WriteLine (" Assembly: " + providerAssembly);
  701. Console.WriteLine (" Connection Class: " + providerConnectionClass);
  702. }
  703. }
  704. Console.WriteLine ();
  705. if (connectionString.Equals (""))
  706. Console.WriteLine ("ConnectionString is not set.");
  707. else {
  708. Console.WriteLine ("The default ConnectionString is: ");
  709. Console.WriteLine (" \"" + connectionString + "\"");
  710. Console.WriteLine ();
  711. }
  712. }
  713. // OpenDataSource - open connection to the data source
  714. public void OpenDataSource ()
  715. {
  716. string msg = "";
  717. if (factoryName.Equals(String.Empty) && provider.Equals(String.Empty)) {
  718. Console.Error.WriteLine("Provider not set.");
  719. return;
  720. }
  721. if (IsOpen()) {
  722. Console.Error.WriteLine("Error: already connected.");
  723. return;
  724. }
  725. OutputLine ("Opening connection...");
  726. try {
  727. if (!factoryName.Equals(String.Empty))
  728. conn = factory.CreateConnection();
  729. else {
  730. switch (provider) {
  731. case "OLEDB":
  732. conn = new OleDbConnection ();
  733. break;
  734. case "SQLCLIENT":
  735. conn = new SqlConnection ();
  736. break;
  737. case "LOADEXTPROVIDER":
  738. if (LoadExternalProvider () == false)
  739. return;
  740. break;
  741. default:
  742. Console.WriteLine ("Error: Bad argument or provider not supported.");
  743. return;
  744. }
  745. }
  746. } catch (Exception e) {
  747. msg = "Error: Unable to create Connection object because: " + e.Message;
  748. Console.WriteLine (msg);
  749. return;
  750. }
  751. conn.ConnectionString = connectionString;
  752. try {
  753. conn.Open ();
  754. if (conn.State == ConnectionState.Open)
  755. OutputLine ("Open was successfull.");
  756. } catch (Exception e) {
  757. msg = "Exception Caught Opening. " + e.Message;
  758. Console.WriteLine (msg);
  759. conn = null;
  760. }
  761. }
  762. // CloseDataSource - close the connection to the data source
  763. public void CloseDataSource () {
  764. string msg = "";
  765. if (conn != null) {
  766. OutputLine ("Attempt to Close...");
  767. try {
  768. conn.Close ();
  769. OutputLine ("Close was successfull.");
  770. } catch(Exception e) {
  771. msg = "Exeception Caught Closing. " + e.Message;
  772. Console.WriteLine (msg);
  773. }
  774. conn = null;
  775. }
  776. }
  777. public bool IsOpen () {
  778. if (conn != null)
  779. if (conn.State.Equals(ConnectionState.Open))
  780. return true;
  781. return false;
  782. }
  783. // ChangeProvider - change the provider string variable
  784. public void ChangeProvider (string[] parms) {
  785. if (IsOpen()) {
  786. Console.Error.WriteLine("Error: already connected.");
  787. return;
  788. }
  789. factory = null;
  790. factoryName = null;
  791. connectionString = "";
  792. provider = "";
  793. if (parms.Length == 2) {
  794. string parm = parms [1].ToUpper ();
  795. switch (parm) {
  796. case "ORACLE":
  797. case "ORACLECLIENT":
  798. case "SYSTEM.DATA.ORACLECLIENT":
  799. factoryName = "SYSTEM.DATA.ORACLECLIENT";
  800. break;
  801. case "SYBASE":
  802. case "MONO.DATA.SYBASECLIENT":
  803. factoryName = "MONO.DATA.SYBASECLIENT";
  804. break;
  805. case "BYTEFX":
  806. case "MYSQL":
  807. case "MYSQL.DATA.MYSQLCLIENT":
  808. factoryName = "MYSQL.DATA.MYSQLCLIENT";
  809. break;
  810. case "SQLITE":
  811. case "MONO.DATA.SQLITE":
  812. factoryName = "MONO.DATA.SQLITE";
  813. break;
  814. case "ODBC":
  815. case "SYSTEM.DATA.ODBC":
  816. factoryName = "SYSTEM.DATA.ODBC";
  817. break;
  818. case "OLEDB":
  819. case "SYSTEM.DATA.OLEDB":
  820. factoryName = "SYSTEM.DATA.OLEDB";
  821. break;
  822. case "FIREBIRD":
  823. case "FIREBIRDSQL.DATA.FIREBIRD":
  824. factoryName = "FIREBIRDSQL.DATA.FIREBIRD";
  825. break;
  826. case "POSTGRESQL":
  827. case "NPGSQL":
  828. case "NPGSQL.DATA":
  829. factoryName = "NPGSQL.DATA";
  830. break;
  831. case "SQLCLIENT":
  832. case "SYSTEM.DATA.SQLCLIENT":
  833. factoryName = "SYSTEM.DATA.SQLCLIENT";
  834. break;
  835. default:
  836. Console.WriteLine ("Error: " + "Bad argument or Provider not supported.");
  837. return;
  838. }
  839. try {
  840. factory = DbProviderFactories.GetFactory(factoryName);
  841. } catch(ConfigurationException) {
  842. Console.Error.WriteLine("*** Error: Unable to load provider factory: " +
  843. factoryName + "\n" +
  844. "*** Check your machine.config to see if the provider is " +
  845. "listed under section system.data and DbProviderFactories " +
  846. "and that your provider assembly is in the GAC. Your provider " +
  847. "may not support ADO.NET 2.0 factory and other features yet.");
  848. factoryName = null;
  849. ChangeProviderBackwardsCompat (parms);
  850. return;
  851. }
  852. OutputLine ("The default Provider is " + factoryName);
  853. }
  854. else
  855. Console.WriteLine ("Error: provider only has one parameter.");
  856. }
  857. public void ChangeProviderBackwardsCompat (string[] parms)
  858. {
  859. Console.Error.WriteLine ("*** Setting provider using Backwards Compatibility mode.");
  860. string[] extp;
  861. if (parms.Length == 2) {
  862. string parm = parms [1].ToUpper ();
  863. switch (parm) {
  864. case "ORACLE":
  865. extp = new string[3] {
  866. "\\loadextprovider",
  867. @"System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
  868. "System.Data.OracleClient.OracleConnection"};
  869. SetupExternalProvider (extp);
  870. UseParameters = false;
  871. UseSimpleReader = false;
  872. break;
  873. case "TDS":
  874. extp = new string[3] {
  875. "\\loadextprovider",
  876. @"Mono.Data.TdsClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756",
  877. "Mono.Data.TdsClient.TdsConnection"};
  878. SetupExternalProvider (extp);
  879. UseParameters = false;
  880. UseSimpleReader = false;
  881. break;
  882. case "SYBASE":
  883. extp = new string[3] {
  884. "\\loadextprovider",
  885. @"Mono.Data.SybaseClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756",
  886. "Mono.Data.SybaseClient.SybaseConnection"};
  887. SetupExternalProvider (extp);
  888. UseParameters = false;
  889. UseSimpleReader = false;
  890. break;
  891. case "BYTEFX":
  892. extp = new string[3] {
  893. "\\loadextprovider",
  894. @"ByteFX.Data, Version=0.7.6.1, Culture=neutral, PublicKeyToken=0738eb9f132ed756",
  895. "ByteFX.Data.MySqlClient.MySqlConnection"};
  896. SetupExternalProvider (extp);
  897. UseParameters = false;
  898. UseSimpleReader = false;
  899. break;
  900. case "MYSQL":
  901. case "MYSQLNET":
  902. extp = new string[3] {
  903. "\\loadextprovider",
  904. @"MySql.Data, Version=1.0.7.30073, Culture=neutral, PublicKeyToken=8e323390df8d9ed4",
  905. "MySql.Data.MySqlClient.MySqlConnection"};
  906. SetupExternalProvider (extp);
  907. UseParameters = false;
  908. UseSimpleReader = false;
  909. break;
  910. case "SQLITE":
  911. extp = new string[3] {
  912. "\\loadextprovider",
  913. @"Mono.Data.SqliteClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756",
  914. "Mono.Data.SqliteClient.SqliteConnection"};
  915. SetupExternalProvider (extp);
  916. UseParameters = false;
  917. UseSimpleReader = true;
  918. break;
  919. case "SQLCLIENT":
  920. UseParameters = false;
  921. UseSimpleReader = false;
  922. provider = parm;
  923. break;
  924. case "ODBC": // for MS NET 1.1 and above
  925. extp = new string[3] {
  926. "\\loadextprovider",
  927. @"System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
  928. "System.Data.Odbc.OdbcConnection"};
  929. SetupExternalProvider (extp);
  930. UseParameters = false;
  931. UseSimpleReader = false;
  932. break;
  933. case "MSODBC": // for MS NET 1.0
  934. extp = new string[3] {
  935. "\\loadextprovider",
  936. @"Microsoft.Data.Odbc, Culture=neutral, PublicKeyToken=b77a5c561934e089, Version=1.0.3300.0",
  937. "Microsoft.Data.Odbc.OdbcConnection"};
  938. SetupExternalProvider (extp);
  939. UseParameters = false;
  940. UseSimpleReader = false;
  941. break;
  942. case "OLEDB":
  943. UseParameters = false;
  944. UseSimpleReader = true;
  945. provider = parm;
  946. break;
  947. case "FIREBIRD":
  948. extp = new string[3] {
  949. "\\loadextprovider",
  950. @"FirebirdSql.Data.Firebird, Version=1.7.1.0, Culture=neutral, PublicKeyToken=0706f5520aae4ff4",
  951. "FirebirdSql.Data.Firebird.FbConnection"};
  952. SetupExternalProvider (extp);
  953. UseParameters = false;
  954. UseSimpleReader = false;
  955. break;
  956. case "POSTGRESQL":
  957. case "NPGSQL":
  958. extp = new string[3] {
  959. "\\loadextprovider",
  960. @"Npgsql, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7",
  961. "Npgsql.NpgsqlConnection"};
  962. SetupExternalProvider (extp);
  963. UseParameters = false;
  964. UseSimpleReader = false;
  965. break;
  966. default:
  967. Console.WriteLine ("Error: " + "Bad argument or Provider not supported.");
  968. break;
  969. }
  970. OutputLine ("The default Provider is " + provider);
  971. if (provider.Equals ("LOADEXTPROVIDER")) {
  972. OutputLine (" Assembly: " +
  973. providerAssembly);
  974. OutputLine (" Connection Class: " +
  975. providerConnectionClass);
  976. }
  977. }
  978. else
  979. Console.WriteLine ("Error: provider only has one parameter.");
  980. }
  981. // ChangeConnectionString - change the connection string variable
  982. public void ChangeConnectionString (string[] parms, string entry)
  983. {
  984. if (parms.Length >= 2)
  985. connectionString = entry.Substring (parms[0].Length, entry.Length - (parms[0].Length + 1));
  986. else
  987. connectionString = "";
  988. }
  989. public void SetupOutputResultsFile (string[] parms) {
  990. if (parms.Length != 2) {
  991. Console.WriteLine ("Error: wrong number of parameters");
  992. return;
  993. }
  994. try {
  995. outputFilestream = new StreamWriter (parms[1]);
  996. }
  997. catch (Exception e) {
  998. Console.WriteLine ("Error: Unable to setup output results file. " + e.Message);
  999. return;
  1000. }
  1001. }
  1002. public void SetupInputCommandsFile (string[] parms)
  1003. {
  1004. if (parms.Length != 2) {
  1005. Console.WriteLine ("Error: wrong number of parameters");
  1006. return;
  1007. }
  1008. try {
  1009. inputFilestream = new StreamReader (parms[1]);
  1010. }
  1011. catch (Exception e) {
  1012. Console.WriteLine ("Error: Unable to setup input commmands file. " + e.Message);
  1013. return;
  1014. }
  1015. }
  1016. public void LoadBufferFromFile (string[] parms)
  1017. {
  1018. if (parms.Length != 2) {
  1019. Console.WriteLine ("Error: wrong number of parameters");
  1020. return;
  1021. }
  1022. string inFilename = parms[1];
  1023. try {
  1024. StreamReader sr = new StreamReader (inFilename);
  1025. StringBuilder buffer = new StringBuilder ();
  1026. string NextLine;
  1027. while ((NextLine = sr.ReadLine ()) != null) {
  1028. buffer.Append (NextLine);
  1029. buffer.Append ("\n");
  1030. }
  1031. sr.Close ();
  1032. buff = buffer.ToString ();
  1033. build = null;
  1034. build = new StringBuilder ();
  1035. build.Append(buff);
  1036. }
  1037. catch (Exception e) {
  1038. Console.WriteLine ("Error: Unable to read file into SQL Buffer. " + e.Message);
  1039. }
  1040. }
  1041. public void SaveBufferToFile(string[] parms)
  1042. {
  1043. if (parms.Length != 2) {
  1044. Console.WriteLine ("Error: wrong number of parameters");
  1045. return;
  1046. }
  1047. string outFilename = parms[1];
  1048. try {
  1049. StreamWriter sw = new StreamWriter (outFilename);
  1050. sw.WriteLine (buff);
  1051. sw.Close ();
  1052. }
  1053. catch (Exception e) {
  1054. Console.WriteLine ("Error: Could not save SQL Buffer to file." + e.Message);
  1055. }
  1056. }
  1057. public void SetUseParameters (string[] parms)
  1058. {
  1059. if (parms.Length != 2) {
  1060. Console.WriteLine ("Error: wrong number of parameters");
  1061. return;
  1062. }
  1063. string parm = parms[1].ToUpper ();
  1064. if (parm.Equals ("TRUE"))
  1065. UseParameters = true;
  1066. else if (parm.Equals ("FALSE"))
  1067. UseParameters = false;
  1068. else
  1069. Console.WriteLine ("Error: invalid parameter.");
  1070. }
  1071. public void SetUseSimpleReader (string[] parms)
  1072. {
  1073. if (parms.Length != 2) {
  1074. Console.WriteLine ("Error: wrong number of parameters");
  1075. return;
  1076. }
  1077. string parm = parms[1].ToUpper ();
  1078. if (parm.Equals ("TRUE"))
  1079. UseSimpleReader = true;
  1080. else if (parm.Equals ("FALSE"))
  1081. UseSimpleReader = false;
  1082. else
  1083. Console.WriteLine ("Error: invalid parameter.");
  1084. }
  1085. public void SetupSilentMode (string[] parms)
  1086. {
  1087. if (parms.Length != 2) {
  1088. Console.WriteLine ("Error: wrong number of parameters");
  1089. return;
  1090. }
  1091. string parm = parms[1].ToUpper ();
  1092. if (parm.Equals ("TRUE"))
  1093. silent = true;
  1094. else if (parm.Equals ("FALSE"))
  1095. silent = false;
  1096. else
  1097. Console.WriteLine ("Error: invalid parameter.");
  1098. }
  1099. public void SetInternalVariable(string[] parms)
  1100. {
  1101. if (parms.Length < 2) {
  1102. Console.WriteLine ("Error: wrong number of parameters.");
  1103. return;
  1104. }
  1105. string parm = parms[1];
  1106. StringBuilder ps = new StringBuilder ();
  1107. for (int i = 2; i < parms.Length; i++)
  1108. ps.Append (parms[i]);
  1109. internalVariables[parm] = ps.ToString ();
  1110. }
  1111. public void UnSetInternalVariable(string[] parms)
  1112. {
  1113. if (parms.Length != 2) {
  1114. Console.WriteLine ("Error: wrong number of parameters.");
  1115. return;
  1116. }
  1117. string parm = parms[1];
  1118. try {
  1119. internalVariables.Remove (parm);
  1120. } catch(Exception e) {
  1121. Console.WriteLine ("Error: internal variable does not exist: " + e.Message);
  1122. }
  1123. }
  1124. public void ShowInternalVariable(string[] parms)
  1125. {
  1126. string internalVariableValue = "";
  1127. if (parms.Length != 2) {
  1128. Console.WriteLine ("Error: wrong number of parameters.");
  1129. return;
  1130. }
  1131. string parm = parms[1];
  1132. if (GetInternalVariable(parm, out internalVariableValue) == true)
  1133. Console.WriteLine ("Internal Variable - Name: " +
  1134. parm + " Value: " + internalVariableValue);
  1135. }
  1136. public bool GetInternalVariable(string name, out string sValue)
  1137. {
  1138. sValue = "";
  1139. bool valueReturned = false;
  1140. try {
  1141. if (internalVariables.ContainsKey (name) == true) {
  1142. sValue = (string) internalVariables[name];
  1143. valueReturned = true;
  1144. }
  1145. else
  1146. Console.WriteLine ("Error: internal variable does not exist.");
  1147. }
  1148. catch(Exception e) {
  1149. Console.WriteLine ("Error: internal variable does not exist: "+ e.Message);
  1150. }
  1151. return valueReturned;
  1152. }
  1153. public void SetupExternalProvider(string[] parms)
  1154. {
  1155. if (parms.Length != 3) {
  1156. Console.WriteLine ("Error: Wrong number of parameters.");
  1157. return;
  1158. }
  1159. provider = "LOADEXTPROVIDER";
  1160. providerAssembly = parms[1];
  1161. providerConnectionClass = parms[2];
  1162. }
  1163. public bool LoadExternalProvider ()
  1164. {
  1165. string msg = "";
  1166. bool success = false;
  1167. // For example: for the MySQL provider in Mono.Data.MySql
  1168. // \LoadExtProvider Mono.Data.MySql Mono.Data.MySql.MySqlConnection
  1169. // \ConnectionString dbname=test
  1170. // \open
  1171. // insert into sometable (tid, tdesc, aint) values ('abc','def',12)
  1172. // \exenonquery
  1173. // \close
  1174. // \quit
  1175. try {
  1176. OutputLine ("Loading external provider...");
  1177. Assembly ps = Assembly.Load (providerAssembly);
  1178. conType = ps.GetType (providerConnectionClass);
  1179. conn = (IDbConnection) Activator.CreateInstance (conType);
  1180. success = true;
  1181. OutputLine ("External provider loaded.");
  1182. UseParameters = false;
  1183. } catch(FileNotFoundException f) {
  1184. msg = "Error: unable to load the assembly of the provider: " + providerAssembly + " : " + f.Message;
  1185. Console.WriteLine(msg);
  1186. }
  1187. catch(Exception e) {
  1188. msg = "Error: unable to load the assembly of the provider: " + providerAssembly + " : " + e.Message;
  1189. Console.WriteLine(msg);
  1190. }
  1191. return success;
  1192. }
  1193. // used for outputting message, but if silent is set,
  1194. // don't display
  1195. public void OutputLine (string line)
  1196. {
  1197. if (silent == false)
  1198. OutputData (line);
  1199. }
  1200. // used for outputting the header columns of a result
  1201. public void OutputHeader (string line)
  1202. {
  1203. if (showHeader == true)
  1204. OutputData (line);
  1205. }
  1206. // OutputData() - used for outputting data
  1207. // if an output filename is set, then the data will
  1208. // go to a file; otherwise, it will go to the Console.
  1209. public void OutputData(string line)
  1210. {
  1211. if (outputFilestream == null)
  1212. Console.WriteLine (line);
  1213. else
  1214. outputFilestream.WriteLine (line);
  1215. }
  1216. // HandleCommand - handle SqlSharpCli commands entered
  1217. public void HandleCommand (string entry)
  1218. {
  1219. string[] parms;
  1220. parms = entry.Split (new char[1] {' '});
  1221. string userCmd = parms[0].ToUpper ();
  1222. switch (userCmd) {
  1223. case "\\LISTPROVIDERS":
  1224. case "\\LISTP":
  1225. ListProviders ();
  1226. break;
  1227. case "\\PROVIDER":
  1228. case "\\P":
  1229. ChangeProvider (parms);
  1230. break;
  1231. case "\\CONNECTIONSTRING":
  1232. case "\\CS":
  1233. ChangeConnectionString (parms, entry);
  1234. break;
  1235. case "\\LOADEXTPROVIDER":
  1236. SetupExternalProvider (parms);
  1237. break;
  1238. case "\\OPEN":
  1239. OpenDataSource ();
  1240. break;
  1241. case "\\CLOSE":
  1242. CloseDataSource ();
  1243. break;
  1244. case "\\S":
  1245. SetupSilentMode (parms);
  1246. break;
  1247. case "\\E":
  1248. case "\\EXEQUERY":
  1249. case "\\EXEREADER":
  1250. case "\\EXECUTE":
  1251. // Execute SQL Commands or Queries
  1252. if (conn == null)
  1253. Console.WriteLine ("Error: connection is not Open.");
  1254. else if (conn.State == ConnectionState.Closed)
  1255. Console.WriteLine ("Error: connection is not Open.");
  1256. else {
  1257. if (build == null)
  1258. Console.WriteLine ("Error: SQL Buffer is empty.");
  1259. else {
  1260. buff = build.ToString ();
  1261. ExecuteSql (buff);
  1262. }
  1263. build = null;
  1264. }
  1265. break;
  1266. case "\\EXENONQUERY":
  1267. if (conn == null)
  1268. Console.WriteLine ("Error: connection is not Open.");
  1269. else if (conn.State == ConnectionState.Closed)
  1270. Console.WriteLine ("Error: connection is not Open.");
  1271. else {
  1272. if (build == null)
  1273. Console.WriteLine ("Error: SQL Buffer is empty.");
  1274. else {
  1275. buff = build.ToString ();
  1276. ExecuteSqlNonQuery (buff);
  1277. }
  1278. build = null;
  1279. }
  1280. break;
  1281. case "\\EXESCALAR":
  1282. if (conn == null)
  1283. Console.WriteLine ("Error: connection is not Open.");
  1284. else if (conn.State == ConnectionState.Closed)
  1285. Console.WriteLine ("Error: connection is not Open.");
  1286. else {
  1287. if (build == null)
  1288. Console.WriteLine ("Error: SQL Buffer is empty.");
  1289. else {
  1290. buff = build.ToString ();
  1291. ExecuteSqlScalar (buff);
  1292. }
  1293. build = null;
  1294. }
  1295. break;
  1296. case "\\EXEXML":
  1297. // \exexml OUTPUT_FILENAME
  1298. if (conn == null)
  1299. Console.WriteLine ("Error: connection is not Open.");
  1300. else if (conn.State == ConnectionState.Closed)
  1301. Console.WriteLine ("Error: connection is not Open.");
  1302. else {
  1303. if (build == null)
  1304. Console.WriteLine ("Error: SQL Buffer is empty.");
  1305. else {
  1306. buff = build.ToString ();
  1307. ExecuteSqlXml (buff, parms);
  1308. }
  1309. build = null;
  1310. }
  1311. break;
  1312. case "\\F":
  1313. SetupInputCommandsFile (parms);
  1314. break;
  1315. case "\\O":
  1316. SetupOutputResultsFile (parms);
  1317. break;
  1318. case "\\LOAD":
  1319. // Load file into SQL buffer: \load FILENAME
  1320. LoadBufferFromFile (parms);
  1321. break;
  1322. case "\\SAVE":
  1323. // Save SQL buffer to file: \save FILENAME
  1324. SaveBufferToFile (parms);
  1325. break;
  1326. case "\\H":
  1327. case "\\HELP":
  1328. // Help
  1329. ShowHelp ();
  1330. break;
  1331. case "\\DEFAULTS":
  1332. // show the defaults for provider and connection strings
  1333. ShowDefaults ();
  1334. break;
  1335. case "\\BCS":
  1336. BuildConnectionString ();
  1337. break;
  1338. case "\\Q":
  1339. case "\\QUIT":
  1340. // Quit
  1341. break;
  1342. case "\\CLEAR":
  1343. case "\\RESET":
  1344. case "\\R":
  1345. // reset (clear) the query buffer
  1346. build = null;
  1347. break;
  1348. case "\\SET":
  1349. // sets internal variable
  1350. // \set name value
  1351. SetInternalVariable (parms);
  1352. break;
  1353. case "\\UNSET":
  1354. // deletes internal variable
  1355. // \unset name
  1356. UnSetInternalVariable (parms);
  1357. break;
  1358. case "\\VARIABLE":
  1359. ShowInternalVariable (parms);
  1360. break;
  1361. case "\\PRINT":
  1362. if (build == null)
  1363. Console.WriteLine ("SQL Buffer is empty.");
  1364. else
  1365. Console.WriteLine ("SQL Bufer:\n" + buff);
  1366. break;
  1367. case "\\USEPARAMETERS":
  1368. SetUseParameters (parms);
  1369. break;
  1370. case "\\USESIMPLEREADER":
  1371. SetUseSimpleReader (parms);
  1372. break;
  1373. default:
  1374. // Error
  1375. Console.WriteLine ("Error: Unknown user command.");
  1376. break;
  1377. }
  1378. }
  1379. public void ListProviders()
  1380. {
  1381. DataTable table = DbProviderFactories.GetFactoryClasses();
  1382. Console.WriteLine("List of Providers:");
  1383. for (int r = 0; r < table.Rows.Count; r++)
  1384. {
  1385. Console.WriteLine("---------------------");
  1386. Console.WriteLine(" Name: " + table.Rows[r][0].ToString());
  1387. Console.WriteLine(" Description: " + table.Rows[r][1].ToString());
  1388. Console.WriteLine(" InvariantName: " + table.Rows[r][2].ToString());
  1389. Console.WriteLine(" AssemblyQualifiedName: " + table.Rows[r][3].ToString());
  1390. }
  1391. Console.WriteLine("---------------------");
  1392. Console.WriteLine("Providers found: " + table.Rows.Count.ToString());
  1393. }
  1394. public void DealWithArgs(string[] args)
  1395. {
  1396. for (int a = 0; a < args.Length; a++) {
  1397. if (args[a].Substring (0,1).Equals ("-")) {
  1398. string arg = args [a].ToUpper ().Substring (1, args [a].Length - 1);
  1399. switch (arg) {
  1400. case "S":
  1401. silent = true;
  1402. break;
  1403. case "F":
  1404. if (a + 1 >= args.Length)
  1405. Console.WriteLine ("Error: Missing FILENAME for -f switch");
  1406. else {
  1407. inputFilename = args [a + 1];
  1408. inputFilestream = new StreamReader (inputFilename);
  1409. }
  1410. break;
  1411. case "O":
  1412. if (a + 1 >= args.Length)
  1413. Console.WriteLine ("Error: Missing FILENAME for -o switch");
  1414. else {
  1415. outputFilename = args [a + 1];
  1416. outputFilestream = new StreamWriter (outputFilename);
  1417. }
  1418. break;
  1419. default:
  1420. Console.WriteLine ("Error: Unknow switch: " + args [a]);
  1421. break;
  1422. }
  1423. }
  1424. }
  1425. }
  1426. public string GetPasswordFromConsole ()
  1427. {
  1428. StringBuilder pb = new StringBuilder ();
  1429. Console.Write ("\nPassword: ");
  1430. ConsoleKeyInfo cki = Console.ReadKey (true);
  1431. while (cki.Key != ConsoleKey.Enter) {
  1432. if (cki.Key == ConsoleKey.Backspace) {
  1433. if (pb.Length > 0) {
  1434. pb.Remove (pb.Length - 1, 1);
  1435. Console.Write ("\b");
  1436. Console.Write (" ");
  1437. Console.Write ("\b");
  1438. }
  1439. } else {
  1440. pb.Append (cki.KeyChar);
  1441. Console.Write ("*");
  1442. }
  1443. cki = Console.ReadKey (true);
  1444. }
  1445. Console.WriteLine ();
  1446. return pb.ToString ();
  1447. }
  1448. public string ReadSqlSharpCommand()
  1449. {
  1450. string entry = "";
  1451. if (inputFilestream == null) {
  1452. if (silent == false)
  1453. Console.Error.Write ("\nSQL# ");
  1454. entry = Console.ReadLine ();
  1455. }
  1456. else {
  1457. try {
  1458. entry = inputFilestream.ReadLine ();
  1459. if (entry == null) {
  1460. OutputLine ("Executing SQL# Commands from file done.");
  1461. }
  1462. }
  1463. catch (Exception e) {
  1464. Console.WriteLine ("Error: Reading command from file: " + e.Message);
  1465. }
  1466. if (silent == false)
  1467. Console.Error.Write ("\nSQL# ");
  1468. entry = Console.ReadLine ();
  1469. }
  1470. return entry;
  1471. }
  1472. public string ReadConnectionOption(string option, string defaultVal)
  1473. {
  1474. Console.Error.Write ("\nConnectionString Option: {0} [{1}] SQL# ", option, defaultVal);
  1475. return Console.ReadLine ();
  1476. }
  1477. public void BuildConnectionString ()
  1478. {
  1479. if (factory == null) {
  1480. Console.WriteLine("Provider is not set.");
  1481. return;
  1482. }
  1483. DbConnectionStringBuilder sb = factory.CreateConnectionStringBuilder ();
  1484. if (!connectionString.Equals(String.Empty))
  1485. sb.ConnectionString = connectionString;
  1486. bool found = false;
  1487. foreach (string key in sb.Keys) {
  1488. if (key.ToUpper().Equals("PASSWORD") || key.ToUpper().Equals("PWD")) {
  1489. string pwd = GetPasswordFromConsole ();
  1490. try {
  1491. sb[key] = pwd;
  1492. } catch(Exception e) {
  1493. Console.Error.WriteLine("Error: unable to set key. Reason: " + e.Message);
  1494. return;
  1495. }
  1496. } else {
  1497. string defaultVal = sb[key].ToString ();
  1498. String val = "";
  1499. val = ReadConnectionOption (key, defaultVal);
  1500. if (val.ToUpper ().Equals ("\\STOP"))
  1501. return;
  1502. if (val != "") {
  1503. try {
  1504. sb[key] = val;
  1505. } catch(Exception e) {
  1506. Console.Error.WriteLine("Error: unable to set key. Reason: " + e.Message);
  1507. return;
  1508. }
  1509. }
  1510. }
  1511. found = true;
  1512. }
  1513. if (!found) {
  1514. Console.Error.WriteLine("Warning: your provider does not subclass DbConnectionStringBuilder fully.");
  1515. return;
  1516. }
  1517. connectionString = sb.ConnectionString;
  1518. Console.WriteLine("ConnectionString is set.");
  1519. }
  1520. public void Run (string[] args)
  1521. {
  1522. DealWithArgs (args);
  1523. string entry = "";
  1524. build = null;
  1525. if (silent == false) {
  1526. Console.WriteLine ("Welcome to SQL#. The interactive SQL command-line client ");
  1527. Console.WriteLine ("for Mono.Data. See http://www.mono-project.com/ for more details.\n");
  1528. StartupHelp ();
  1529. ShowDefaults ();
  1530. }
  1531. while (entry.ToUpper ().Equals ("\\Q") == false &&
  1532. entry.ToUpper ().Equals ("\\QUIT") == false) {
  1533. while ((entry = ReadSqlSharpCommand ()) == "") {}
  1534. if (entry.Substring(0,1).Equals ("\\")) {
  1535. HandleCommand (entry);
  1536. }
  1537. else if (entry.IndexOf(";") >= 0) {
  1538. // most likely the end of SQL Command or Query found
  1539. // execute the SQL
  1540. if (conn == null)
  1541. Console.WriteLine ("Error: connection is not Open.");
  1542. else if (conn.State == ConnectionState.Closed)
  1543. Console.WriteLine ("Error: connection is not Open.");
  1544. else {
  1545. if (build == null) {
  1546. build = new StringBuilder ();
  1547. }
  1548. build.Append (entry);
  1549. //build.Append ("\n");
  1550. buff = build.ToString ();
  1551. ExecuteSql (buff);
  1552. build = null;
  1553. }
  1554. }
  1555. else {
  1556. // most likely a part of a SQL Command or Query found
  1557. // append this part of the SQL
  1558. if (build == null) {
  1559. build = new StringBuilder ();
  1560. }
  1561. build.Append (entry + "\n");
  1562. buff = build.ToString ();
  1563. }
  1564. }
  1565. CloseDataSource ();
  1566. if (outputFilestream != null)
  1567. outputFilestream.Close ();
  1568. }
  1569. }
  1570. public enum BindVariableCharacter {
  1571. Colon, // ':' - named parameter - :name
  1572. At, // '@' - named parameter - @name
  1573. QuestionMark, // '?' - positioned parameter - ?
  1574. SquareBrackets // '[]' - delimited named parameter - [name]
  1575. }
  1576. public class ParametersBuilder
  1577. {
  1578. private BindVariableCharacter bindCharSetting;
  1579. private char bindChar;
  1580. private IDataParameterCollection parms;
  1581. private string sql;
  1582. private IDbCommand cmd;
  1583. private void SetBindCharacter ()
  1584. {
  1585. switch(bindCharSetting) {
  1586. case BindVariableCharacter.Colon:
  1587. bindChar = ':';
  1588. break;
  1589. case BindVariableCharacter.At:
  1590. bindChar = '@';
  1591. break;
  1592. case BindVariableCharacter.SquareBrackets:
  1593. bindChar = '[';
  1594. break;
  1595. case BindVariableCharacter.QuestionMark:
  1596. bindChar = '?';
  1597. break;
  1598. }
  1599. }
  1600. public ParametersBuilder (IDbCommand command, BindVariableCharacter bindVarChar)
  1601. {
  1602. cmd = command;
  1603. sql = cmd.CommandText;
  1604. parms = cmd.Parameters;
  1605. bindCharSetting = bindVarChar;
  1606. SetBindCharacter();
  1607. }
  1608. public char ParameterMarkerCharacter {
  1609. get {
  1610. return bindChar;
  1611. }
  1612. }
  1613. public int ParseParameters ()
  1614. {
  1615. int numParms = 0;
  1616. char[] chars = sql.ToCharArray ();
  1617. bool bStringConstFound = false;
  1618. for (int i = 0; i < chars.Length; i++) {
  1619. if (chars[i] == '\'') {
  1620. if (bStringConstFound == true)
  1621. bStringConstFound = false;
  1622. else
  1623. bStringConstFound = true;
  1624. }
  1625. else if (chars[i] == bindChar &&
  1626. bStringConstFound == false) {
  1627. if (bindChar != '?') {
  1628. StringBuilder parm = new StringBuilder ();
  1629. i++;
  1630. if (bindChar.Equals ('[')) {
  1631. bool endingBracketFound = false;
  1632. while (i <= chars.Length) {
  1633. char ch;
  1634. if (i == chars.Length)
  1635. ch = ' '; // a space
  1636. else
  1637. ch = chars[i];
  1638. if (Char.IsLetterOrDigit (ch) || ch == ' ') {
  1639. parm.Append (ch);
  1640. }
  1641. else if (ch == ']') {
  1642. endingBracketFound = true;
  1643. string p = parm.ToString ();
  1644. AddParameter (p);
  1645. numParms ++;
  1646. break;
  1647. }
  1648. else throw new Exception("SQL Parser Error: Invalid character in parameter name");
  1649. i++;
  1650. }
  1651. i--;
  1652. if (endingBracketFound == false)
  1653. throw new Exception("SQL Parser Error: Ending bracket not found for parameter");
  1654. }
  1655. else {
  1656. while (i <= chars.Length) {
  1657. char ch;
  1658. if (i == chars.Length)
  1659. ch = ' '; // a space
  1660. else
  1661. ch = chars[i];
  1662. if (Char.IsLetterOrDigit(ch)) {
  1663. parm.Append (ch);
  1664. }
  1665. else {
  1666. string p = parm.ToString ();
  1667. AddParameter (p);
  1668. numParms ++;
  1669. break;
  1670. }
  1671. i++;
  1672. }
  1673. i--;
  1674. }
  1675. }
  1676. else {
  1677. // placeholder paramaeter for ?
  1678. string p = numParms.ToString ();
  1679. AddParameter (p);
  1680. numParms ++;
  1681. }
  1682. }
  1683. }
  1684. return numParms;
  1685. }
  1686. public void AddParameter (string p)
  1687. {
  1688. Console.WriteLine ("Add Parameter: " + p);
  1689. if (parms.Contains (p) == false) {
  1690. IDataParameter prm = cmd.CreateParameter ();
  1691. prm.ParameterName = p;
  1692. prm.Direction = ParameterDirection.Input;
  1693. prm.DbType = DbType.String; // default
  1694. prm.Value = ""; // default
  1695. cmd.Parameters.Add(prm);
  1696. }
  1697. }
  1698. }
  1699. public class SqlSharpDriver
  1700. {
  1701. public static void Main (string[] args)
  1702. {
  1703. SqlSharpCli sqlCommandLineEngine = new SqlSharpCli ();
  1704. sqlCommandLineEngine.Run (args);
  1705. }
  1706. }
  1707. }