private void confirmfail(WvDbusMsg response) { WVPASS(response.type = Wv.Dbus.MType.Error); WVPASS(response.signature = "s"); var i = response.iter(); WVPASSEQ(i.pop(), failmsg); }
public static void CallExecRecordset(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "s") { reply = CreateUnknownMethodReply(call, "ExecRecordset"); return; } if (call.Body == null) { reply = call.err_reply ("org.freedesktop.DBus.Error.InvalidSignature", "Signature provided but no body received"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string query = it.pop(); VxColumnInfo[] colinfo; object[][] data; byte[][] nullity; VxDb.ExecRecordset(clientid, (string)query, out colinfo, out data, out nullity); // FIXME: Add vx.db.toomuchdata error WvDbusWriter writer = PrepareRecordsetWriter(colinfo, data, nullity); reply = call.reply("a(issnny)vaay").write(writer); }
private static void HandleCancelQuery(WvDbus conn, WvDbusMsg msg) { log.print(WvLog.L.Debug4, "Received CancelQuery request\n"); //FIXME: Should I be in yet another thread? Action perform = null; if (msg.signature != "u" && msg.signature != "s") { //accept 's' signatures for Perl DBus, which is stupid and can't //send me 'u' parameters, even though the api accepts them. log.print(WvLog.L.Debug4, "CancelQuery: bad signature {0}\n", msg.signature); perform = () => { conn.send(msg.err_reply( "org.freedesktop.DBus.Error.UnknownMethod", "No overload of {0} has signature '{1}'", "CancelQuery", msg.signature)); }; } else { var it = msg.iter(); uint tokill; if (msg.signature == "s") { log.print(WvLog.L.Debug4, "CancelQuery: converting arg from string\n"); string temps = it.pop(); tokill = Convert.ToUInt32(temps); } else tokill = it.pop(); log.print(WvLog.L.Debug4, "CancelQuery: try killing msg id {0}\n", tokill); lock (action_mutex) { if (curaction != null && curaction.conn == conn && curaction.src.serial == tokill) { log.print(WvLog.L.Debug4, "CancelQuery: killing current action!\n"); WvSqlRows_IDataReader.Cancel(); curaction = null; } else { log.print(WvLog.L.Debug4, "CancelQuery: traversing action queue...\n"); //Traverse the action queue, killing stuff foreach (VxActionTriple t in action_queue) if (t.conn == conn && t.src.serial == tokill) { log.print(WvLog.L.Debug4, "CancelQuery: found culprit, killing.\n"); //action_queue.Remove(t); //FIXME: What message should we really put here? t.action = () => { conn.send(t.src.err_reply("vx.db.sqlerror", "This message got canceled")); }; break; } } } //Pointless return to make Perl happy. perform = () => { WvDbusWriter writer = new WvDbusWriter(); writer.Write("Cancel"); conn.send(msg.reply("s").write(writer)); }; log.print(WvLog.L.Debug4, "CancelQuery: complete\n"); } //FIXME: It's not clear whether for just add operations, in conjuction //with RemoveAt(0) going on in the otherthread, we need a mutex. action_queue.Add(new VxActionTriple(conn, msg, perform)); }
internal static void ExecChunkRecordset(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { string connid = VxDbusRouter.GetClientId(call); if (connid == null) { reply = call.err_reply( "org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string query = query_parser(it.pop(), VxSqlPool.access_restrictions(connid)); log.print(WvLog.L.Debug3, "ExecChunkRecordset {0}\n", query); //Times we tried going through this loop to completion int numtries = 0; while (true) { try { List<object[]> rows = new List<object[]>(); List<byte[]> rownulls = new List<byte[]>(); VxColumnInfo[] colinfo; // Our size here is just an approximation. int cursize = 0; // FIXME: Sadly, this is stupidly similar to ExecRecordset. // Anything we can do here to identify commonalities? using (var dbi = VxSqlPool.create(connid)) using (WvSqlRows resultset = dbi.select(query)) { var columns = resultset.columns.ToArray(); colinfo = ProcessSchema(columns); int ncols = columns.Count(); foreach (WvSqlRow cur_row in resultset) { object[] row = new object[ncols]; byte[] rownull = new byte[ncols]; cursize += rownull.Length; for (int i = 0; i < ncols; i++) { WvAutoCast cval = cur_row[i]; bool isnull = cval.IsNull; row[i] = null; rownull[i] = isnull ? (byte)1 : (byte)0; switch (colinfo[i].VxColumnType) { case VxColumnType.Int64: row[i] = !isnull ? (Int64)cval : new Int64(); cursize += sizeof(Int64); break; case VxColumnType.Int32: row[i] = !isnull ? (Int32)cval : new Int32(); cursize += sizeof(Int32); break; case VxColumnType.Int16: row[i] = !isnull ? (Int16)cval : new Int16(); cursize += sizeof(Int16); break; case VxColumnType.UInt8: row[i] = !isnull ? (Byte)cval : new Byte(); cursize += sizeof(Byte); break; case VxColumnType.Bool: row[i] = !isnull ? (bool)cval : new Boolean(); cursize += sizeof(Boolean); break; case VxColumnType.Double: // Might return a Single or Double // FIXME: Check if getting a single causes // this to croak row[i] = !isnull ? (double)cval : (double)0.0; cursize += sizeof(double); break; case VxColumnType.Uuid: //FIXME: Do I work? row[i] = !isnull ? (string)cval : ""; cursize += !isnull ? ((string)cval).Length * sizeof(Char):0; break; case VxColumnType.Binary: { if (isnull) { row[i] = new byte[0]; break; } row[i] = (byte[])cval; cursize += ((byte[])cval).Length; break; } case VxColumnType.String: row[i] = !isnull ? (string)cval : ""; cursize += !isnull ? ((string)cval).Length * sizeof(Char):0; break; case VxColumnType.DateTime: row[i] = !isnull ? new VxDbusDateTime((DateTime)cval) : new VxDbusDateTime(); cursize += System.Runtime.InteropServices.Marshal.SizeOf((VxDbusDateTime)row[i]); break; case VxColumnType.Decimal: row[i] = !isnull ? ((Decimal)cval).ToString() : ""; cursize += ((string)(row[i])).Length * sizeof(Char); break; } } // column iterator rows.Add(row); rownulls.Add(rownull); if (cursize >= 1024*1024) //approx 1 MB { log.print(WvLog.L.Debug4, "(1 MB reached; {0} rows)\n", rows.Count); SendChunkRecordSignal(conn, call, call.sender, colinfo, rows.ToArray(), rownulls.ToArray()); rows = new List<object[]>(); rownulls = new List<byte[]>(); cursize = 0; } } // row iterator } // using // OK, we're down to either one more packet or no more data // Package that up in the 'reply' to this message, saving some // data being sent. if (cursize > 0) log.print(WvLog.L.Debug4, "(Remaining data; {0} rows)\n", rows.Count); // Create reply, either with or with no data WvDbusWriter replywriter = VxDbusRouter.PrepareRecordsetWriter(colinfo, rows.ToArray(), rownulls.ToArray()); reply = call.reply("a(issnny)vaay").write(replywriter); break; } catch (DbException e) { throw new VxSqlException(e.Message, e); } catch (VxConfigException e) { if (e.Message.StartsWith("Connect: A network-related or instance-specific error") && ++numtries <= 1) //only one retry { log.print(WvLog.L.Debug4, "Can't connect to DB, fishy..., attempting to reconnect... (attempt #{0})\n", numtries); } else throw e; //rethrow } } //while }
static void CallExecScalar(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "s") { reply = CreateUnknownMethodReply(call, "ExecScalar"); return; } if (call.Body == null) { reply = call.err_reply ("org.freedesktop.DBus.Error.InvalidSignature", "Signature provided but no body received"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string query = it.pop(); object result; VxColumnType coltype; VxDb.ExecScalar(clientid, (string)query, out coltype, out result); WvDbusWriter writer = new WvDbusWriter(); writer.WriteSig(VxColumnTypeToSignature(coltype)); WriteV(writer, coltype, result); reply = call.reply("v").write(writer); }
static void CallPutSchemaData(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "ss") { reply = CreateUnknownMethodReply(call, "PutSchemaData"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string tablename = it.pop(); string text = it.pop(); using (var dbi = VxSqlPool.create(clientid)) { VxDbSchema backend = new VxDbSchema(dbi); backend.PutSchemaData(tablename, text, 0); } reply = call.reply(); }
static void CallGetSchemaData(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "ss") { reply = CreateUnknownMethodReply(call, "GetSchemaData"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string tablename = it.pop(); string where = it.pop(); WvDbusWriter writer = new WvDbusWriter(); // FIXME: No exception catching? // FIXME: Should receive the replace/skip parameters via dbus using (var dbi = VxSqlPool.create(clientid)) { VxDbSchema backend = new VxDbSchema(dbi); string schemadata = backend.GetSchemaData(tablename, 0, where, null, null); writer.Write(schemadata); } reply = call.reply("s").write(writer); }
static void CallPutSchema(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != String.Format("{0}i", VxSchema.GetDbusSignature())) { reply = CreateUnknownMethodReply(call, "PutSchema"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); VxSchema schema = new VxSchema(it.pop()); int opts = it.pop(); VxSchemaErrors errs; using (var dbi = VxSqlPool.create(clientid)) { VxDbSchema backend = new VxDbSchema(dbi); errs = backend.Put(schema, null, (VxPutOpts)opts); } WvDbusWriter writer = new WvDbusWriter(); VxSchemaErrors.WriteErrors(writer, errs); reply = call.reply(VxSchemaErrors.GetDbusSignature()).write(writer); if (errs != null && errs.Count > 0) { reply.type = Wv.Dbus.MType.Error; reply.err = "org.freedesktop.DBus.Error.Failed"; } }
static void CallDropSchema(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "as") { reply = CreateUnknownMethodReply(call, "DropSchema"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string[] keys = it.pop().Cast<string>().ToArray(); VxSchemaErrors errs; using (var dbi = VxSqlPool.create(clientid)) { VxDbSchema backend = new VxDbSchema(dbi); errs = backend.DropSchema(keys); } WvDbusWriter writer = new WvDbusWriter(); VxSchemaErrors.WriteErrors(writer, errs); reply = call.reply(VxSchemaErrors.GetDbusSignature()).write(writer); if (errs != null && errs.Count > 0) { reply.type = Wv.Dbus.MType.Error; reply.err = "org.freedesktop.DBus.Error.Failed"; } }
static void CallGetSchema(WvDbus conn, WvDbusMsg call, out WvDbusMsg reply) { if (call.signature != "as") { reply = CreateUnknownMethodReply(call, "GetSchema"); return; } string clientid = GetClientId(call); if (clientid == null) { reply = call.err_reply("org.freedesktop.DBus.Error.Failed", "Could not identify the client"); return; } var it = call.iter(); string[] names = it.pop().Cast<string>().ToArray(); WvDbusWriter writer = new WvDbusWriter(); using (var dbi = VxSqlPool.create(clientid)) { VxDbSchema backend = new VxDbSchema(dbi); VxSchema schema = backend.Get(names); schema.WriteSchema(writer); } reply = call.reply(VxSchema.GetDbusSignature()).write(writer); }