iter() 공개 메소드

public iter ( ) : WvDbusIter
리턴 WvDbusIter
예제 #1
0
    private void confirmfail(WvDbusMsg response)
    {
	WVPASS(response.type = Wv.Dbus.MType.Error);
	WVPASS(response.signature = "s");
	var i = response.iter();
	WVPASSEQ(i.pop(), failmsg);
    }
예제 #2
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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);
    }
예제 #3
0
    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));
    }
예제 #4
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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
    }
예제 #5
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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);
    }
예제 #6
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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();
    }
예제 #7
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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);
    }
예제 #8
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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";
        }
    }
예제 #9
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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";
        }
    }
예제 #10
0
파일: vxapi.cs 프로젝트: apenwarr/versaplex
    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);
    }