Commit b7875b36 authored by casualet's avatar casualet

modify cdbtest

parent 6a00e3a4
......@@ -98,20 +98,6 @@ struct rawReturnValue{
std::vector<int> fieldTypes;
};
struct backupOnionSelection {
int numOfFields;
std::vector<int> fieldSize;
std::vector<int> saltIndex;
std::vector<int> onionIndex;
backupOnionSelection(int n):numOfFields(n),fieldSize(n,-1),saltIndex(n,-1),onionIndex(n,-1){}
void print();
};
//must be static, or we get "no previous declaration"
//execute the query and getthe rawReturnVale, this struct can be copied.
static
......@@ -434,62 +420,6 @@ static void processSchemaInfo(SchemaInfo &schema,std::string db="tdb"){
}
}
//first step of back
static std::vector<FieldMeta *> getFieldMeta(SchemaInfo &schema,std::string db = "tdb",std::string table="student1"){
const std::unique_ptr<AES_KEY> &TK = std::unique_ptr<AES_KEY>(getKey(std::string("113341234")));
Analysis analysis(db,schema,TK,
SECURITY_RATING::SENSITIVE);
if(analysis.databaseMetaExists(db)){
const DatabaseMeta & dbm = analysis.getDatabaseMeta(db);
TableMeta & tbm = *dbm.getChild(IdentityMetaKey(table));
return tbm.orderedFieldMetas();
}else{
std::cout<<"data base not exists"<<std::endl;
return std::vector<FieldMeta *>();
}
}
//representation of one field.
struct transField{
bool hasSalt;
int onionIndex;
int numOfOnions;
//onions
std::vector<std::string> fields;
std::vector<onion> onions;
void show(){
for(auto i=0U;i<fields.size();i++){
cout<<fields[i]<<" : "<<gmp2[onions[i]]<<"\t";
}
cout<<endl;
if(hasSalt){
cout<<"has salt"<<endl;
}else cout<<"do not have salt"<<endl;
}
};
static std::vector<transField> getTransField(std::vector<FieldMeta *> pfms){
std::vector<transField> res;
//for every field
for(auto pfm:pfms){
transField tf;
for(std::pair<const OnionMetaKey *, OnionMeta *> &ompair:pfm->orderedOnionMetas()){
tf.numOfOnions++;
tf.fields.push_back((ompair.second)->getAnonOnionName());
tf.onions.push_back(ompair.first->getValue());
}
if(pfm->getHasSalt()){
tf.hasSalt=true;
tf.fields.push_back(pfm->getSaltName());
}
res.push_back(tf);
}
return res;
}
static std::unique_ptr<SchemaInfo> myLoadSchemaInfo() {
std::unique_ptr<Connect> e_conn(Connect::getEmbedded(embeddedDir));
std::unique_ptr<SchemaInfo> schema(new SchemaInfo());
......@@ -510,460 +440,6 @@ static std::unique_ptr<SchemaInfo> myLoadSchemaInfo() {
return schema;
}
static void
addToReturn(ReturnMeta *const rm, int pos, const OLK &constr,
bool has_salt, const std::string &name) {
const bool test = static_cast<unsigned int>(pos) == rm->rfmeta.size();
TEST_TextMessageError(test, "ReturnMeta has badly ordered"
" ReturnFields!");
const int salt_pos = has_salt ? pos + 1 : -1;
std::pair<int, ReturnField>
pair(pos, ReturnField(false, name, constr, salt_pos));
rm->rfmeta.insert(pair);
}
static void
addSaltToReturn(ReturnMeta *const rm, int pos) {
const bool test = static_cast<unsigned int>(pos) == rm->rfmeta.size();
TEST_TextMessageError(test, "ReturnMeta has badly ordered"
" ReturnFields!");
std::pair<int, ReturnField>
pair(pos, ReturnField(true, "", OLK::invalidOLK(), -1));
rm->rfmeta.insert(pair);
}
static Item *
decrypt_item_layers(const Item &i, const FieldMeta *const fm, onion o,
uint64_t IV) {
assert(!RiboldMYSQL::is_null(i));
const Item *dec = &i;
Item *out_i = NULL;
//we have fieldMeta, but only use part of it. we select the onion via the o in olk we constructed.
const OnionMeta *const om = fm->getOnionMeta(o);
assert(om);
//its easy to use onionmeta, just get layers, and use dectypt() to decrypt the results.
const auto &enc_layers = om->getLayers();
for (auto it = enc_layers.rbegin(); it != enc_layers.rend(); ++it) {
out_i = (*it)->decrypt(*dec, IV);
assert(out_i);
dec = out_i;
LOG(cdb_v) << "dec okay";
}
assert(out_i && out_i != &i);
return out_i;
}
static
ResType decryptResults(const ResType &dbres, const ReturnMeta &rmeta) {
const unsigned int rows = dbres.rows.size();
const unsigned int cols = dbres.names.size();
std::vector<std::string> dec_names;
for (auto it = dbres.names.begin();
it != dbres.names.end(); it++) {
const unsigned int index = it - dbres.names.begin();
//fetch rfmeta based on index
const ReturnField &rf = rmeta.rfmeta.at(index);
if (!rf.getIsSalt()) {
//need to return this field
//filed name here is plaintext
dec_names.push_back(rf.fieldCalled());
}
}
const unsigned int real_cols = dec_names.size();
std::vector<std::vector<Item *> > dec_rows(rows);
for (unsigned int i = 0; i < rows; i++) {
dec_rows[i] = std::vector<Item *>(real_cols);
}
//
unsigned int col_index = 0;
for (unsigned int c = 0; c < cols; c++) {
const ReturnField &rf = rmeta.rfmeta.at(c);
if (rf.getIsSalt()) {
continue;
}
//the key is in fieldMeta
FieldMeta *const fm = rf.getOLK().key;
for (unsigned int r = 0; r < rows; r++) {
if (!fm || dbres.rows[r][c]->is_null()) {
dec_rows[r][col_index] = dbres.rows[r][c];
} else {
uint64_t salt = 0;
const int salt_pos = rf.getSaltPosition();
//read salt from remote datab for descrypting.
if (salt_pos >= 0) {
Item_int *const salt_item =
static_cast<Item_int *>(dbres.rows[r][salt_pos]);
assert_s(!salt_item->null_value, "salt item is null");
salt = salt_item->value;
}
//peel onion.
dec_rows[r][col_index] =
decrypt_item_layers(*dbres.rows[r][c],
fm, rf.getOLK().o, salt);
}
}
col_index++;
}
//resType is used befor and after descrypting.
return ResType(dbres.ok, dbres.affected_rows, dbres.insert_id,
std::move(dec_names),
std::vector<enum_field_types>(dbres.types),
std::move(dec_rows));
}
//can not use unique_ptr here in argument 3?
static std::shared_ptr<ReturnMeta> myGetReturnMeta(std::string database, std::string table,\
SchemaInfo & schema,backupOnionSelection & bonion) {
std::cout<<"start my decrypt!!"<<std::endl;
std::shared_ptr<ReturnMeta> myReturnMeta = std::make_shared<ReturnMeta>();
myReturnMeta->rfmeta.size();
//construct OLKs for each field!!
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const std::unique_ptr<IdentityMetaKey> dbmeta_key(new IdentityMetaKey(database));
//get databaseMeta
std::cout<<dbmeta_key->getValue()<<std::endl;
DatabaseMeta * db = schema.getChild(*dbmeta_key);
if(db==NULL) {
std::cout<<"db == NULL"<<std::endl;
exit(0);
}else{
std::cout<<db->getDatabaseID()<<std::endl;
}
//get tableMeta
const std::unique_ptr<IdentityMetaKey> tbMeta_key(new IdentityMetaKey(table));
TableMeta * tbMeta = (*db).getChild(*tbMeta_key);
if(tbMeta==NULL){
std::cout<<"tb == NULL"<<std::endl;
exit(0);
}else{
std::cout<<tbMeta->getDatabaseID()<<std::endl;
}
std::cout<<"table anon name: "<<tbMeta->getAnonTableName()<<std::endl;
//get fieldMeta
const auto & fields = tbMeta->getChildren();
//num of fields
std::cout<<fields.size()<<std::endl;
//one Olk for each field
std::cout<<"fields print: "<<std::endl;
int pos = 0;
std::vector<std::string> selectFields;
//according to uniqueCounter
for(FieldMeta * field : tbMeta->orderedFieldMetas()) {
std::cout<<field->getFieldName()<<field->getSaltName()<<std::endl;
//getOlks!!
for(std::pair<const OnionMetaKey *, OnionMeta *> oneOnion:field->orderedOnionMetas()){
std::cout<<oneOnion.first->getValue()<<":"<<oneOnion.second->getAnonOnionName()<<std::endl;
OLK curOLK(oneOnion.first->getValue(),oneOnion.second->getSecLevel(),field);
std::cout<<curOLK.o<<std::endl;
addToReturn(myReturnMeta.get(),pos++,curOLK,true,field->getFieldName());
addSaltToReturn(myReturnMeta.get(),pos++);
selectFields.push_back(oneOnion.second->getAnonOnionName());
break;
}
selectFields.push_back(field->getSaltName());
}
auto allFieldMetas = tbMeta->orderedFieldMetas();
int numOfFields = allFieldMetas.size();
for(int i=0;i<numOfFields;i++){
FieldMeta *field = allFieldMetas[i];
auto allOnionMetas = field->orderedOnionMetas();
//choose onion and then construct returnmeta,
//current we choose the first onion
std::pair<const OnionMetaKey *, OnionMeta *> oneOnion = allOnionMetas[0];
OLK curOLK(oneOnion.first->getValue(),oneOnion.second->getSecLevel(),field);
addToReturn(myReturnMeta.get(),pos++,curOLK,true,field->getFieldName());
addSaltToReturn(myReturnMeta.get(),pos++);
}
//we have constructed OLK in myReturnMeta, let's decrypt
// ResType deResType = decryptResults(backResType,*myReturnMeta);
// std::cout<<"start parsing deresType!!!!!"<<std::endl;
// parseResType(deResType);
return myReturnMeta;
}
//select query generate, select and retrive the onion selected
static std::string generateSelectQuery(std::string database, std::string table,
SchemaInfo & schema,backupOnionSelection &bonion) {
//construct OLKs for each field!!
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const std::unique_ptr<IdentityMetaKey> dbmeta_key(new IdentityMetaKey(database));
//get databaseMeta
DatabaseMeta * db = schema.getChild(*dbmeta_key);
if(db==NULL) {
std::cout<<"db == NULL"<<std::endl;
return "select NULL";
}
//get tableMeta
const std::unique_ptr<IdentityMetaKey> tbMeta_key(new IdentityMetaKey(table));
TableMeta * tbMeta = (*db).getChild(*tbMeta_key);
if(tbMeta==NULL){
std::cout<<"tb == NULL"<<std::endl;
return "select NULL";
}
//get fieldMeta
const auto & fields = tbMeta->getChildren();
//num of fields
int numOfFields = fields.size();
assert(numOfFields==bonion.numOfFields);
//one Olk for each field
std::vector<std::string> selectFields;
/*
//according to uniqueCounter
for(FieldMeta * field : tbMeta->orderedFieldMetas()) {
std::cout<<field->getFieldName()<<field->getSaltName()<<std::endl;
//getOlks!!
for(std::pair<const OnionMetaKey *, OnionMeta *> oneOnion:field->orderedOnionMetas()){
selectFields.push_back(oneOnion.second->getAnonOnionName());
break;
}
selectFields.push_back(field->getSaltName());
}
*/
std::cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl;
auto allFieldMetas = tbMeta->orderedFieldMetas();
for(int i=0;i<numOfFields;i++){
FieldMeta* field = allFieldMetas[i];
auto allOnionMetas = field->orderedOnionMetas();
//for this field, choose an onion
std::pair<const OnionMetaKey *, OnionMeta *> oneOnion = allOnionMetas[0];
selectFields.push_back(oneOnion.second->getAnonOnionName());
selectFields.push_back(field->getSaltName());
}
std::string firstFields;
for(int i=0; i<(int)selectFields.size()-1; i++) {
firstFields = firstFields + selectFields[i] + ",";
}
firstFields += selectFields[selectFields.size()-1];
//backup(select) only some of the onions
std::string backQuery = std::string("select "+ firstFields + " from "+database+".") \
+ std::string(tbMeta->getAnonTableName());
return backQuery;
}
static void split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss;
ss.str(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
}
static std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
void backupOnionSelection::print() {
std::cout<<GREEN_BEGIN<<"numOfFields: "<<numOfFields<<COLOR_END<<std::endl;
std::cout<<"field size: "<<std::endl;
for(auto item:fieldSize){
std::cout<<item<<"\t"<<std::endl;
}
std::cout<<"saltIndex: "<<std::endl;
for(auto item:saltIndex){
std::cout<<item<<"\t"<<std::endl;
}
std::cout<<"onionIndex: "<<std::endl;
for(auto item:onionIndex){
std::cout<<item<<"\t"<<std::endl;
}
}
//based on the Metadata, we mordify the original create tabe query and generate the new query.
//static void std::string getCreateTable) {
static std::string getCreateTable(std::string orignalQuery,backupOnionSelection back) {
std::cout<<"orignalQuery: "<<orignalQuery<<std::endl;
back.print();
auto res = split(orignalQuery,',');
for(auto item:res) {
std::cout<<item<<std::endl;
}
std::string result;
//choose the salt and onion base on backupOnionSelection.
for(int i=0;i<back.numOfFields-1;i++){
int indexOne = back.onionIndex[i];
int indexTwo = back.saltIndex[i];
result = result + res[indexOne] +","+ res[indexTwo]+",";
}
int indexOne = back.onionIndex[back.numOfFields-1];
int indexTwo = back.saltIndex[back.numOfFields-1];
result = result + res[indexOne] + ","+res[indexTwo];
return result;
}
//generate simple INSERT query for testing purposes.
static
void generateInsertQuery(rawReturnValue &raw,std::string annoTable) {
std::cout<<raw.rowValues.size()<<std::endl;
std::cout<<annoTable<<std::endl;
int len = raw.fieldNames.size();
for(auto oneRow:raw.rowValues){
std::string res= std::string("INSERT INTO ")+annoTable+" VALUES(";
for(int i=0;i<len-1;i++){
res = res + oneRow[i]+" , ";
}
res = res + oneRow[len-1]+")";
std::cout<<GREEN_BEGIN<<res<<COLOR_END<<std::endl;
}
}
static
backupOnionSelection generateBackupStrategy(std::string database, std::string table,
SchemaInfo & schema){
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const std::unique_ptr<IdentityMetaKey> dbmeta_key(new IdentityMetaKey(database));
//get databaseMeta, search in the map
DatabaseMeta * db = schema.getChild(*dbmeta_key);
if(db==NULL) {
std::cout<<"db == NULL"<<std::endl;
return backupOnionSelection(0);
}
//get tableMeta
const std::unique_ptr<IdentityMetaKey> tbMeta_key(new IdentityMetaKey(table));
TableMeta * tbMeta = (*db).getChild(*tbMeta_key);
if(tbMeta==NULL){
std::cout<<"tb == NULL"<<std::endl;
return backupOnionSelection(0);
}
//get fieldMeta(we only need size here)
const auto & fields = tbMeta->getChildren();
//one Olk for each field
backupOnionSelection curBack(fields.size());
int fieldIndex =0;
//according to uniqueCounter
for(FieldMeta * field : tbMeta->orderedFieldMetas()){
curBack.fieldSize[fieldIndex] = field->getChildren().size()+1;
curBack.onionIndex[fieldIndex] = 0;
fieldIndex+=1;
}
//complete curBack
int num = curBack.numOfFields;
int add=0;
for(int i=0;i<num;i++){
int cur = curBack.fieldSize[i];
curBack.onionIndex[i] = add;
add += cur;
curBack.saltIndex[i] = add-1;
}
assert(num=curBack.saltIndex.size());
assert(num=curBack.onionIndex.size());
return curBack;
}
static std::string logicBackUp(std::string database, std::string table,SchemaInfo & schema) {
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const std::unique_ptr<IdentityMetaKey> dbmeta_key(new IdentityMetaKey(database));
//get databaseMeta, search in the map
DatabaseMeta * db = schema.getChild(*dbmeta_key);
if(db==NULL) {
std::cout<<"db == NULL"<<std::endl;
return "";
}
//get tableMeta
const std::unique_ptr<IdentityMetaKey> tbMeta_key(new IdentityMetaKey(table));
TableMeta * tbMeta = (*db).getChild(*tbMeta_key);
if(tbMeta==NULL){
std::cout<<"tb == NULL"<<std::endl;
return "";
}
//construct OLKs for each field!!
backupOnionSelection curBack = generateBackupStrategy(database,table,schema);
std::string logicTableQuery = std::string("SHOW create table "+database+".") +\
std::string(tbMeta->getAnonTableName());
auto res2 = executeAndGetResultRemote(globalConn,logicTableQuery);
assert(res2.rowValues.size()==1);
std::vector<std::string> oneRow = res2.rowValues[0];
//modify and get the create table command.
getCreateTable(oneRow[1],curBack);
//then create SELECT command,based on the curBack
std::string selectQuery = generateSelectQuery(database,table,schema,curBack);
auto res3 = executeAndGetResultRemote(globalConn,selectQuery);
generateInsertQuery(res3, tbMeta->getAnonTableName());
return selectQuery;
}
static
void
startBack(){
return ;
//only for testing backup module
std::unique_ptr<SchemaInfo> schema = myLoadSchemaInfo();
processSchemaInfo(*schema);
std::cout<<"please input dbname:####"<<std::endl;
std::string dbname;
std::cin>>dbname;
std::cout<<"please input tableame:####"<<std::endl;
std::string tablename;
std::cin>>tablename;
backupOnionSelection curBack = generateBackupStrategy(dbname,tablename,*schema);
std::shared_ptr<ReturnMeta> rmeta = myGetReturnMeta(dbname,tablename,*schema,curBack);
std::string selectQuery = logicBackUp(dbname,tablename,*schema);
auto res3 = executeAndGetResultRemote(globalConn,selectQuery);
const auto dres = MygetResTypeFromLuaTable(false,&res3);
if(rmeta.get()!=NULL){
std::cout<<"decrypted results !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl;
ResType deResType = decryptResults(dres,*rmeta);
parseResType(deResType);
std::cout<<"decrypted results !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl;
}
}
int
main() {
gmp[SECLEVEL::INVALID]="INVALID";
......@@ -1014,26 +490,14 @@ main() {
if(curQuery.size()==0){
std::cout<<std::endl;
std::getline(std::cin,curQuery);
continue;
}
if(curQuery=="back1"){
startBack();
std::unique_ptr<SchemaInfo> schema = myLoadSchemaInfo();
processSchemaInfo(*schema);
}else if(curQuery=="back"){
std::unique_ptr<SchemaInfo> schema = myLoadSchemaInfo();
std::vector<FieldMeta*> fms = getFieldMeta(*schema);
auto res = getTransField(fms);
for(auto &item:res){
item.show();
}
}else{
std::cout<<GREEN_BEGIN<<"curQuery: "<<curQuery<<"\n"<<COLOR_END<<std::endl;
batchTogether(client,curQuery,_thread_id);
continue;
}
std::cout<<GREEN_BEGIN<<"curQuery: "<<
curQuery<<"\n"<<COLOR_END<<std::endl;
batchTogether(client,curQuery,_thread_id);
std::cout<<GREEN_BEGIN<<"\nplease input a new query:#######"<<COLOR_END<<std::endl;
std::getline(std::cin,curQuery);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment