* Send an SQL query to the server */
| 216 | * Send an SQL query to the server |
| 217 | */ |
| 218 | static int db_oracle_submit_query(const db_con_t* _h, const str* _s) |
| 219 | { |
| 220 | OCIBind* bind[MAX_BIND_HANDLES]; |
| 221 | OCIDate odt[sizeof(bind)/sizeof(bind[0])]; |
| 222 | str tmps; |
| 223 | sword status; |
| 224 | int pass; |
| 225 | ora_con_t* con = CON_ORA(_h); |
| 226 | query_data_t* pqd = con->pqdata; |
| 227 | size_t hc = pqd->_n + pqd->_nw; |
| 228 | OCIStmt *stmthp; |
| 229 | |
| 230 | if (hc >= sizeof(bind)/sizeof(bind[0])) { |
| 231 | LM_ERR("too many bound. Rebuild with MAX_BIND_HANDLES >= %u\n", |
| 232 | (unsigned)hc); |
| 233 | return -1; |
| 234 | } |
| 235 | |
| 236 | if (!pqd->_rs) { |
| 237 | /* |
| 238 | * This method is at ~25% faster as set OCI_COMMIT_ON_SUCCESS |
| 239 | * in StmtExecute |
| 240 | */ |
| 241 | tmps.len = snprintf(st_buf, sizeof(st_buf), |
| 242 | "begin %.*s; commit write batch nowait; end;", |
| 243 | _s->len, _s->s); |
| 244 | if ((unsigned)tmps.len >= sizeof(st_buf)) |
| 245 | return sql_buf_small(); |
| 246 | tmps.s = st_buf; |
| 247 | _s = &tmps; |
| 248 | } |
| 249 | |
| 250 | pass = 1; |
| 251 | if (!con->connected) { |
| 252 | status = db_oracle_reconnect(con); |
| 253 | if (status != OCI_SUCCESS) { |
| 254 | LM_ERR("can't restore connection: %s\n", db_oracle_error(con, status)); |
| 255 | return -2; |
| 256 | } |
| 257 | LM_INFO("connection restored\n"); |
| 258 | --pass; |
| 259 | } |
| 260 | repeat: |
| 261 | stmthp = NULL; |
| 262 | status = OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&stmthp, |
| 263 | OCI_HTYPE_STMT, 0, NULL); |
| 264 | if (status != OCI_SUCCESS) |
| 265 | goto ora_err; |
| 266 | status = OCIStmtPrepare(stmthp, con->errhp, (text*)_s->s, _s->len, |
| 267 | OCI_NTV_SYNTAX, OCI_DEFAULT); |
| 268 | if (status != OCI_SUCCESS) |
| 269 | goto ora_err; |
| 270 | |
| 271 | if (hc) { |
| 272 | bmap_t bmap; |
| 273 | size_t pos = 1; |
| 274 | int i; |
| 275 |
nothing calls this directly
no test coverage detected