Merge commit 'origin/master'
[versaplex.git] / vxodbc / vxhelpers.cc
blob3d5403ed91397c10a9dbad246778974bf5e51c0b
1 #include "vxhelpers.h"
2 #include "wvistreamlist.h"
3 #include <list>
5 static std::map<unsigned int, VxResultSet *> signal_returns;
7 static void update_sigrets(unsigned int key, VxResultSet *value)
9 signal_returns[key] = value;
12 static bool signal_sorter(WvDBusMsg &msg)
14 WvString member = msg.get_member();
15 // We have a signal, and it's a signal carrying data we want!
16 if (!!member && member == "ChunkRecordsetSig")
18 WvDBusMsg::Iter top(msg);
19 unsigned int reply_serial =
20 (unsigned int)top.getnext().getnext().getnext().getnext().get_int();
21 if (signal_returns[reply_serial])
23 signal_returns[reply_serial]->process_msg(msg);
24 return true;
28 return false;
31 static std::map<WvDBusConn *, bool> callbacked_conns;
33 static void erase_conn(WvStream &s)
35 WvDBusConn *c = (WvDBusConn *)&s;
36 callbacked_conns.erase(c);
39 void VxResultSet::process_msg(WvDBusMsg &msg)
41 WvDBusMsg::Iter top(msg);
42 WvDBusMsg::Iter colinfo(top.getnext().open());
43 WvDBusMsg::Iter data(top.getnext().open().getnext().open());
44 WvDBusMsg::Iter flags(top.getnext().open());
46 if (process_colinfo)
48 int num_cols;
49 // Sadly there's no better way to get the number of columns
50 for (num_cols = 0; colinfo.next(); ++num_cols) { }
51 colinfo.rewind();
52 // Allocate space for the column info data.
53 QR_set_num_fields(res, num_cols);
54 maxcol = num_cols - 1;
56 for (int colnum = 0; colinfo.next(); ++colnum)
58 WvDBusMsg::Iter i(colinfo.open());
60 int colsize = i.getnext();
61 WvString colname = i.getnext();
62 int coltype = vxtype_to_pgtype(i.getnext());
64 set_field_info(colnum, colname, coltype, colsize);
66 process_colinfo = false;
69 for (data.rewind(); data.next(); )
71 TupleField *tuple = QR_AddNew(res);
73 WvDBusMsg::Iter cols(data.open());
74 for (int colnum = 0; cols.next() && colnum < numcols(); colnum++)
75 set_tuplefield_string(&tuple[colnum], *cols);
79 void VxResultSet::_runquery(WvDBusConn &conn, const char *func,
80 const char *query)
82 WvDBusMsg msg("vx.versaplexd", "/db", "vx.db", func);
83 msg.append(query);
84 if (!callbacked_conns[&conn])
86 conn.add_callback(WvDBusConn::PriNormal, signal_sorter);
87 conn.setclosecallback(wv::bind(&erase_conn, wv::ref(conn)));
88 callbacked_conns[&conn] = true;
90 process_colinfo = true;
91 while (WvIStreamList::globallist.select(0))
92 WvIStreamList::globallist.callback();
93 WvDBusMsg reply = conn.send_and_wait(msg, 50000,
94 wv::bind(&update_sigrets, _1, this));
96 if (reply.iserror())
97 mylog("DBus error: '%s'\n", ((WvString)reply).cstr());
98 else // Method return
99 process_msg(reply);
101 uint32_t reply_serial = reply.get_replyserial();
102 if (signal_returns[reply_serial])
103 signal_returns.erase(reply_serial);
106 void VxStatement::runquery(VxResultSet &rs,
107 const char *func, const char *query)
109 if (dbus().isok())
110 rs._runquery(dbus(), func, query);
111 if (!dbus().isok())
113 ConnectionClass *conn = SC_get_conn(stmt);
114 ConnInfo *ci = &conn->connInfo;
115 mylog("DBus connection died! Reconnecting to %s\n",
116 ci->dbus_moniker);
117 conn->dbus = new WvDBusConn(ci->dbus_moniker);
118 rs._runquery(dbus(), func, query);
122 void VxResultSet::return_versaplex_db()
124 // Allocate space for the column info data... see below.
125 // const int my_cols = 5;
126 const int my_cols = 1;
127 QR_set_num_fields(res, my_cols);
128 maxcol = my_cols - 1;
130 // Column info... the names and types of the columns here were stolen from
131 // tracing the result of a 'list tables' call to the server.
132 set_field_info(0, "TABLE_QUALIFIER", 1043, 128);
133 //FIXME: The below 4 are commented out, because StarQuery happens to work
134 // with only one return column. Will other applications that also
135 // expect some kind of standard reply to what catalogs are available?
136 //set_field_info(1, "TABLE_OWNER", 1043, 128);
137 //set_field_info(2, "TABLE_NAME", 1043, 128);
138 //set_field_info(3, "TABLE_TYPE", 1043, 32);
139 //set_field_info(4, "REMARKS", 1043, 254);
141 // set up fake data, just one row, with the TABLE_QUALIFIER being
142 // a fake '__VERSAPLEX' database, and the rest of the columns being null.
143 TupleField *tuple = QR_AddNew(res);
145 set_tuplefield_string(&tuple[0], "__VERSAPLEX");
146 //FIXME: See above.
147 //for (int i = 1; i < my_cols; ++i)
148 // set_tuplefield_string(&tuple[i], NULL);