localcli.cpp

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

CPP
1,971
字号
	dbTableDescriptor* table = db->tables;	db->unlinkTable(table);	delete table;    }    return cli_ok;}int cli_remove(int statement){    return dbCLI::instance.remove(statement);}int dbCLI::remove(int statement){    statement_desc* stmt = statements.get(statement);        if (stmt == NULL || !stmt->prepared) {	return cli_bad_descriptor;    }    if (!stmt->for_update) {	return cli_not_update_mode;    }    if (stmt->cursor.isEmpty()) { 	return cli_not_found;    }    stmt->cursor.removeAllSelected();    return cli_ok;}int cli_describe(int session, char const* table, cli_field_descriptor** fields){    return dbCLI::instance.describe(session, table, fields);}int dbCLI::describe(int session, char const* table, cli_field_descriptor** fields){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return cli_bad_descriptor;    }	    dbDatabase* db = s->db;    dbTableDescriptor* desc = db->findTableByName(table);    if (desc == NULL) {	return cli_table_not_found;    } else { 	int nColumns = desc->nColumns;	cli_field_descriptor* fp = 	    (cli_field_descriptor*)malloc(nColumns*sizeof(cli_field_descriptor));	dbFieldDescriptor* fd = desc->columns; 	*fields = fp;	for (int i = 0; i < nColumns; i++, fp++) { 	    fp->type = (cli_var_type)map_type(fd);	    fp->name = fd->name;	    	    fp->refTableName = fd->refTableName;	    fp->inverseRefFieldName = fd->inverseRefName;	    fp->flags = 0;	    if (fd->tTree != 0) { 		fp->flags |= cli_indexed;	    }	    if (fd->hashTable != 0) { 		fp->flags |= cli_hashed;	    }	    fd = fd->next;	}	return nColumns;    }}int cli_show_tables(int session, cli_table_descriptor** tables){    return dbCLI::instance.show_tables(session, tables);}int dbCLI::show_tables(int session, cli_table_descriptor** tables){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return cli_bad_descriptor;    }	    dbTableDescriptor* desc;    int nTables = 0;    for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {	if (strcmp(desc->name, "Metatable")) {	    nTables += 1;	}    }        if (nTables != 0) { 	cli_table_descriptor* td = (cli_table_descriptor*)malloc(nTables*sizeof(cli_table_descriptor));	*tables = td;	for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {	    if (strcmp(desc->name, "Metatable")) {		td->name = desc->name;		td += 1;	    }	}    } else { 	*tables = NULL;    }    return nTables;}#define MAX_QUERY_INDETIFIER_LENGTH 256int sql_scanner::get(){    char buf[MAX_QUERY_INDETIFIER_LENGTH];    int i = 0, ch;    do {	ch = *p++;	if (ch == '\0') {	    return tkn_eof;	}    } while (ch > 0 && ch <= 32);    if (ch == '*') {	return tkn_all;    } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-') {		int const_type = tkn_iconst;	while (true) {	    ch = *p++;	    if (ch == '.' || ch == 'e' || ch == 'E') { 		const_type = tkn_fconst;	    } else if (!((ch >= '0' && ch <= '9') || ch == '+' || ch == '-')) { 		break;	    }	}	return const_type;    } else if (isalnum(ch) || ch == '$' || ch == '_') {	do {	    buf[i++] = ch;	    if (i == MAX_QUERY_INDETIFIER_LENGTH) {		// Identifier too long		return tkn_error;	    }	    ch = *p++;	} while (ch != EOF && (isalnum(ch) || ch == '$' || ch == '_'));	p -= 1;	buf[i] = '\0';	ident = buf;	return dbSymbolTable::add(ident, tkn_ident);    } else {	// Invalid symbol	return tkn_error;    }}int cli_create_table(int session, char const* tableName, int nColumns, 		     cli_field_descriptor* columns){    return dbCLI::instance.create_table(session, tableName, nColumns, columns);}int dbCLI::create_table(int session, char const* tableName, int nColumns, 			cli_field_descriptor* columns){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return cli_bad_descriptor;    }	        s->db->beginTransaction(dbDatabase::dbExclusiveLock);    if (s->existed_tables == NULL) {         s->existed_tables = s->db->tables;    }    return create_table(s->db, tableName, nColumns, columns);}int dbCLI::create_table(dbDatabase* db, char const* tableName, int nColumns, 			cli_field_descriptor* columns){    int i;    db->modified = true;    if (db->findTableByName(tableName) != NULL) {	return cli_table_already_exists;    }    int nFields = nColumns;    int varyingLength = strlen(tableName) + 1;    for (i = 0; i < nColumns; i++) { 	int type = columns[i].type;	varyingLength += strlen(columns[i].name) + 3;	if (type == cli_oid || type == cli_array_of_oid) { 	    varyingLength += strlen(columns[i].refTableName);	    if (columns[i].inverseRefFieldName != NULL) { 		varyingLength += strlen(columns[i].inverseRefFieldName);	    }	}	switch (type) {        	  case cli_oid:	  case cli_bool:	  case cli_int1:	  case cli_int2:	  case cli_int4:	  case cli_autoincrement:	  case cli_int8:	  case cli_real4:	  case cli_real8:	  case cli_asciiz:	  case cli_pasciiz:	    break;	  case cli_array_of_oid:	  case cli_array_of_bool:	  case cli_array_of_int1:	  case cli_array_of_int2:	  case cli_array_of_int4:	  case cli_array_of_int8:	  case cli_array_of_real4:	  case cli_array_of_real8:	  case cli_array_of_string:	    varyingLength += strlen(columns[i].name) + 2 + 3;	    nFields += 1;	    break;	  case cli_unknown:	    return cli_unsupported_type;	}    }    db->beginTransaction(dbDatabase::dbExclusiveLock);    oid_t oid = db->allocateRow(dbMetaTableId, 				sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength);    dbTable* table = (dbTable*)db->putRow(oid);    int offs = sizeof(dbTable) + sizeof(dbField)*nFields;    table->name.offs = offs;    table->name.size = strlen(tableName)+1;    strcpy((char*)table + offs, tableName);    offs += table->name.size;    size_t size = sizeof(dbRecord);    table->fields.offs = sizeof(dbTable);    dbField* field = (dbField*)((char*)table + table->fields.offs);    offs -= sizeof(dbTable);    for (i = 0; i < nColumns; i++, field += 1, offs -= sizeof(dbField)) {	field->name.offs = offs;	field->name.size = strlen(columns[i].name) + 1;	strcpy((char*)field + offs, columns[i].name);	offs += field->name.size;		field->tableName.offs = offs;	int type = columns[i].type;		if (type == cli_oid || type == cli_array_of_oid) {	    field->tableName.size = strlen(columns[i].refTableName) + 1;	    strcpy((char*)field + offs, columns[i].refTableName);	    offs += field->tableName.size;	    field->inverse.offs = offs;	    if (columns[i].inverseRefFieldName != NULL) { 		field->inverse.size = strlen(columns[i].inverseRefFieldName) + 1;		strcpy((char*)field + offs, columns[i].inverseRefFieldName);		offs += field->inverse.size;	    } else { 		field->inverse.size = 1;		*((char*)field + offs) = '\0';		offs += 1;	    }	} else { 	    field->tableName.size = 1;            *((char*)field + offs) = '\0';	    offs += 1;            field->inverse.size = 1;            field->inverse.offs = offs;	    *((char*)field + offs) = '\0';	    offs += 1;            	}	field->tTree = field->hashTable = 0; 	switch (type) {        	  case cli_oid:	    field->type = dbField::tpReference;	    field->size = sizeof(oid_t);	    break;	  case cli_bool:	    field->type = dbField::tpBool;	    field->size = sizeof(bool);	    break;	  case cli_int1:	    field->type = dbField::tpInt1;	    field->size = sizeof(int1);	    break;	  case cli_int2:	    field->type = dbField::tpInt2;	    field->size = sizeof(int2);	    break;	  case cli_int4:	  case cli_autoincrement:	    field->type = dbField::tpInt4;	    field->size = sizeof(int4);	    break;	  case cli_int8:	    field->type = dbField::tpInt8;	    field->size = sizeof(db_int8);	    break;	  case cli_real4:	    field->type = dbField::tpReal4;	    field->size = sizeof(real4);	    break;	  case cli_real8:	    field->type = dbField::tpReal8;	    field->size = sizeof(real8);	    break;	  case cli_asciiz:	  case cli_pasciiz:	    field->type = dbField::tpString;	    field->size = sizeof(dbVarying);	    field->offset = DOALIGN(size, sizeof(int4));	    size = field->offset + sizeof(dbVarying);	    field->hashTable = (columns[i].flags & cli_hashed) 		? dbHashTable::allocate(db) : 0; 	    field->tTree = (columns[i].flags & cli_indexed)		? dbTtree::allocate(db) : 0; 	    continue;	  case cli_array_of_oid:	  case cli_array_of_bool:	  case cli_array_of_int1:	  case cli_array_of_int2:	  case cli_array_of_int4:	  case cli_array_of_int8:	  case cli_array_of_real4:	  case cli_array_of_real8:	  case cli_array_of_string:	    field->type = dbField::tpArray;	    field->size = sizeof(dbVarying);	    field->offset = DOALIGN(size, sizeof(int4));	    size = field->offset + sizeof(dbVarying);	    field->hashTable = field->tTree = 0;            field += 1;	    offs -= sizeof(dbField);	    field->name.offs = offs;	    field->name.size = strlen(columns[i].name) + 3;	    sprintf((char*)field + offs, "%s[]", columns[i].name);	    offs += field->name.size;		    field->tableName.offs = offs;	    field->tableName.size = 1;	    *((char*)field + offs) = '\0';	    offs += 1;	    field->inverse.offs = offs;	    field->inverse.size = 1;	    *((char*)field + offs) = '\0';	    offs += 1;	    field->offset = 0;	    field->hashTable = field->tTree = 0;	    switch (type) { 	      case cli_array_of_oid:		field->type = dbField::tpReference;		field->size = sizeof(oid_t);		break;	      case cli_array_of_bool:		field->type = dbField::tpBool;		field->size = sizeof(bool);		break;	      case cli_array_of_int1:		field->type = dbField::tpInt1;		field->size = sizeof(int1);		break;	      case cli_array_of_int2:		field->type = dbField::tpInt2;		field->size = sizeof(int2);		break;	      case cli_array_of_int4:		field->type = dbField::tpInt4;		field->size = sizeof(int4);		break;	      case cli_array_of_int8:		field->type = dbField::tpInt8;		field->size = sizeof(db_int8);		break;	      case cli_array_of_real4:		field->type = dbField::tpReal4;		field->size = sizeof(real4);		break;	      case cli_array_of_real8:		field->type = dbField::tpReal8;		field->size = sizeof(real8);		break;	      case cli_array_of_string:		field->type = dbField::tpString;		field->size = sizeof(dbVarying);		break;	    }	    continue;	}         field->hashTable = (columns[i].flags & cli_hashed)             ? dbHashTable::allocate(db) : 0;         field->tTree = (columns[i].flags & cli_indexed)            ? dbTtree::allocate(db) : 0; 	field->offset = DOALIGN(size, field->size);	size = field->offset + sizeof(dbVarying);    }    table->fields.size = nFields;    table->fixedSize = size;    table->nRows = 0;    table->nColumns = nColumns;    table->firstRow = 0;    table->lastRow = 0;        db->linkTable(new dbTableDescriptor(table), oid);    if (!db->completeDescriptorsInitialization()) {	return cli_table_not_found;    }    return cli_ok;}int cli_drop_table(int session, char const* tableName){    return dbCLI::instance.drop_table(session, tableName);}int dbCLI::drop_table(int session, char const* tableName){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return cli_bad_descriptor;    }	        dbDatabase* db = s->db;    dbTableDescriptor* desc = db->findTableByName(tableName);    if (desc == NULL) {	return cli_table_not_found;    }    db->dropTable(desc);    if (desc == s->existed_tables) { 	s->existed_tables = desc->nextDbTable;    }    db->unlinkTable(desc);    desc->nextDbTable = s->dropped_tables;    s->dropped_tables = desc;    return cli_ok;}int cli_alter_index(int session, char const* tableName, char const* fieldName, int newFlags){    return dbCLI::instance.alter_index(session, tableName, fieldName, newFlags);}int dbCLI::alter_index(int session, char const* tableName, char const* fieldName, int newFlags){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return cli_bad_descriptor;    }	        return alter_index(s->db, tableName, fieldName, newFlags);}int dbCLI::alter_index(dbDatabase* db, char const* tableName, char const* fieldName, int newFlags){    db->beginTransaction(dbDatabase::dbExclusiveLock);    dbTableDescriptor* desc = db->findTableByName(tableName);    if (desc == NULL) {	return cli_table_not_found;    }    dbFieldDescriptor* fd = desc->find(fieldName);    if (fd == NULL) { 	return cli_column_not_found;    }    if (fd->tTree != 0 && (newFlags & cli_indexed) == 0) { 	db->dropIndex(fd);    }     if (fd->hashTable != 0 && (newFlags & cli_hashed) == 0) { 	db->dropHashTable(fd);    }     if (fd->tTree == 0 && (newFlags & cli_indexed) != 0) {	db->createIndex(fd);    }    if (fd->hashTable == 0 && (newFlags & cli_hashed) != 0) {	db->createHashTable(fd);    }    return cli_ok;}cli_error_handler cli_set_error_handler(int session, cli_error_handler new_handler){    return dbCLI::instance.set_error_handler(session, new_handler);}cli_error_handler dbCLI::set_error_handler(int session, cli_error_handler new_handler){    session_desc* s = sessions.get(session);    if (s == NULL) { 	return NULL;    }	        return (cli_error_handler)s->db->setErrorHandler(dbDatabase::dbErrorHandler(new_handler));}   

⌨️ 快捷键说明

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