Info API::CreateTable(SqlCommandCreateTable* command){ IndexManager index_manager; CatalogManager catalog_manager; TableInfo table; std::string table_name = command->table_name(); std::string primary_key = command->primary_key(); std::vector<std::string> unique_keys = command->unique(); int attribute_count = 0; //判断表是否存在 if(catalog_manager.HasTable(table_name)){ std::string error_info; error_info = "Table \"" + table_name + "\" already exists."; return Info(error_info); } else{ table.set_table_name(table_name); //Check primary key. if (primary_key.empty()){ return Info("Must assign a primary key."); } std::map<std::string, std::pair<std::string,int>> attributes = command->attribute(); for (auto it = attributes.begin(); it != attributes.end(); ++it){ AttributeInfo single_attribute_info; single_attribute_info.set_name(it->first); attribute_count++; //判断类型是否有效 if (it->second.first != "char" && it->second.first != "int" && it->second.first != "float"){ std::string error_info; error_info = "The type \"" + it->second.first + "\" of attribute \"" + it->first + "\" is invalid."; return Info(error_info); } else{ single_attribute_info.set_type(it->second.first); //判断char(n) n是否在1~255的范围内 if (0<it->second.second && it->second.second<256){ single_attribute_info.set_length(it->second.second); } else{ std::string error_info; error_info = "The length of char of attribute \"" + it->first + "\" must in range of [1,256]."; return Info(error_info); } } //判断是否是 primary_key if(it->first == primary_key){ single_attribute_info.set_is_primary_key(true); single_attribute_info.add_index("#pri_" + table_name +"_"+it->first); index_manager.CreateIndex(it->second.first,it->second.second,IndexInfo("#pri_" + table_name +"_"+it->first,table_name,it->first)); catalog_manager.RegisterIndex(IndexInfo("#pri_" + table_name +"_"+it->first,table_name,it->first)); } else{ single_attribute_info.set_is_primary_key(false); } //判断是否 unique if (std::find(unique_keys.begin(), unique_keys.end(), it->first) != unique_keys.end()){ single_attribute_info.set_is_unique(true); } else{ single_attribute_info.set_is_unique(false); } table.add_attribute(single_attribute_info); } if(!table.HasAttribute(primary_key)){ std::string error_info; error_info = "assigned primary key \"" + primary_key + "\" is not an attribute of the table."; return Info(error_info); } table.set_attribute_number(attribute_count); table.set_attribute_names_ordered(command->attribute_names_ordered()); if(catalog_manager.RegisterTable(table)){ return Info(); } else{ return Info("Register table failed."); } } }
//--------------------------------------------------------------------- bool OptimiseTool::calculateDuplicateVertices() { bool duplicates = false; // Lock all the buffers first typedef std::vector<char*> BufferLocks; BufferLocks bufferLocks; const VertexBufferBinding::VertexBufferBindingMap& bindings = mTargetVertexData->vertexBufferBinding->getBindings(); VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi; bufferLocks.resize(mTargetVertexData->vertexBufferBinding->getLastBoundIndex()+1); for (bindi = bindings.begin(); bindi != bindings.end(); ++bindi) { char* lock = static_cast<char*>(bindi->second->lock(HardwareBuffer::HBL_READ_ONLY)); bufferLocks[bindi->first] = lock; } for (uint32 v = 0; v < mTargetVertexData->vertexCount; ++v) { UniqueVertex uniqueVertex; const VertexDeclaration::VertexElementList& elemList = mTargetVertexData->vertexDeclaration->getElements(); VertexDeclaration::VertexElementList::const_iterator elemi; unsigned short uvSets = 0; for (elemi = elemList.begin(); elemi != elemList.end(); ++elemi) { // all float pointers for the moment float *pFloat; elemi->baseVertexPointerToElement( bufferLocks[elemi->getSource()], &pFloat); switch(elemi->getSemantic()) { case VES_POSITION: uniqueVertex.position.x = *pFloat++; uniqueVertex.position.y = *pFloat++; uniqueVertex.position.z = *pFloat++; break; case VES_NORMAL: uniqueVertex.normal.x = *pFloat++; uniqueVertex.normal.y = *pFloat++; uniqueVertex.normal.z = *pFloat++; break; case VES_TANGENT: uniqueVertex.tangent.x = *pFloat++; uniqueVertex.tangent.y = *pFloat++; uniqueVertex.tangent.z = *pFloat++; // support w-component on tangent if present if (VertexElement::getTypeCount(elemi->getType()) == 4) { uniqueVertex.tangent.w = *pFloat++; } break; case VES_BINORMAL: uniqueVertex.binormal.x = *pFloat++; uniqueVertex.binormal.y = *pFloat++; uniqueVertex.binormal.z = *pFloat++; break; case VES_TEXTURE_COORDINATES: // supports up to 4 dimensions for (unsigned short dim = 0; dim < VertexElement::getTypeCount(elemi->getType()); ++dim) { uniqueVertex.uv[elemi->getIndex()][dim] = *pFloat++; } ++uvSets; break; case VES_BLEND_INDICES: case VES_BLEND_WEIGHTS: case VES_DIFFUSE: case VES_SPECULAR: // No action needed for these semantics. break; }; } if (v == 0) { // set up comparator UniqueVertexLess lessObj; lessObj.pos_tolerance = mPosTolerance; lessObj.norm_tolerance = mNormTolerance; lessObj.uv_tolerance = mUVTolerance; lessObj.uvSets = uvSets; mUniqueVertexMap = UniqueVertexMap(lessObj); } // try to locate equivalent vertex in the list already uint32 indexUsed; UniqueVertexMap::iterator ui = mUniqueVertexMap.find(uniqueVertex); bool isOrig = false; if (ui != mUniqueVertexMap.end()) { // re-use vertex, remap indexUsed = ui->second.newIndex; duplicates = true; } else { // new vertex isOrig = true; indexUsed = static_cast<uint32>(mUniqueVertexMap.size()); // store the originating and new vertex index in the unique map VertexInfo newInfo(v, indexUsed); // lookup mUniqueVertexMap[uniqueVertex] = newInfo; // ordered mUniqueVertexList.push_back(newInfo); } // Insert remap entry (may map to itself) mIndexRemap.push_back(IndexInfo(indexUsed, isOrig)); // increment buffer lock pointers for (bindi = bindings.begin(); bindi != bindings.end(); ++bindi) { bufferLocks[bindi->first] += bindi->second->getVertexSize(); } } // unlock the buffers now for (bindi = bindings.begin(); bindi != bindings.end(); ++bindi) { bindi->second->unlock(); } // Were there duplicates? return duplicates; }