internal static void SendChunkRecordSignal(WvDbus conn, WvDbusMsg call, string sender, VxColumnInfo[] colinfo, object[][] data, byte[][] nulls) { WvDbusWriter writer = VxDbusRouter.PrepareRecordsetWriter(colinfo, data, nulls); writer.Write(call.serial); new WvDbusSignal(call.sender, call.path, "vx.db", "ChunkRecordsetSig", "a(issnny)vaayu") .write(writer) .send(conn); }
static string VxColumnInfoToArraySignature(VxColumnInfo[] vxci) { StringBuilder sig = new StringBuilder("a("); foreach (VxColumnInfo ci in vxci) sig.Append(VxColumnTypeToSignature(ci.VxColumnType)); sig.Append(")"); return sig.ToString(); }
static void WriteColInfo(WvDbusWriter writer, VxColumnInfo[] colinfo) { // a(issnny) writer.WriteArray(8, colinfo, (w2, i) => { w2.Write(i.size); w2.Write(i.colname); w2.Write(i.coltype.ToString()); w2.Write(i.precision); w2.Write(i.scale); w2.Write(i.nullable); }); }
private static VxColumnInfo[] ProcessSchema(IEnumerable<WvColInfo> columns) { // FIXME: This is stupidly similar to ProcessSchema int ncols = columns.Count(); VxColumnInfo[] colinfo = new VxColumnInfo[ncols]; if (ncols <= 0) return colinfo; int i = 0; foreach (WvColInfo col in columns) { System.Type type = col.type; if (type == typeof(object)) { // We're not even going to try to handle this yet throw new VxBadSchemaException("Columns of type sql_variant " + "are not supported by Versaplex at this time"); } VxColumnType coltype; if (type == typeof(Int64)) { coltype = VxColumnType.Int64; } else if (type == typeof(Int32)) { coltype = VxColumnType.Int32; } else if (type == typeof(Int16)) { coltype = VxColumnType.Int16; } else if (type == typeof(Byte)) { coltype = VxColumnType.UInt8; } else if (type == typeof(Boolean)) { coltype = VxColumnType.Bool; } else if (type == typeof(Single) || type == typeof(Double)) { coltype = VxColumnType.Double; } else if (type == typeof(Guid)) { coltype = VxColumnType.Uuid; } else if (type == typeof(Byte[])) { coltype = VxColumnType.Binary; } else if (type == typeof(string)) { coltype = VxColumnType.String; } else if (type == typeof(DateTime)) { coltype = VxColumnType.DateTime; } else if (type == typeof(Decimal)) { coltype = VxColumnType.Decimal; } else { throw new VxBadSchemaException("Columns of type " + type.ToString() + " are not supported by " + "Versaplex at this time " + "(column " + col.name + ")"); } colinfo[i] = new VxColumnInfo(col.name, coltype, col.nullable, col.size, col.precision, col.scale); i++; } return colinfo; }
internal static void ExecRecordset(string connid, string query, out VxColumnInfo[] colinfo, out object[][] data, out byte[][] nullity) { query = query_parser(query, VxSqlPool.access_restrictions(connid)); log.print(WvLog.L.Debug3, "ExecRecordset {0}\n", query); try { List<object[]> rows = new List<object[]>(); List<byte[]> rownulls = new List<byte[]>(); using (var dbi = VxSqlPool.create(connid)) using (var result = dbi.select(query)) { var columns = result.columns.ToArray(); if (columns.Length <= 0) log.print("No columns in resulting data set."); colinfo = ProcessSchema(result.columns); foreach (var r in result) { object[] row = new object[columns.Length]; byte[] rownull = new byte[columns.Length]; for (int i = 0; i < columns.Length; i++) { bool isnull = r[i].IsNull; row[i] = null; rownull[i] = isnull ? (byte)1 : (byte)0; switch (colinfo[i].VxColumnType) { case VxColumnType.Int64: row[i] = !isnull ? (Int64)r[i] : new Int64(); break; case VxColumnType.Int32: row[i] = !isnull ? (Int32)r[i] : new Int32(); break; case VxColumnType.Int16: row[i] = !isnull ? (Int16)r[i] : new Int16(); break; case VxColumnType.UInt8: row[i] = !isnull ? (Byte)r[i] : new Byte(); break; case VxColumnType.Bool: row[i] = !isnull ? (bool)r[i] : new 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)r[i] : (double)0.0; break; case VxColumnType.Uuid: row[i] = !isnull ? ((Guid)r[i]).ToString() : ""; break; case VxColumnType.Binary: row[i] = !isnull ? (byte[])r[i] : new byte[0]; break; case VxColumnType.String: row[i] = !isnull ? (string)r[i] : ""; break; case VxColumnType.DateTime: row[i] = !isnull ? new VxDbusDateTime(r[i]) : new VxDbusDateTime(); break; case VxColumnType.Decimal: row[i] = !isnull ? ((decimal)r[i]).ToString() : ""; break; } } rows.Add(row); rownulls.Add(rownull); } } data = rows.ToArray(); nullity = rownulls.ToArray(); log.print(WvLog.L.Debug4, "({0} rows)\n", data.Length); wv.assert(nullity.Length == data.Length); } catch (DbException e) { throw new VxSqlException(e.Message, e); } }
// a(issnny)vaay public static WvDbusWriter PrepareRecordsetWriter(VxColumnInfo[] colinfo, object[][] data, byte[][] nulldata) { WvDbusWriter writer = new WvDbusWriter(); // a(issnny) WriteColInfo(writer, colinfo); // v if (colinfo.Length <= 0) { // Some clients can't parse a() (empty struct) properly, so // we'll have an empty array of (i) instead. writer.WriteSig("a(i)"); } else writer.WriteSig(VxColumnInfoToArraySignature(colinfo)); // a(whatever) writer.WriteArray(8, data, (w2, r) => { for (int i = 0; i < colinfo.Length; i++) WriteV(w2, colinfo[i].VxColumnType, r[i]); }); // aay writer.WriteArray(4, nulldata, (w2, r) => { w2.Write(r); }); return writer; }