cli.cpp

来自「一个功能强大的内存数据库源代码,c++编写,有详细的注释」· C++ 代码 · 共 1,213 行 · 第 1/3 页

CPP
1,213
字号
	    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_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);	    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_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, int n = 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;	int4        n;    } get;    int length = sizeof(cli_request);    if (cmd == cli_cmd_skip) { 	length += 4;	get.n = n;	pack4(get.n);    }    get.req.length  = sizeof(cli_request);    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;    }    dbSmallBuffer buf(response-4);    if (!s->session->sock->read(buf, response-4)) { 	return cli_network_error;    }    char* p = buf;    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);            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 { 		switch (sizeof_type[cb->var_type]) { 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?