Allow schema files that are missing checksums on the !!SCHEMAMATIC line.
[versaplex.git] / versaplexd / vxcli.cs
blob380efc0522c0c835e07a000186e009922a490783
1 /*
2 * Versaplex:
3 * Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
4 * See the included file named LICENSE for license information.
5 */
6 using System;
7 using System.Collections.Generic;
8 using System.Data;
9 using System.Data.Common;
10 using System.IO;
11 using System.Linq;
12 using Wv.Mono.Terminal;
13 using Wv;
14 using Wv.Extensions;
16 namespace Wv
18 public class VxDbException : DbException
20 public VxDbException(string msg) : base(msg)
25 [WvMoniker]
26 public class WvDbi_Versaplex : WvDbi
28 WvDbus bus;
30 struct ColInfo
32 public int size;
33 public string name;
34 public string type;
35 public short precision;
36 public short scale;
37 public byte nullable;
40 public static void wvmoniker_register()
42 WvMoniker<WvDbi>.register("vx",
43 (string m, object o) => new WvDbi_Versaplex(m));
46 public WvDbi_Versaplex(string busurl)
48 WvUrl url = new WvUrl(busurl);
50 if (url.host.e() || url.host == "session")
51 bus = WvDbus.session_bus;
52 else
53 bus = new WvDbus(wv.fmt("tcp:host={0},port={1}",
54 url.host, url.port));
57 public override WvSqlRows select(string sql, params object[] args)
59 var call = new WvDbusCall("vx.versaplexd", "/db", "vx.db",
60 "ExecRecordset", "s");
61 WvDbusWriter writer = new WvDbusWriter();
62 writer.Write(sql);
63 call.write(writer);
65 WvDbusMsg reply = bus.send_and_wait(call);
66 if (reply.err == "vx.db.sqlerror")
67 throw new VxDbException(reply.iter().pop());
68 reply.check("a(issnny)vaay");
69 var it = reply.iter();
71 // decode the raw column info
72 var l = new List<WvColInfo>();
73 foreach (IEnumerable<WvAutoCast> c in it.pop())
75 int size;
76 string name, type;
77 short precision, scale;
78 byte nullable;
79 c.ToArray().assignto(out size, out name, out type,
80 out precision, out scale,
81 out nullable);
83 l.Add(new WvColInfo(name, typeof(string),
84 nullable != 0,
85 size, precision, scale));
88 WvColInfo[] colinfo = l.ToArray();
89 var rows = new List<WvSqlRow>();
90 foreach (var r in it.pop())
91 rows.Add(new WvSqlRow(r.Cast<object>().ToArray(),
92 colinfo));
94 return new WvSqlRows_Versaplex(rows.ToArray(), colinfo);
97 public override int execute(string sql, params object[] args)
99 using (select(sql, args))
100 return 0;
104 class WvSqlRows_Versaplex : WvSqlRows, IEnumerable<WvSqlRow>
106 WvSqlRow[] rows;
107 WvColInfo[] schema;
109 public WvSqlRows_Versaplex(WvSqlRow[] rows, WvColInfo[] schema)
111 this.rows = rows;
112 this.schema = schema;
115 public override IEnumerable<WvColInfo> columns
116 { get { return schema; } }
118 public override IEnumerator<WvSqlRow> GetEnumerator()
120 foreach (var row in rows)
121 yield return row;
126 public static class VxCli
128 public static int Main(string[] args)
130 WvLog.maxlevel = WvLog.L.Debug;
131 WvLog log = new WvLog("vxcli");
133 if (args.Length != 1)
135 Console.Error.WriteLine("Usage: vxcli <db-connection-string>");
136 return 1;
139 string moniker = args[0];
141 WvIni vxini = new WvIni("versaplexd.ini");
142 if (vxini.get("Connections", moniker) != null)
143 moniker = vxini.get("Connections", moniker);
145 WvIni bookmarks = new WvIni(
146 wv.PathCombine(wv.getenv("HOME"), ".wvdbi.ini"));
147 if (!moniker.Contains(":")
148 && bookmarks["Bookmarks"].ContainsKey(moniker))
150 moniker = bookmarks["Bookmarks"][moniker];
152 else
154 // not found in existing bookmarks, so see if we can parse and
155 // save instead.
156 WvUrl url = new WvUrl(moniker);
157 string path = url.path;
158 if (path.StartsWith("/"))
159 path = path.Substring(1);
160 if (path != "" && url.host != null)
162 log.print("Creating bookmark '{0}'\n", path);
163 bookmarks.set("Bookmarks", path, moniker);
164 try {
165 bookmarks.save();
166 } catch (IOException) {
167 // not a big deal if we can't save our bookmarks.
172 using (var dbi = WvDbi.create(moniker))
174 LineEditor le = new LineEditor("VxCli");
175 string inp;
177 while (true)
179 Console.WriteLine();
180 inp = le.Edit("vx> ", "");
181 if (inp == null) break;
182 if (inp == "") continue;
185 using (var result = dbi.select(inp))
187 var colnames =
188 from c in result.columns
189 select c.name.ToUpper();
190 Console.Write(wv.fmt("{0}\n\n",
191 colnames.join(",")));
193 foreach (var row in result)
194 Console.Write(wv.fmt("{0}\n", row.join(",")));
197 catch (DbException e)
199 Console.Write(wv.fmt("ERROR: {0}\n", e.Short()));
204 return 0;