⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cli.cpp

📁 实现内存数据库的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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;
	    if (cb->var_type >= cli_array_of_oid) { 
		len *= sizeof_type[cb->var_type - cli_array_of_oid];
	    }
	    msg_size += 4 + 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_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);
	    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)
{
    statement_desc* s = statements.get(statement);
    if (s == NULL) { 
	return cli_bad_descriptor;
    }
    if (!s->prepared) { 
	return cli_not_fetched;
    }
    cli_request req;
    req.length  = sizeof(cli_request);
    req.cmd     = cmd;
    req.stmt_id = statement;
    req.pack();
    if (!s->session->sock->write(&req, sizeof req)) { 
	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);
	    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) { 
		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) { 
		    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]) { 
		  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 cli_ok;
}

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);
}

cli_oid_t cli_get_oid(int statement)
{
    statement_desc* s = statements.get(statement);
    if (s == NULL) { 
	return 0;
    }
    return s->oid;
}


static int cli_send_command(int session, int statement, int cmd)
{
    session_desc* s = sessions.get(session);
    if (s == NULL) { 
	return cli_bad_descriptor;
    }	
    cli_request req;
    req.length  = sizeof(cli_request);
    req.cmd     = cmd;
    req.stmt_id = statement;
    req.pack();
    if (!s->sock->write(&req, sizeof req)) { 
	return cli_network_error;
    }
    int4 response;
    if (!s->sock->read(&response, sizeof response)) { 
	return cli_network_error;
    }
    unpack4(response);
    return response;
}

int cli_free(int statement)
{
    statement_desc* stmt = statements.get(statement);
    session_desc* s = stmt->session;
    if (s == NULL) { 
	return cli_bad_descriptor;
    }	
    statement_desc *sp, **spp = &s->stmts; 
    while ((sp = *spp) != stmt) { 
	if (sp == NULL) { 
	    return cli_bad_descriptor;
	}
	spp = &sp->next;
    }
    *spp = stmt->next;
    stmt->deallocate();
    statements.deallocate(stmt);
    cli_request req;
    req.length  = sizeof(cli_request);
    req.cmd     = cli_cmd_free_statement;
    req.stmt_id = statement;
    req.pack();
    if (!s->sock->write(&req, sizeof req)) { 
	return cli_network_error;
    }
    return cli_ok;
}
    

int cli_commit(int session)
{
    return cli_send_command(session, 0, cli_cmd_commit);
}

int cli_abort(int session)
{
    return cli_send_command(session, 0, cli_cmd_abort);
}

int cli_remove(int statement)
{
    statement_desc* s = statements.get(statement);
    if (s == NULL) { 
	return cli_bad_descriptor;
    }
    if (s->oid == 0) { 
	return cli_not_found;
    }
    if (!s->for_update) { 
	return cli_not_update_mode;
    }
    return cli_send_command(s->session->id, s->id, cli_cmd_remove);
}




⌨️ 快捷键说明

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