Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
Practical-Cryptdb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Zhaozhen
Practical-Cryptdb
Commits
0e66ba42
Commit
0e66ba42
authored
Jan 14, 2018
by
yiwenshao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use able to use class metadata_file to serilize metadata
parent
6920a01b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
716 additions
and
634 deletions
+716
-634
.store.hh.swp
debug/.store.hh.swp
+0
-0
load.cc
debug/load.cc
+11
-539
load.hh
debug/load.hh
+540
-0
store.cc
debug/store.cc
+16
-74
store.hh
debug/store.hh
+149
-21
No files found.
debug/.store.hh.swp
0 → 100644
View file @
0e66ba42
File added
debug/load.cc
View file @
0e66ba42
/*1. store data as column files, and restore data as plaintext insert query
#include "debug/load.hh"
* 2. plaintext insert query should be able to recover directly
* 3. should be able to used exsisting data to reduce the computation overhead(to be implemented)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <main/rewrite_main.hh>
#include <main/rewrite_util.hh>
using
std
::
cout
;
using
std
::
cin
;
using
std
::
endl
;
using
std
::
vector
;
using
std
::
string
;
using
std
::
to_string
;
class
WrapperState
{
WrapperState
(
const
WrapperState
&
other
);
WrapperState
&
operator
=
(
const
WrapperState
&
rhs
);
KillZone
kill_zone
;
public
:
std
::
string
last_query
;
std
::
string
default_db
;
WrapperState
()
{}
~
WrapperState
()
{}
const
std
::
unique_ptr
<
QueryRewrite
>
&
getQueryRewrite
()
const
{
assert
(
this
->
qr
);
return
this
->
qr
;
}
void
setQueryRewrite
(
std
::
unique_ptr
<
QueryRewrite
>
&&
in_qr
)
{
this
->
qr
=
std
::
move
(
in_qr
);
}
void
selfKill
(
KillZone
::
Where
where
)
{
kill_zone
.
die
(
where
);
}
void
setKillZone
(
const
KillZone
&
kz
)
{
kill_zone
=
kz
;
}
std
::
unique_ptr
<
ProxyState
>
ps
;
std
::
vector
<
SchemaInfoRef
>
schema_info_refs
;
private
:
std
::
unique_ptr
<
QueryRewrite
>
qr
;
};
static
std
::
string
embeddedDir
=
"/t/cryt/shadow"
;
char
*
globalEsp
=
NULL
;
int
num_of_pipe
=
4
;
//global map, for each client, we have one WrapperState which contains ProxyState.
static
std
::
map
<
std
::
string
,
WrapperState
*>
clients
;
//This connection mimics the behaviour of MySQL-Proxy
Connect
*
globalConn
;
//Return values got by using directly the MySQL c Client
struct
rawMySQLReturnValue
{
std
::
vector
<
std
::
vector
<
std
::
string
>>
rowValues
;
/*data tuples*/
std
::
vector
<
std
::
string
>
fieldNames
;
std
::
vector
<
enum_field_types
>
fieldTypes
;
std
::
vector
<
int
>
lengths
;
std
::
vector
<
int
>
maxlengths
;
/*what's the difference between length and maxlength?*/
std
::
vector
<
int
>
choosen_onions
;
void
show
();
};
void
rawMySQLReturnValue
::
show
(){
cout
<<
"rowvalues:"
<<
endl
;
for
(
auto
item_vec
:
rowValues
){
for
(
auto
item
:
item_vec
){
cout
<<
item
.
size
()
<<
"
\t
"
;
}
cout
<<
endl
;
}
cout
<<
"types:"
<<
endl
;
for
(
auto
item
:
fieldTypes
){
cout
<<
IS_NUM
(
item
)
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"fieldNames:"
<<
endl
;
for
(
auto
item
:
fieldNames
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"lengths:"
<<
endl
;
for
(
auto
item
:
lengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"maxlengths:"
<<
endl
;
for
(
auto
item
:
maxlengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
}
//must be static, or we get "no previous declaration"
//execute the query and get the rawReturnVale, this struct can be copied.
static
rawMySQLReturnValue
executeAndGetResultRemote
(
Connect
*
curConn
,
std
::
string
query
){
std
::
unique_ptr
<
DBResult
>
dbres
;
curConn
->
execute
(
query
,
&
dbres
);
rawMySQLReturnValue
myRaw
;
if
(
dbres
==
nullptr
||
dbres
->
n
==
NULL
){
std
::
cout
<<
"no results"
<<
std
::
endl
;
return
myRaw
;
}
int
num
=
mysql_num_rows
(
dbres
->
n
);
int
numOfFields
=
mysql_num_fields
(
dbres
->
n
);
MYSQL_FIELD
*
field
;
MYSQL_ROW
row
;
if
(
num
!=
0
){
while
(
(
row
=
mysql_fetch_row
(
dbres
->
n
))
){
//what's the difference between fieldlen
unsigned
long
*
fieldLen
=
mysql_fetch_lengths
(
dbres
->
n
);
std
::
vector
<
std
::
string
>
curRow
;
for
(
int
i
=
0
;
i
<
numOfFields
;
i
++
){
if
(
i
==
0
)
{
while
(
(
field
=
mysql_fetch_field
(
dbres
->
n
))
)
{
myRaw
.
fieldNames
.
push_back
(
std
::
string
(
field
->
name
));
myRaw
.
fieldTypes
.
push_back
(
field
->
type
);
//myRaw.lengths.push_back(field->length);
//myRaw.lengths.push_back(fieldLen[i]);
myRaw
.
lengths
.
push_back
(
field
->
max_length
);
myRaw
.
maxlengths
.
push_back
(
field
->
max_length
);
//cout<<field->length<<"::"<<field->max_length<<endl;
}
}
if
(
row
[
i
]
==
NULL
)
curRow
.
push_back
(
"NULL"
);
else
curRow
.
push_back
(
std
::
string
(
row
[
i
],
fieldLen
[
i
]));
}
myRaw
.
rowValues
.
push_back
(
curRow
);
}
}
return
myRaw
;
}
//helper function for transforming the rawMySQLReturnValue
static
Item_null
*
make_null
(
const
std
::
string
&
name
=
""
){
char
*
const
n
=
current_thd
->
strdup
(
name
.
c_str
());
return
new
Item_null
(
n
);
}
//helper function for transforming the rawMySQLReturnValue
static
std
::
vector
<
Item
*>
itemNullVector
(
unsigned
int
count
)
{
std
::
vector
<
Item
*>
out
;
for
(
unsigned
int
i
=
0
;
i
<
count
;
++
i
)
{
out
.
push_back
(
make_null
());
}
return
out
;
}
//transform rawMySQLReturnValue to ResType
static
ResType
MygetResTypeFromLuaTable
(
bool
isNULL
,
rawMySQLReturnValue
*
inRow
=
NULL
,
int
in_last_insert_id
=
0
){
std
::
vector
<
std
::
string
>
names
;
std
::
vector
<
enum_field_types
>
types
;
std
::
vector
<
std
::
vector
<
Item
*>
>
rows
;
//return NULL restype
if
(
isNULL
){
return
ResType
(
true
,
0
,
0
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
else
{
for
(
auto
inNames
:
inRow
->
fieldNames
){
names
.
push_back
(
inNames
);
}
for
(
auto
inTypes
:
inRow
->
fieldTypes
){
types
.
push_back
(
static_cast
<
enum_field_types
>
(
inTypes
));
}
for
(
auto
inRows
:
inRow
->
rowValues
)
{
std
::
vector
<
Item
*>
curTempRow
=
itemNullVector
(
types
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)(
inRows
.
size
());
i
++
){
curTempRow
[
i
]
=
(
MySQLFieldTypeToItem
(
types
[
i
],
inRows
[
i
])
);
}
rows
.
push_back
(
curTempRow
);
}
// uint64_t afrow = globalConn->get_affected_rows();
// std::cout<<GREEN_BEGIN<<"Affected rows: "<<afrow<<COLOR_END<<std::endl;
return
ResType
(
true
,
0
,
in_last_insert_id
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
}
//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
;
FieldMeta
*
originalFm
;
vector
<
int
>
choosenOnions
;
//used to construct return meta
int
onionIndex
=
0
;
int
numOfOnions
=
0
;
//onions
std
::
vector
<
std
::
string
>
fields
;
std
::
vector
<
onion
>
onions
;
std
::
vector
<
OnionMeta
*>
originalOm
;
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
;
}
};
/*for each field, convert the format to transField*/
static
std
::
vector
<
transField
>
getTransField
(
std
::
vector
<
FieldMeta
*>
pfms
){
std
::
vector
<
transField
>
res
;
//for every field
for
(
auto
pfm
:
pfms
){
transField
tf
;
tf
.
originalFm
=
pfm
;
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
());
tf
.
originalOm
.
push_back
(
ompair
.
second
);
}
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
());
std
::
function
<
DBMeta
*
(
DBMeta
*
const
)
>
loadChildren
=
[
&
loadChildren
,
&
e_conn
](
DBMeta
*
const
parent
)
{
auto
kids
=
parent
->
fetchChildren
(
e_conn
);
for
(
auto
it
:
kids
)
{
loadChildren
(
it
);
}
return
parent
;
};
//load all metadata and then store it in schema
loadChildren
(
schema
.
get
());
Analysis
analysis
(
std
::
string
(
"student"
),
*
schema
,
std
::
unique_ptr
<
AES_KEY
>
(
getKey
(
std
::
string
(
"113341234"
))),
SECURITY_RATING
::
SENSITIVE
);
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
;
}
/*
structure of return field.
map<int,returnField>, int is the index of names
returnField, represent a field, if the field is not salt, then fieldCalled is the plaintex name
*/
static
ResType
decryptResults
(
const
ResType
&
dbres
,
const
ReturnMeta
&
rmeta
)
{
//num of rows
const
unsigned
int
rows
=
dbres
.
rows
.
size
();
//num of names, to be decrypted
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
);
//real cols depends on plain text names.
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
;
}
//specify fieldMeta, onion, and salt should be able to decrpyt
//peel onion
dec_rows
[
r
][
col_index
]
=
decrypt_item_layers
(
*
dbres
.
rows
[
r
][
c
],
fm
,
rf
.
getOLK
().
o
,
salt
);
}
}
col_index
++
;
}
std
::
vector
<
enum_field_types
>
types
;
for
(
auto
item
:
dec_rows
[
0
]){
types
.
push_back
(
item
->
field_type
());
}
//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
>
(
types
),
//different from previous version
std
::
move
(
dec_rows
));
}
//get returnMeta
//get returnMeta
//for each filed, we have a fieldmeta. we can chosse one onion under that field to construct a return meta.
//for each filed, we have a fieldmeta. we can chosse one onion under that field to construct a return meta.
...
@@ -448,41 +18,8 @@ std::shared_ptr<ReturnMeta> getReturnMeta(std::vector<FieldMeta*> fms, std::vect
...
@@ -448,41 +18,8 @@ std::shared_ptr<ReturnMeta> getReturnMeta(std::vector<FieldMeta*> fms, std::vect
return
myReturnMeta
;
return
myReturnMeta
;
}
}
struct
meta_file
{
string
db
,
table
;
int
num_of_fields
;
vector
<
string
>
field_types
;
vector
<
int
>
field_lengths
;
vector
<
string
>
field_names
;
vector
<
int
>
choosen_onions
;
void
show
(){
cout
<<
db
<<
endl
;
cout
<<
table
<<
endl
;
cout
<<
num_of_fields
<<
endl
;
for
(
auto
item
:
field_types
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_lengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_names
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
choosen_onions
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
}
};
static
meta_file
load_meta
(
string
db
=
"tdb"
,
string
table
=
"student"
,
string
filename
=
"metadata.data"
){
static
meta_file
load_meta
(
string
db
=
"tdb"
,
string
table
=
"student"
,
string
filename
=
"metadata.data"
){
//FILE * meta = NULL;
//localmeta = fopen(filename.c_str(),"r");
filename
=
string
(
"data/"
)
+
db
+
"/"
+
table
+
"/"
+
filename
;
filename
=
string
(
"data/"
)
+
db
+
"/"
+
table
+
"/"
+
filename
;
std
::
ifstream
infile
(
filename
);
std
::
ifstream
infile
(
filename
);
string
line
;
string
line
;
...
@@ -625,101 +162,36 @@ static ResType load_files(std::string db="tdb", std::string table="student"){
...
@@ -625,101 +162,36 @@ static ResType load_files(std::string db="tdb", std::string table="student"){
}
}
ResType
rawtorestype
=
MygetResTypeFromLuaTable
(
false
,
&
resraw2
);
ResType
rawtorestype
=
MygetResTypeFromLuaTable
(
false
,
&
resraw2
);
auto
finalresults
=
decryptResults
(
rawtorestype
,
*
rm
);
auto
finalresults
=
decryptResults
(
rawtorestype
,
*
rm
);
// parseResType(finalresults);
return
finalresults
;
return
finalresults
;
}
}
static
void
init
(){
std
::
string
client
=
"192.168.1.1:1234"
;
//one Wrapper per user.
clients
[
client
]
=
new
WrapperState
();
//Connect phase
ConnectionInfo
ci
(
"localhost"
,
"root"
,
"letmein"
,
3306
);
const
std
::
string
master_key
=
"113341234"
;
char
*
buffer
;
if
((
buffer
=
getcwd
(
NULL
,
0
))
==
NULL
){
perror
(
"getcwd error"
);
}
embeddedDir
=
std
::
string
(
buffer
)
+
"/shadow"
;
SharedProxyState
*
shared_ps
=
new
SharedProxyState
(
ci
,
embeddedDir
,
master_key
,
determineSecurityRating
());
assert
(
0
==
mysql_thread_init
());
//we init embedded database here.
clients
[
client
]
->
ps
=
std
::
unique_ptr
<
ProxyState
>
(
new
ProxyState
(
*
shared_ps
));
clients
[
client
]
->
ps
->
safeCreateEmbeddedTHD
();
//Connect end!!
globalConn
=
new
Connect
(
ci
.
server
,
ci
.
user
,
ci
.
passwd
,
ci
.
port
);
}
static
void
add
(
rawMySQLReturnValue
&
str
,
ResType
&
item
){
for
(
auto
row
:
item
.
rows
){
std
::
vector
<
string
>
temp
;
for
(
auto
item
:
row
){
temp
.
push_back
(
ItemToString
(
*
item
));
}
str
.
rowValues
.
push_back
(
temp
);
}
str
.
fieldTypes
=
item
.
types
;
}
static
void
construct_insert
(
rawMySQLReturnValue
&
str
,
std
::
string
table
,
std
::
vector
<
string
>
&
res
){
std
::
string
head
=
string
(
"INSERT INTO `"
)
+
table
+
"` VALUES "
;
int
cnt
=
0
;
string
cur
=
head
;
for
(
unsigned
int
i
=
0u
;
i
<
str
.
rowValues
.
size
();
i
++
){
++
cnt
;
cur
+=
"("
;
for
(
unsigned
int
j
=
0u
;
j
<
str
.
rowValues
[
i
].
size
();
j
++
){
if
(
IS_NUM
(
str
.
fieldTypes
[
j
]))
{
// cout<<str.fieldTypes[j]<<endl;
cur
+=
str
.
rowValues
[
i
][
j
]
+=
","
;
// cout<<"isnum"<<endl;
}
else
{
//cur+=string("\"")+=str.rowValues[i][j]+="\",";
int
len
=
str
.
rowValues
[
i
][
j
].
size
();
mysql_real_escape_string
(
globalConn
->
get_conn
(),
globalEsp
,
str
.
rowValues
[
i
][
j
].
c_str
(),
len
);
cur
+=
string
(
"
\"
"
)
+=
string
(
globalEsp
)
+=
"
\"
,"
;
}
}
cur
.
back
()
=
')'
;
cur
+=
","
;
if
(
cnt
==
num_of_pipe
){
cnt
=
0
;
cur
.
back
()
=
';'
;
res
.
push_back
(
cur
);
cur
=
head
;
}
}
if
(
cnt
!=
0
){
cur
.
back
()
=
';'
;
res
.
push_back
(
cur
);
}
}
int
int
main
(
int
argc
,
char
*
argv
[])
{
main
(
int
argc
,
char
*
argv
[])
{
init
();
init
();
std
::
string
db
=
"tdb"
,
table
=
"student"
;
std
::
string
db
=
"tdb"
,
table
=
"student"
;
globalEsp
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
5000
);
globalEsp
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
5000
);
if
(
globalEsp
==
NULL
){
if
(
globalEsp
==
NULL
){
printf
(
"unable to allocate esp
\n
"
);
printf
(
"unable to allocate esp
\n
"
);
return
0
;
return
0
;
}
}
/*load and decrypt*/
ResType
res
=
load_files
(
db
,
table
);
ResType
res
=
load_files
(
db
,
table
);
/*transform*/
rawMySQLReturnValue
str
;
rawMySQLReturnValue
str
;
add
(
str
,
res
);
transform_to_rawMySQLReturnValue
(
str
,
res
);
std
::
vector
<
string
>
res_query
;
std
::
vector
<
string
>
res_query
;
/*get piped insert*/
construct_insert
(
str
,
table
,
res_query
);
construct_insert
(
str
,
table
,
res_query
);
for
(
auto
item
:
res_query
){
for
(
auto
item
:
res_query
){
cout
<<
item
<<
endl
;
cout
<<
item
<<
endl
;
}
}
free
(
globalEsp
);
free
(
globalEsp
);
/*the next step is to construct encrypted insert query*/
return
0
;
return
0
;
}
}
debug/load.hh
0 → 100644
View file @
0e66ba42
#pragma once
/*1. store data as column files, and restore data as plaintext insert query
* 2. plaintext insert query should be able to recover directly
* 3. should be able to used exsisting data to reduce the computation overhead(to be implemented)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <main/rewrite_main.hh>
#include <main/rewrite_util.hh>
using
std
::
cout
;
using
std
::
cin
;
using
std
::
endl
;
using
std
::
vector
;
using
std
::
string
;
using
std
::
to_string
;
class
WrapperState
{
WrapperState
(
const
WrapperState
&
other
);
WrapperState
&
operator
=
(
const
WrapperState
&
rhs
);
KillZone
kill_zone
;
public
:
std
::
string
last_query
;
std
::
string
default_db
;
WrapperState
()
{}
~
WrapperState
()
{}
const
std
::
unique_ptr
<
QueryRewrite
>
&
getQueryRewrite
()
const
{
assert
(
this
->
qr
);
return
this
->
qr
;
}
void
setQueryRewrite
(
std
::
unique_ptr
<
QueryRewrite
>
&&
in_qr
)
{
this
->
qr
=
std
::
move
(
in_qr
);
}
void
selfKill
(
KillZone
::
Where
where
)
{
kill_zone
.
die
(
where
);
}
void
setKillZone
(
const
KillZone
&
kz
)
{
kill_zone
=
kz
;
}
std
::
unique_ptr
<
ProxyState
>
ps
;
std
::
vector
<
SchemaInfoRef
>
schema_info_refs
;
private
:
std
::
unique_ptr
<
QueryRewrite
>
qr
;
};
static
std
::
string
embeddedDir
=
"/t/cryt/shadow"
;
char
*
globalEsp
=
NULL
;
int
num_of_pipe
=
4
;
//global map, for each client, we have one WrapperState which contains ProxyState.
static
std
::
map
<
std
::
string
,
WrapperState
*>
clients
;
//This connection mimics the behaviour of MySQL-Proxy
Connect
*
globalConn
;
//Return values got by using directly the MySQL c Client
struct
rawMySQLReturnValue
{
std
::
vector
<
std
::
vector
<
std
::
string
>>
rowValues
;
/*data tuples*/
std
::
vector
<
std
::
string
>
fieldNames
;
std
::
vector
<
enum_field_types
>
fieldTypes
;
std
::
vector
<
int
>
lengths
;
std
::
vector
<
int
>
maxlengths
;
/*what's the difference between length and maxlength?*/
std
::
vector
<
int
>
choosen_onions
;
void
show
();
};
void
rawMySQLReturnValue
::
show
(){
cout
<<
"rowvalues:"
<<
endl
;
for
(
auto
item_vec
:
rowValues
){
for
(
auto
item
:
item_vec
){
cout
<<
item
.
size
()
<<
"
\t
"
;
}
cout
<<
endl
;
}
cout
<<
"types:"
<<
endl
;
for
(
auto
item
:
fieldTypes
){
cout
<<
IS_NUM
(
item
)
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"fieldNames:"
<<
endl
;
for
(
auto
item
:
fieldNames
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"lengths:"
<<
endl
;
for
(
auto
item
:
lengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
cout
<<
"maxlengths:"
<<
endl
;
for
(
auto
item
:
maxlengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
}
//must be static, or we get "no previous declaration"
//execute the query and get the rawReturnVale, this struct can be copied.
static
rawMySQLReturnValue
executeAndGetResultRemote
(
Connect
*
curConn
,
std
::
string
query
){
std
::
unique_ptr
<
DBResult
>
dbres
;
curConn
->
execute
(
query
,
&
dbres
);
rawMySQLReturnValue
myRaw
;
if
(
dbres
==
nullptr
||
dbres
->
n
==
NULL
){
std
::
cout
<<
"no results"
<<
std
::
endl
;
return
myRaw
;
}
int
num
=
mysql_num_rows
(
dbres
->
n
);
int
numOfFields
=
mysql_num_fields
(
dbres
->
n
);
MYSQL_FIELD
*
field
;
MYSQL_ROW
row
;
if
(
num
!=
0
){
while
(
(
row
=
mysql_fetch_row
(
dbres
->
n
))
){
//what's the difference between fieldlen
unsigned
long
*
fieldLen
=
mysql_fetch_lengths
(
dbres
->
n
);
std
::
vector
<
std
::
string
>
curRow
;
for
(
int
i
=
0
;
i
<
numOfFields
;
i
++
){
if
(
i
==
0
)
{
while
(
(
field
=
mysql_fetch_field
(
dbres
->
n
))
)
{
myRaw
.
fieldNames
.
push_back
(
std
::
string
(
field
->
name
));
myRaw
.
fieldTypes
.
push_back
(
field
->
type
);
//myRaw.lengths.push_back(field->length);
//myRaw.lengths.push_back(fieldLen[i]);
myRaw
.
lengths
.
push_back
(
field
->
max_length
);
myRaw
.
maxlengths
.
push_back
(
field
->
max_length
);
//cout<<field->length<<"::"<<field->max_length<<endl;
}
}
if
(
row
[
i
]
==
NULL
)
curRow
.
push_back
(
"NULL"
);
else
curRow
.
push_back
(
std
::
string
(
row
[
i
],
fieldLen
[
i
]));
}
myRaw
.
rowValues
.
push_back
(
curRow
);
}
}
return
myRaw
;
}
//helper function for transforming the rawMySQLReturnValue
static
Item_null
*
make_null
(
const
std
::
string
&
name
=
""
){
char
*
const
n
=
current_thd
->
strdup
(
name
.
c_str
());
return
new
Item_null
(
n
);
}
//helper function for transforming the rawMySQLReturnValue
static
std
::
vector
<
Item
*>
itemNullVector
(
unsigned
int
count
)
{
std
::
vector
<
Item
*>
out
;
for
(
unsigned
int
i
=
0
;
i
<
count
;
++
i
)
{
out
.
push_back
(
make_null
());
}
return
out
;
}
//transform rawMySQLReturnValue to ResType
static
ResType
MygetResTypeFromLuaTable
(
bool
isNULL
,
rawMySQLReturnValue
*
inRow
=
NULL
,
int
in_last_insert_id
=
0
){
std
::
vector
<
std
::
string
>
names
;
std
::
vector
<
enum_field_types
>
types
;
std
::
vector
<
std
::
vector
<
Item
*>
>
rows
;
//return NULL restype
if
(
isNULL
){
return
ResType
(
true
,
0
,
0
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
else
{
for
(
auto
inNames
:
inRow
->
fieldNames
){
names
.
push_back
(
inNames
);
}
for
(
auto
inTypes
:
inRow
->
fieldTypes
){
types
.
push_back
(
static_cast
<
enum_field_types
>
(
inTypes
));
}
for
(
auto
inRows
:
inRow
->
rowValues
)
{
std
::
vector
<
Item
*>
curTempRow
=
itemNullVector
(
types
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)(
inRows
.
size
());
i
++
){
curTempRow
[
i
]
=
(
MySQLFieldTypeToItem
(
types
[
i
],
inRows
[
i
])
);
}
rows
.
push_back
(
curTempRow
);
}
return
ResType
(
true
,
0
,
in_last_insert_id
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
}
//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
;
FieldMeta
*
originalFm
;
vector
<
int
>
choosenOnions
;
//used to construct return meta
int
onionIndex
=
0
;
int
numOfOnions
=
0
;
//onions
std
::
vector
<
std
::
string
>
fields
;
std
::
vector
<
onion
>
onions
;
std
::
vector
<
OnionMeta
*>
originalOm
;
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
;
}
};
/*for each field, convert the format to transField*/
static
std
::
vector
<
transField
>
getTransField
(
std
::
vector
<
FieldMeta
*>
pfms
){
std
::
vector
<
transField
>
res
;
//for every field
for
(
auto
pfm
:
pfms
){
transField
tf
;
tf
.
originalFm
=
pfm
;
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
());
tf
.
originalOm
.
push_back
(
ompair
.
second
);
}
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
());
std
::
function
<
DBMeta
*
(
DBMeta
*
const
)
>
loadChildren
=
[
&
loadChildren
,
&
e_conn
](
DBMeta
*
const
parent
)
{
auto
kids
=
parent
->
fetchChildren
(
e_conn
);
for
(
auto
it
:
kids
)
{
loadChildren
(
it
);
}
return
parent
;
};
//load all metadata and then store it in schema
loadChildren
(
schema
.
get
());
Analysis
analysis
(
std
::
string
(
"student"
),
*
schema
,
std
::
unique_ptr
<
AES_KEY
>
(
getKey
(
std
::
string
(
"113341234"
))),
SECURITY_RATING
::
SENSITIVE
);
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
;
}
/*
structure of return field.
map<int,returnField>, int is the index of names
returnField, represent a field, if the field is not salt, then fieldCalled is the plaintex name
*/
static
ResType
decryptResults
(
const
ResType
&
dbres
,
const
ReturnMeta
&
rmeta
)
{
//num of rows
const
unsigned
int
rows
=
dbres
.
rows
.
size
();
//num of names, to be decrypted
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
);
//real cols depends on plain text names.
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
;
}
//specify fieldMeta, onion, and salt should be able to decrpyt
//peel onion
dec_rows
[
r
][
col_index
]
=
decrypt_item_layers
(
*
dbres
.
rows
[
r
][
c
],
fm
,
rf
.
getOLK
().
o
,
salt
);
}
}
col_index
++
;
}
std
::
vector
<
enum_field_types
>
types
;
for
(
auto
item
:
dec_rows
[
0
]){
types
.
push_back
(
item
->
field_type
());
}
//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
>
(
types
),
//different from previous version
std
::
move
(
dec_rows
));
}
struct
meta_file
{
string
db
,
table
;
int
num_of_fields
;
vector
<
string
>
field_types
;
vector
<
int
>
field_lengths
;
vector
<
string
>
field_names
;
vector
<
int
>
choosen_onions
;
void
show
(){
cout
<<
db
<<
endl
;
cout
<<
table
<<
endl
;
cout
<<
num_of_fields
<<
endl
;
for
(
auto
item
:
field_types
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_lengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_names
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
choosen_onions
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
}
};
static
void
init
(){
std
::
string
client
=
"192.168.1.1:1234"
;
//one Wrapper per user.
clients
[
client
]
=
new
WrapperState
();
//Connect phase
ConnectionInfo
ci
(
"localhost"
,
"root"
,
"letmein"
,
3306
);
const
std
::
string
master_key
=
"113341234"
;
char
*
buffer
;
if
((
buffer
=
getcwd
(
NULL
,
0
))
==
NULL
){
perror
(
"getcwd error"
);
}
embeddedDir
=
std
::
string
(
buffer
)
+
"/shadow"
;
SharedProxyState
*
shared_ps
=
new
SharedProxyState
(
ci
,
embeddedDir
,
master_key
,
determineSecurityRating
());
assert
(
0
==
mysql_thread_init
());
//we init embedded database here.
clients
[
client
]
->
ps
=
std
::
unique_ptr
<
ProxyState
>
(
new
ProxyState
(
*
shared_ps
));
clients
[
client
]
->
ps
->
safeCreateEmbeddedTHD
();
//Connect end!!
globalConn
=
new
Connect
(
ci
.
server
,
ci
.
user
,
ci
.
passwd
,
ci
.
port
);
}
static
void
transform_to_rawMySQLReturnValue
(
rawMySQLReturnValue
&
str
,
ResType
&
item
){
for
(
auto
row
:
item
.
rows
){
std
::
vector
<
string
>
temp
;
for
(
auto
item
:
row
){
temp
.
push_back
(
ItemToString
(
*
item
));
}
str
.
rowValues
.
push_back
(
temp
);
}
str
.
fieldTypes
=
item
.
types
;
}
static
void
construct_insert
(
rawMySQLReturnValue
&
str
,
std
::
string
table
,
std
::
vector
<
string
>
&
res
){
std
::
string
head
=
string
(
"INSERT INTO `"
)
+
table
+
"` VALUES "
;
int
cnt
=
0
;
string
cur
=
head
;
for
(
unsigned
int
i
=
0u
;
i
<
str
.
rowValues
.
size
();
i
++
){
++
cnt
;
cur
+=
"("
;
for
(
unsigned
int
j
=
0u
;
j
<
str
.
rowValues
[
i
].
size
();
j
++
){
if
(
IS_NUM
(
str
.
fieldTypes
[
j
]))
{
// cout<<str.fieldTypes[j]<<endl;
cur
+=
str
.
rowValues
[
i
][
j
]
+=
","
;
// cout<<"isnum"<<endl;
}
else
{
//cur+=string("\"")+=str.rowValues[i][j]+="\",";
int
len
=
str
.
rowValues
[
i
][
j
].
size
();
mysql_real_escape_string
(
globalConn
->
get_conn
(),
globalEsp
,
str
.
rowValues
[
i
][
j
].
c_str
(),
len
);
cur
+=
string
(
"
\"
"
)
+=
string
(
globalEsp
)
+=
"
\"
,"
;
}
}
cur
.
back
()
=
')'
;
cur
+=
","
;
if
(
cnt
==
num_of_pipe
){
cnt
=
0
;
cur
.
back
()
=
';'
;
res
.
push_back
(
cur
);
cur
=
head
;
}
}
if
(
cnt
!=
0
){
cur
.
back
()
=
';'
;
res
.
push_back
(
cur
);
}
}
debug/store.cc
View file @
0e66ba42
#include "debug/store.hh"
#include "debug/store.hh"
/*for each field, convert the format to transField*/
static
std
::
vector
<
transField
>
getTransField
(
std
::
vector
<
FieldMeta
*>
pfms
){
std
::
vector
<
transField
>
res
;
//for every field
for
(
auto
pfm
:
pfms
){
transField
tf
;
tf
.
originalFm
=
pfm
;
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
());
tf
.
originalOm
.
push_back
(
ompair
.
second
);
}
if
(
pfm
->
getHasSalt
()){
tf
.
hasSalt
=
true
;
tf
.
fields
.
push_back
(
pfm
->
getSaltName
());
}
res
.
push_back
(
tf
);
}
return
res
;
}
//query for testing purposes
static
std
::
string
getTestQuery
(
SchemaInfo
&
schema
,
std
::
vector
<
transField
>
&
tfds
,
std
::
string
db
=
"tdb"
,
std
::
string
table
=
"student1"
){
std
::
string
res
=
"SELECT "
;
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
db
));
//get databaseMeta, search in the map
DatabaseMeta
*
dbm
=
schema
.
getChild
(
*
dbmeta_key
);
const
TableMeta
&
tbm
=
*
((
*
dbm
).
getChild
(
IdentityMetaKey
(
table
)));
std
::
string
annotablename
=
tbm
.
getAnonTableName
();
//then a list of onion names
for
(
auto
item
:
tfds
){
for
(
auto
index
:
item
.
choosenOnions
){
res
+=
item
.
fields
[
index
];
res
+=
" , "
;
}
if
(
item
.
hasSalt
){
res
+=
item
.
originalFm
->
getSaltName
()
+
" , "
;
}
}
res
=
res
.
substr
(
0
,
res
.
size
()
-
2
);
res
=
res
+
"FROM `"
+
db
+
std
::
string
(
"`.`"
)
+
annotablename
+
"`"
;
return
res
;
}
/*
only support relative path
*/
static
bool
make_path
(
string
directory
){
struct
stat
st
;
if
(
directory
.
size
()
==
0
||
directory
[
0
]
==
'/'
)
return
false
;
if
(
directory
.
back
()
==
'/'
)
directory
.
pop_back
();
int
start
=
0
,
next
=
0
;
while
(
stat
(
directory
.
c_str
(),
&
st
)
==-
1
&&
next
!=-
1
){
next
=
directory
.
find
(
'/'
,
start
);
if
(
next
!=-
1
){
string
sub
=
directory
.
substr
(
0
,
next
);
if
(
stat
(
sub
.
c_str
(),
&
st
)
==-
1
)
mkdir
(
sub
.
c_str
(),
0700
);
start
=
next
+
1
;
}
else
{
mkdir
(
directory
.
c_str
(),
0700
);
}
}
return
true
;
}
static
void
write_meta
(
rawMySQLReturnValue
&
resraw
,
string
db
,
string
table
){
static
void
write_meta
(
rawMySQLReturnValue
&
resraw
,
string
db
,
string
table
){
//write metadata
//write metadata
FILE
*
localmeta
=
NULL
;
// FILE * localmeta = NULL;
metadata_file
mf
;
mf
.
set_db_table
(
db
,
table
);
mf
.
set_num_of_fields
(
resraw
.
fieldNames
.
size
());
std
::
vector
<
std
::
string
>
temp
;
for
(
auto
item
:
resraw
.
fieldTypes
){
temp
.
push_back
(
std
::
to_string
(
static_cast
<
int
>
(
item
)));
}
mf
.
set_field_types
(
temp
);
mf
.
set_field_lengths
(
resraw
.
lengths
);
mf
.
set_field_names
(
resraw
.
fieldNames
);
mf
.
set_choosen_onions
(
resraw
.
choosen_onions
);
mf
.
serilize
();
/*
string prefix = string("data/")+db+"/"+table;
string prefix = string("data/")+db+"/"+table;
make_path(prefix);
make_path(prefix);
localmeta = fopen((prefix+"/metadata.data").c_str(),"w");
localmeta = fopen((prefix+"/metadata.data").c_str(),"w");
...
@@ -85,6 +27,7 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
...
@@ -85,6 +27,7 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
fwrite(s.c_str(),1,s.size(),localmeta);
fwrite(s.c_str(),1,s.size(),localmeta);
s = string("num_of_fields:")+to_string(resraw.fieldNames.size())+"\n";
s = string("num_of_fields:")+to_string(resraw.fieldNames.size())+"\n";
fwrite(s.c_str(),1,s.size(),localmeta);
fwrite(s.c_str(),1,s.size(),localmeta);
s = string("field_types:");
s = string("field_types:");
for(auto item:resraw.fieldTypes){
for(auto item:resraw.fieldTypes){
s+=std::to_string(item)+=" ";
s+=std::to_string(item)+=" ";
...
@@ -98,14 +41,12 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
...
@@ -98,14 +41,12 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
}
}
s.back()='\n';
s.back()='\n';
fwrite(s.c_str(),1,s.size(),localmeta);
fwrite(s.c_str(),1,s.size(),localmeta);
s = string("field_names:");
s = string("field_names:");
for(auto item : resraw.fieldNames){
for(auto item : resraw.fieldNames){
s+=item+=" ";
s+=item+=" ";
}
}
s.back()='\n';
s.back()='\n';
fwrite(s.c_str(),1,s.size(),localmeta);
fwrite(s.c_str(),1,s.size(),localmeta);
s = string("choosen_onions:");
s = string("choosen_onions:");
for(auto item : resraw.choosen_onions){
for(auto item : resraw.choosen_onions){
s+=to_string(item)+=" ";
s+=to_string(item)+=" ";
...
@@ -113,6 +54,7 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
...
@@ -113,6 +54,7 @@ static void write_meta(rawMySQLReturnValue& resraw,string db,string table){
s.back()='\n';
s.back()='\n';
fwrite(s.c_str(),1,s.size(),localmeta);
fwrite(s.c_str(),1,s.size(),localmeta);
fclose(localmeta);
fclose(localmeta);
*/
}
}
...
...
debug/store.hh
View file @
0e66ba42
...
@@ -291,40 +291,168 @@ std::shared_ptr<ReturnMeta> getReturnMeta(std::vector<FieldMeta*> fms, std::vect
...
@@ -291,40 +291,168 @@ std::shared_ptr<ReturnMeta> getReturnMeta(std::vector<FieldMeta*> fms, std::vect
return
myReturnMeta
;
return
myReturnMeta
;
}
}
/*
only support relative path
*/
static
bool
make_path
(
string
directory
){
struct
stat
st
;
if
(
directory
.
size
()
==
0
||
directory
[
0
]
==
'/'
)
return
false
;
if
(
directory
.
back
()
==
'/'
)
directory
.
pop_back
();
int
start
=
0
,
next
=
0
;
while
(
stat
(
directory
.
c_str
(),
&
st
)
==-
1
&&
next
!=-
1
){
next
=
directory
.
find
(
'/'
,
start
);
if
(
next
!=-
1
){
string
sub
=
directory
.
substr
(
0
,
next
);
if
(
stat
(
sub
.
c_str
(),
&
st
)
==-
1
)
mkdir
(
sub
.
c_str
(),
0700
);
start
=
next
+
1
;
}
else
{
mkdir
(
directory
.
c_str
(),
0700
);
}
}
return
true
;
}
class
metadata_file
{
struct
meta_file
{
string
db
,
table
;
string
db
,
table
;
int
num_of_fields
;
int
num_of_fields
;
vector
<
string
>
field_types
;
vector
<
string
>
field_types
;
vector
<
int
>
field_lengths
;
vector
<
int
>
field_lengths
;
vector
<
string
>
field_names
;
vector
<
string
>
field_names
;
vector
<
int
>
choosen_onions
;
vector
<
int
>
choosen_onions
;
public
:
void
set_db_table
(
std
::
string
idb
,
std
::
string
itable
){
db
=
idb
;
table
=
itable
;}
void
set_num_of_fields
(
int
num
){
num_of_fields
=
num
;}
void
set_field_types
(
vector
<
string
>
input
){
field_types
=
input
;}
void
set_field_lengths
(
vector
<
int
>
input
){
field_lengths
=
input
;}
void
set_field_names
(
vector
<
string
>
input
){
field_names
=
input
;}
void
set_choosen_onions
(
vector
<
int
>
input
){
choosen_onions
=
input
;}
void
serilize
();
void
deserilize
();
void
show
();
};
void
metadata_file
::
serilize
(){
FILE
*
localmeta
=
NULL
;
string
prefix
=
string
(
"data/"
)
+
db
+
"/"
+
table
;
make_path
(
prefix
);
localmeta
=
fopen
((
prefix
+
"/metadata.data"
).
c_str
(),
"w"
);
string
s
=
string
(
"database:"
)
+
db
;
s
+=
"
\n
"
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"table:"
)
+
table
;
s
+=
"
\n
"
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"num_of_fields:"
)
+
to_string
(
num_of_fields
)
+
"
\n
"
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"field_types:"
);
for
(
auto
item
:
field_types
){
s
+=
item
+=
" "
;
}
s
.
back
()
=
'\n'
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"field_lengths:"
);
for
(
auto
item
:
field_lengths
){
s
+=
to_string
(
item
)
+=
" "
;
}
s
.
back
()
=
'\n'
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"field_names:"
);
for
(
auto
item
:
field_names
){
s
+=
item
+=
" "
;
}
s
.
back
()
=
'\n'
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
s
=
string
(
"choosen_onions:"
);
for
(
auto
item
:
choosen_onions
){
s
+=
to_string
(
item
)
+=
" "
;
}
s
.
back
()
=
'\n'
;
fwrite
(
s
.
c_str
(),
1
,
s
.
size
(),
localmeta
);
fclose
(
localmeta
);
}
void
metadata_file
::
deserilize
(){
}
void
metadata_file
::
show
(){
cout
<<
db
<<
endl
;
cout
<<
table
<<
endl
;
cout
<<
num_of_fields
<<
endl
;
for
(
auto
item
:
field_types
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_lengths
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
field_names
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
for
(
auto
item
:
choosen_onions
){
cout
<<
item
<<
"
\t
"
;
}
cout
<<
endl
;
}
void
show
(){
cout
<<
db
<<
endl
;
/*for each field, convert the format to transField*/
cout
<<
table
<<
endl
;
static
std
::
vector
<
transField
>
getTransField
(
std
::
vector
<
FieldMeta
*>
pfms
){
cout
<<
num_of_fields
<<
endl
;
std
::
vector
<
transField
>
res
;
for
(
auto
item
:
field_types
){
//for every field
cout
<<
item
<<
"
\t
"
;
for
(
auto
pfm
:
pfms
){
transField
tf
;
tf
.
originalFm
=
pfm
;
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
());
tf
.
originalOm
.
push_back
(
ompair
.
second
);
}
}
cout
<<
endl
;
if
(
pfm
->
getHasSalt
()){
for
(
auto
item
:
field_lengths
){
tf
.
hasSalt
=
true
;
cout
<<
item
<<
"
\t
"
;
tf
.
fields
.
push_back
(
pfm
->
getSaltName
())
;
}
}
res
.
push_back
(
tf
);
}
return
res
;
}
cout
<<
endl
;
for
(
auto
item
:
field_names
){
//query for testing purposes
cout
<<
item
<<
"
\t
"
;
static
std
::
string
getTestQuery
(
SchemaInfo
&
schema
,
std
::
vector
<
transField
>
&
tfds
,
std
::
string
db
=
"tdb"
,
std
::
string
table
=
"student1"
){
std
::
string
res
=
"SELECT "
;
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
db
));
//get databaseMeta, search in the map
DatabaseMeta
*
dbm
=
schema
.
getChild
(
*
dbmeta_key
);
const
TableMeta
&
tbm
=
*
((
*
dbm
).
getChild
(
IdentityMetaKey
(
table
)));
std
::
string
annotablename
=
tbm
.
getAnonTableName
();
//then a list of onion names
for
(
auto
item
:
tfds
){
for
(
auto
index
:
item
.
choosenOnions
){
res
+=
item
.
fields
[
index
];
res
+=
" , "
;
}
}
cout
<<
endl
;
if
(
item
.
hasSalt
){
for
(
auto
item
:
choosen_onions
){
res
+=
item
.
originalFm
->
getSaltName
()
+
" , "
;
cout
<<
item
<<
"
\t
"
;
}
}
cout
<<
endl
;
}
}
};
res
=
res
.
substr
(
0
,
res
.
size
()
-
2
);
res
=
res
+
"FROM `"
+
db
+
std
::
string
(
"`.`"
)
+
annotablename
+
"`"
;
return
res
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment