📄 cli.cpp
字号:
while ((*p++ = *src++) != '\0'); if (pb != NULL) { *p++ = pb->var_type == cli_pasciiz ? cli_asciiz : pb->var_type; pb = pb->next; } } for (cb = stmt->columns; cb != NULL; cb = cb->next) { *p++ = cb->var_type; s = cb->name; while ((*p++ = *s++) != '\0'); } } *p++ = for_update; for (pb = stmt->params; pb != NULL; pb = pb->next) { switch (pb->var_type) { case cli_asciiz: s = (char*)pb->var_ptr; while ((*p++ = *s++) != '\0'); continue; case cli_rectangle: p = pack_rectangle(p, (cli_rectangle_t*)pb->var_ptr); continue; case cli_pasciiz: s = *(char**)pb->var_ptr; while ((*p++ = *s++) != '\0'); continue; default: switch (sizeof_type[pb->var_type]) { case 1: *p++ = *(char*)pb->var_ptr; continue; case 2: p = pack2(p, *(int2*)pb->var_ptr); continue; case 4: p = pack4(p, *(int4*)pb->var_ptr); continue; case 8: p = pack8(p, *(db_int8*)pb->var_ptr); continue; } } } assert(msg_size == p - buf.base()); if (!stmt->session->sock->write(buf, msg_size)) { return cli_network_error; } int4 response; if (!stmt->session->sock->read(&response, sizeof response)) { return cli_network_error; } unpack4(response); if (response >= 0) { stmt->prepared = true; } return response;}static int cli_send_columns(int statement, int cmd){ statement_desc* s = statements.get(statement); column_binding* cb; if (s == NULL) { return cli_bad_descriptor; } long msg_size = sizeof(cli_request); if (cmd == cli_cmd_update) { if (!s->prepared) { return cli_not_fetched; } if (s->oid == 0) { return cli_not_found; } if (s->updated) { return cli_already_updated; } if (!s->for_update) { return cli_not_update_mode; } } else { if (!s->prepared) { cmd = cli_cmd_prepare_and_insert; msg_size += 1 + s->stmt_len + s->n_columns + s->columns_len; } } s->autoincrement = false; for (cb = s->columns; cb != NULL; cb = cb->next) { if (cb->get_fnc != NULL) { cb->arr_ptr = cb->get_fnc(cb->var_type, cb->var_ptr, &cb->arr_len, cb->name, statement, cb->user_data); int len = cb->arr_len; msg_size += 4; if (cb->var_type == cli_array_of_string) { char** p = (char**)cb->arr_ptr; while (--len >= 0) { msg_size += strlen(*p++) + 1; } } else if (cb->var_type >= cli_array_of_oid) { msg_size += len * sizeof_type[cb->var_type - cli_array_of_oid]; } else { msg_size += len; } } else { if (cb->var_type == cli_asciiz) { msg_size += 4 + strlen((char*)cb->var_ptr) + 1; } else if (cb->var_type == cli_pasciiz) { msg_size += 4 + strlen(*(char**)cb->var_ptr) + 1; } else if (cb->var_type == cli_autoincrement) { s->autoincrement = true; } else if (cb->var_type == cli_array_of_string) { char** p = (char**)cb->var_ptr; msg_size += 4; for (int len = *cb->var_len; --len >= 0;) { msg_size += strlen(*p++) + 1; } } else if (cb->var_type >= cli_array_of_oid) { msg_size += 4 + *cb->var_len * sizeof_type[cb->var_type-cli_array_of_oid]; } else { msg_size += sizeof_type[cb->var_type]; } } } dbSmallBuffer buf(msg_size); char* p = buf; cli_request* req = (cli_request*)p; req->length = msg_size; req->cmd = cmd; req->stmt_id = statement; req->pack(); p += sizeof(cli_request); if (cmd == cli_cmd_prepare_and_insert) { char* cmd = s->stmt; while ((*p++ = *cmd++) != '\0'); *p++ = s->n_columns; for (cb = s->columns; cb != NULL; cb = cb->next) { char* src = cb->name; *p++ = cb->var_type; while ((*p++ = *src++) != '\0'); } } for (cb = s->columns; cb != NULL; cb = cb->next) { int n = 0; char* src; if (cb->get_fnc != NULL) { src = (char*)cb->arr_ptr; n = cb->arr_len; } else { src = (char*)cb->var_ptr; if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8) { n = *cb->var_len; } } if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8) { p = pack4(p, n); if (cb->var_type == cli_array_of_string) { while (--n >= 0) { strcpy(p, *(char**)src); p += strlen(p) + 1; src += sizeof(char*); } } else { switch (sizeof_type[cb->var_type-cli_array_of_oid]) { case 2: while (--n >= 0) { p = pack2(p, src); src += 2; } break; case 4: while (--n >= 0) { p = pack4(p, src); src += 4; } break; case 8: while (--n >= 0) { p = pack8(p, src); src += 8; } break; default: memcpy(p, src, n); p += n; } } } else if (cb->var_type == cli_asciiz) { p = pack4(p, strlen(src)+1); while ((*p++ = *src++) != 0); } else if (cb->var_type == cli_pasciiz) { src = *(char**)src; p = pack4(p, strlen(src)+1); while ((*p++ = *src++) != 0); } else if (cb->var_type == cli_rectangle) { p = pack_rectangle(p, (cli_rectangle_t*)src); } else if (cb->var_type != cli_autoincrement) { switch (sizeof_type[cb->var_type]) { case 2: p = pack2(p, src); break; case 4: p = pack4(p, src); break; case 8: p = pack8(p, src); break; default: *p++ = *src; } } } assert(p - buf.base() == msg_size); if (!s->session->sock->write(buf, msg_size)) { return cli_network_error; } return cli_ok;}int cli_insert(int statement, cli_oid_t* oid){ int rc = cli_send_columns(statement, cli_cmd_insert); if (rc == cli_ok) { char buf[sizeof(cli_oid_t) + 8]; statement_desc* s = statements.get(statement); if (!s->session->sock->read(buf, sizeof buf)) { rc = cli_network_error; } else { rc = unpack4(buf); s->prepared = true; s->oid = unpack_oid(buf + 8); if (oid != NULL) { *oid = s->oid; } if (s->autoincrement) { int4 rowid = unpack4(buf + 4); for (column_binding* cb = s->columns; cb != NULL; cb = cb->next) { if (cb->var_type == cli_autoincrement) { *(int4*)cb->var_ptr = rowid; } } } } } return rc;}int cli_update(int statement){ int rc = cli_send_columns(statement, cli_cmd_update); if (rc == cli_ok) { int4 response; statement_desc* s = statements.get(statement); s->updated = true; if (!s->session->sock->read(&response, sizeof response)) { rc = cli_network_error; } else { unpack4(response); rc = response; } } return rc; }static int cli_get(int statement, int cmd, cli_oid_t value = 0){ statement_desc* s = statements.get(statement); if (s == NULL) { return cli_bad_descriptor; } if (!s->prepared) { return cli_not_fetched; } struct get_req { cli_request req; cli_oid_t value; } get; int length = sizeof(cli_request); if (cmd == cli_cmd_skip) { length += 4; pack4((char*)(&get.req+1), (int)value); } else if (cmd == cli_cmd_seek) { length += sizeof(cli_oid_t); pack_oid((char*)(&get.req+1), value); } get.req.length = length; get.req.cmd = cmd; get.req.stmt_id = statement; get.req.pack(); if (!s->session->sock->write(&get.req, length)) { return cli_network_error; } int4 response; if (!s->session->sock->read(&response, sizeof response)) { return cli_network_error; } unpack4(response); if (response <= 0) { return response; } if (s->buf_size < (size_t)response-4) { delete[] s->buf; s->buf_size = response-4 < DEFAULT_BUF_SIZE ? DEFAULT_BUF_SIZE : response-4; s->buf = new char[s->buf_size]; } char* buf = s->buf; if (!s->session->sock->read(buf, response-4)) { return cli_network_error; } char* p = buf; int result = cli_ok; if (cmd == cli_cmd_seek) { s->oid = value; result = unpack_oid(p); } else { s->oid = unpack_oid(p); if (s->oid == 0) { return cli_not_found; } } p += sizeof(cli_oid_t); for (column_binding* cb = s->columns; cb != NULL; cb = cb->next) { if (cb->set_fnc != NULL) { int len = unpack4(p); p += 4; char* dst = (char*)cb->set_fnc(cb->var_type, cb->var_ptr, len, cb->name, statement, p, cb->user_data); if (dst == NULL) { continue; } if (cb->var_type == cli_array_of_string) { char** s = (char**)dst; while (--len >= 0) { *s++ = p; p += strlen(p) + 1; } } else if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8) { switch (sizeof_type[cb->var_type-cli_array_of_oid]) { case 2: while (--len >= 0) { p = unpack2(dst, p); dst += 2; } break; case 4: while (--len >= 0) { p = unpack4(dst, p); dst += 4; } break; case 8: while (--len >= 0) { p = unpack8(dst, p); dst += 8; } break; default: memcpy(dst, p, len); p += len; } } else { memcpy(dst, p, len); p += len; } } else { if (cb->var_type >= cli_asciiz && cb->var_type <= cli_array_of_string) { int len = unpack4(p); p += 4; char* dst = (char*)cb->var_ptr; char* src = p; int n = len; if (cb->var_len != NULL) { if (n > *cb->var_len) { n = *cb->var_len; } *cb->var_len = n; } if (cb->var_type >= cli_array_of_oid) { if (cb->var_type == cli_array_of_string) { char** s = (char**)dst; len -= n; while (--n >= 0) { *s++ = p; p += strlen(p) + 1; } while (--len >= 0) { p += strlen(p) + 1; } } else { switch (sizeof_type[cb->var_type-cli_array_of_oid]) { case 2: while (--n >= 0) { src = unpack2(dst, src); dst += 2; } p += len*2; break; case 4: while (--n >= 0) { src = unpack4(dst, src); dst += 4; } p += len*4; break; case 8: while (--n >= 0) { src = unpack8(dst, src); dst += 8; } p += len*8; break; default: memcpy(dst, p, n); p += len; } } } else { if (cb->var_type == cli_pasciiz) { dst = *(char**)dst; } memcpy(dst, p, n); p += len; } } else if (cb->var_type == cli_rectangle) { p = unpack_rectangle((cli_rectangle_t*)cb->var_ptr, p); } else { switch (sizeof_type[cb->var_type]) { case 2: p = unpack2((char*)cb->var_ptr, p); break; case 4: p = unpack4((char*)cb->var_ptr, p); break; case 8: p = unpack8((char*)cb->var_ptr, p); break; default: *(char*)cb->var_ptr = *p++; } } } } s->updated = false; return result;}int cli_get_first(int statement){ return cli_get(statement, cli_cmd_get_first);}int cli_get_last(int statement){ return cli_get(statement, cli_cmd_get_last);}int cli_get_next(int statement){ return cli_get(statement, cli_cmd_get_next);}int cli_get_prev(int statement){ return cli_get(statement, cli_cmd_get_prev);}int cli_skip(int statement, int n)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -