2 #include "wvistreamlist.h"
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
);
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());
49 // Sadly there's no better way to get the number of columns
50 for (num_cols
= 0; colinfo
.next(); ++num_cols
) { }
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
,
82 WvDBusMsg
msg("vx.versaplexd", "/db", "vx.db", func
);
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));
97 mylog("DBus error: '%s'\n", ((WvString
)reply
).cstr());
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
)
110 rs
._runquery(dbus(), func
, query
);
113 ConnectionClass
*conn
= SC_get_conn(stmt
);
114 ConnInfo
*ci
= &conn
->connInfo
;
115 mylog("DBus connection died! Reconnecting to %s\n",
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");
147 //for (int i = 1; i < my_cols; ++i)
148 // set_tuplefield_string(&tuple[i], NULL);