Skip to content

Commit e1daffe

Browse files
committed
add a sfTxsHashFillField field to implement "concat" command in sql statement
1 parent 46e5a0a commit e1daffe

File tree

5 files changed

+135
-67
lines changed

5 files changed

+135
-67
lines changed

src/peersafe/app/sql/SQLDataType.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class FieldValue {
105105
}
106106
}
107107

108-
enum { fVARCHAR, fCHAR, fTEXT, fBLOB };
108+
enum { fVARCHAR, fCHAR, fTEXT, fBLOB,fCommand };
109109
explicit FieldValue(const std::string& value, int flag)
110110
: value_type_(STRING) {
111111

@@ -117,6 +117,8 @@ class FieldValue {
117117
value_type_ = TEXT;
118118
else if (flag == fBLOB)
119119
value_type_ = BLOB;
120+
else if (flag == fCommand)
121+
value_type_ = COMMAND;
120122

121123
value_.str = new std::string;
122124
if (value_.str) {
@@ -189,7 +191,7 @@ class FieldValue {
189191
}
190192
else if (value_type_ == STRING || value_type_ == VARCHAR
191193
|| value_type_ == TEXT || value_type_ == BLOB
192-
|| value_type_ == CHAR) {
194+
|| value_type_ == CHAR || value_type_ == COMMAND) {
193195

194196
value_.str = new std::string;
195197
if (value_.str) {
@@ -560,10 +562,16 @@ class FieldValue {
560562
return value_type_ == DATE;
561563
}
562564

565+
563566
bool isNull() {
564567
return value_type_ == NULLTYPE;
565568
}
566569

570+
bool isCommand() const {
571+
return value_type_ == COMMAND;
572+
573+
}
574+
567575
const int& asInt() {
568576
return value_.i;
569577
}
@@ -644,6 +652,7 @@ class FieldValue {
644652
BLOB,
645653
STRING,
646654
NULLTYPE,
655+
COMMAND
647656
};
648657

649658
int value_type_;

src/peersafe/app/sql/STTx2SQL.cpp

Lines changed: 100 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace ripple {
4848

4949
class BuildField {
5050

51-
// propertiese of field
51+
// properties of field
5252
#define PK 0x00000001 // primary key
5353
#define NN 0x00000002 // not null
5454
#define UQ 0x00000004 // unique
@@ -341,10 +341,15 @@ class BuildField {
341341
return value_.isDate();
342342
}
343343

344+
344345
bool isNull() {
345346
return value_.isNull();
346347
}
347348

349+
bool isCommand() {
350+
return value_.isCommand();
351+
}
352+
348353
void SetPrimaryKey() {
349354
flag_ |= PK;
350355
}
@@ -444,7 +449,7 @@ std::pair<int, std::string> parseField(const Json::Value& json, BuildField& fiel
444449
InnerNull value;
445450
field.SetFieldValue(value);
446451
}else {
447-
std::string error = (boost::format("Unkown type when parsing fields.[%s]")
452+
std::string error = (boost::format("Unknown type when parsing fields.[%s]")
448453
%Json::jsonAsString(val)).str();
449454
return{ -1, error };
450455
}
@@ -1075,6 +1080,10 @@ class DisposeSQL {
10751080
update_fields += (boost::format("%1%=%2%")
10761081
%field.Name()
10771082
%field.asInt64()).str();
1083+
}else if (field.isCommand()) {
1084+
update_fields += (boost::format("%1%=%2%")
1085+
% field.Name()
1086+
% field.asString()).str();
10781087
}
10791088
else if (field.isNull()) {
10801089
update_fields += (boost::format("%1%=%2%")
@@ -1121,10 +1130,16 @@ class DisposeSQL {
11211130

11221131
std::string& tablename = tables_[0];
11231132
std::string update_fields;
1133+
1134+
std::string update_command_fields;
11241135

11251136
index_ = 0;
11261137
for (size_t idx = 0; idx < fields_.size(); idx++) {
11271138
BuildField& field = fields_[idx];
1139+
if (field.isCommand()) {
1140+
update_command_fields = field.Name() + std::string("=") + field.asString();
1141+
continue;
1142+
}
11281143
update_fields += field.Name() + std::string("=:") + std::to_string(++index_);
11291144
if (idx != fields_.size() - 1)
11301145
update_fields += ",";
@@ -1133,16 +1148,23 @@ class DisposeSQL {
11331148
auto conditions = build_execute_conditions();
11341149
if (std::get<0>(conditions) == 0) {
11351150
const std::string& c = std::get<1>(conditions);
1151+
1152+
// similar to this sql statement £º update table_01 set age=1,name=concat("a_",name);
1153+
if (!update_command_fields.empty()) {
1154+
std::string extraComma = (update_fields.back() == ',' ? std::string("") : std::string(","));
1155+
update_fields += extraComma + update_command_fields;
1156+
}
1157+
11361158
if (c.empty()) {
11371159
sql_str = (boost::format("update %s set %s")
11381160
% tablename
1139-
%update_fields).str();
1161+
% update_fields).str();
11401162
}
11411163
else {
11421164
sql_str = (boost::format("update %s set %s where %s")
11431165
% tablename
1144-
%update_fields
1145-
%c).str();
1166+
% update_fields
1167+
% c).str();
11461168
}
11471169

11481170
LockedSociSession sql = db_conn_->checkoutDb();
@@ -1157,7 +1179,7 @@ class DisposeSQL {
11571179
}
11581180
}
11591181
// fix an issue that we can't catch an exception on top-level,
1160-
// beacause desctructor of one-temp-type driver to execute actual SQL-engine API.
1182+
// because destructor of one-temp-type driver to execute actual SQL-engine API.
11611183
// however destructor can catch an exception but can't throw an exception that was catched by destructor.
11621184
//if (db_conn_->getSession().last_error().first != 0) {
11631185
// last_error(db_conn_->getSession().last_error());
@@ -1652,8 +1674,9 @@ class DisposeSQL {
16521674
for (size_t idx = 0; idx < fields_.size(); idx++) {
16531675
BuildField& field = fields_[idx];
16541676
if (field.isString() || field.isVarchar()
1655-
|| field.isBlob() || field.isText())
1677+
|| field.isBlob() || field.isText()) {
16561678
t = t, soci::use(field.asString());
1679+
}
16571680
else if (field.isInt())
16581681
t = t, soci::use(field.asInt());
16591682
else if (field.isFloat())
@@ -1668,7 +1691,7 @@ class DisposeSQL {
16681691
}
16691692

16701693
BuildSQL::BUILDTYPE build_type_;
1671-
int index_;
1694+
int index_;
16721695
BuildSQL::OrConditionsType conditions_;
16731696
DatabaseCon* db_conn_;
16741697
Json::Value condition_;
@@ -2353,7 +2376,9 @@ class BuildSqlite : public BuildSQL {
23532376

23542377
namespace helper {
23552378

2379+
23562380
std::pair<int, std::string> ParseQueryJson(const Json::Value& tx_json, BuildSQL &buildsql) {
2381+
23572382
std::string error = "Unknown Error when parse json";
23582383
int code = 0;
23592384
do {
@@ -3325,13 +3350,13 @@ std::pair<bool, std::string> STTx2SQL::check_optionalRule(const std::string& opt
33253350
}
33263351

33273352
std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const ripple::STTx& tx, const std::string& sOperationRule /* = "" */,
3328-
bool bVerifyAffectedRows /* = false */){
3353+
bool bVerifyAffectedRows /* = false */) {
33293354
std::pair<int, std::string> ret = { -1, "inner error" };
33303355
if (tx.getTxnType() != ttTABLELISTSET && tx.getTxnType() != ttSQLSTATEMENT) {
33313356
ret = { -1, "Transaction's type is error." };
33323357
return ret;
33333358
}
3334-
3359+
33353360
uint16_t optype = tx.getFieldU16(sfOpType);
33363361
const ripple::STArray& tables = tx.getFieldArray(sfTables);
33373362
ripple::uint160 hex_tablename = tables[0].getFieldH160(sfNameInDB);
@@ -3356,7 +3381,7 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
33563381
Json::Value raw_json;
33573382
if (sRaw.size()) {
33583383
if (Json::Reader().parse(sRaw, raw_json) == false) {
3359-
ret = { -1, "parase Raw unsuccessfully." };
3384+
ret = { -1, "parse Raw unsuccessfully." };
33603385
return ret;
33613386
}
33623387
}
@@ -3366,7 +3391,7 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
33663391
}
33673392

33683393
if (check_raw(raw_json, optype) == false) {
3369-
ret = { -1, (boost::format("Raw data is malformed. %s") %Json::jsonAsString(raw_json)).str() };
3394+
ret = { -1, (boost::format("Raw data is malformed. %s") % Json::jsonAsString(raw_json)).str() };
33703395
return ret;
33713396
}
33723397

@@ -3400,9 +3425,9 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
34003425
case 10:
34013426
build_type = BuildSQL::BUILD_ASSERT_STATEMENT;
34023427
break;
3403-
case 12:
3404-
build_type = BuildSQL::BUILD_RECREATE_SQL;
3405-
break;
3428+
case 12:
3429+
build_type = BuildSQL::BUILD_RECREATE_SQL;
3430+
break;
34063431
default:
34073432
break;
34083433
}
@@ -3436,6 +3461,22 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
34363461
}
34373462

34383463

3464+
bool bHasTxsHashField = false;
3465+
std::string sTxsHashFillField;
3466+
if (tx.isFieldPresent(sfTxsHashFillField))
3467+
{
3468+
auto blob = tx.getFieldVL(sfTxsHashFillField);;
3469+
sTxsHashFillField.assign(blob.begin(), blob.end());
3470+
auto sql_str = (boost::format("select * from information_schema.columns WHERE table_name ='%s'AND column_name ='%s'")
3471+
% txt_tablename
3472+
% sTxsHashFillField).str();
3473+
LockedSociSession sql = db_conn_->checkoutDb();
3474+
soci::rowset<soci::row> records = ((*sql).prepare << sql_str);
3475+
3476+
bHasTxsHashField = records.end() != records.begin();
3477+
}
3478+
3479+
34393480
if (build_type == BuildSQL::BUILD_INSERT_SQL) {
34403481
std::string sql;
34413482

@@ -3444,26 +3485,34 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
34443485
auto& v = raw_json[idx];
34453486
if (v.isObject() == false) {
34463487
//JSON_ASSERT(v.isObject());
3447-
ret = { -1, "Element of raw may be malformal." };
3488+
ret = { -1, "Element of raw may be malformed." };
34483489
return ret;
34493490
}
34503491

34513492
auto retPair = GenerateInsertSql(v, buildsql.get());
3452-
if(retPair.first != 0) {
3493+
if (retPair.first != 0) {
34533494
return retPair;
34543495
}
3455-
if (bHasAutoField)
3456-
{
3457-
BuildField insert_field(sAutoFillField);
3458-
insert_field.SetFieldValue(to_string(tx.getTransactionID()));
3459-
buildsql->AddField(insert_field);
3460-
}
3461-
3496+
3497+
if (bHasAutoField)
3498+
{
3499+
BuildField insert_field(sAutoFillField);
3500+
insert_field.SetFieldValue(to_string(tx.getTransactionID()));
3501+
buildsql->AddField(insert_field);
3502+
}
3503+
3504+
if (bHasTxsHashField)
3505+
{
3506+
BuildField insert_tx_field(sTxsHashFillField);
3507+
insert_tx_field.SetFieldValue(to_string(tx.getTransactionID()));
3508+
buildsql->AddField(insert_tx_field);
3509+
}
3510+
34623511
sql += buildsql->asString();
3463-
if(buildsql->execSQL() != 0) {
3512+
if (buildsql->execSQL() != 0) {
34643513
//ret = { -1, std::string("Executing SQL was failure.") + sql };
34653514
ret = { -1, (boost::format("Executing `%1%` was failure. %2%")
3466-
%sql
3515+
% sql
34673516
%buildsql->last_error().second).str() };
34683517
return ret;
34693518
}
@@ -3476,38 +3525,38 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
34763525
if (idx != raw_json.size() - 1)
34773526
sql += ";";
34783527
}
3479-
if(bVerifyAffectedRows && affected_rows == 0)
3480-
return{ -1, "insert operation affect 0 rows." };
3481-
3482-
return{0, sql};
3528+
3529+
if (bVerifyAffectedRows && affected_rows == 0)
3530+
return{ -1, "insert operation affect 0 rows." };
3531+
3532+
return{ 0, sql };
34833533
}
34843534
else if (build_type == BuildSQL::BUILD_ASSERT_STATEMENT) {
34853535
auto result = handle_assert_statement(raw_json, buildsql.get());
34863536
if (result.first) {
3487-
return{0, result.second};
3537+
return{ 0, result.second };
34883538
}
3489-
return{1, result.second};
3539+
return{ 1, result.second };
34903540
}
34913541

34923542

34933543
int result = -1;
34943544

3495-
if (build_type == BuildSQL::BUILD_UPDATE_SQL){
3545+
if (build_type == BuildSQL::BUILD_UPDATE_SQL) {
34963546

34973547
Json::Value conditions;
3498-
34993548
// parse record
35003549
for (Json::UInt idx = 0; idx < raw_json.size(); idx++) {
35013550
auto& v = raw_json[idx];
35023551
if (v.isObject() == false) {
35033552
//JSON_ASSERT(v.isObject());
3504-
result= -1;
3553+
result = -1;
35053554
}
35063555

35073556
if (idx == 0) {
35083557
std::vector<std::string> members = v.getMemberNames();
35093558

3510-
if (bHasAutoField){
3559+
if (bHasAutoField) {
35113560
BuildField update_field(sAutoFillField);
35123561
update_field.SetFieldValue(to_string(tx.getTransactionID()));
35133562
buildsql->AddField(update_field);
@@ -3525,7 +3574,7 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
35253574
BuildField field(field_name);
35263575
std::pair<int, std::string> ret = parseField(v[field_name], field);
35273576
if (ret.first != 0) {
3528-
result = ret.first;
3577+
result = ret.first;
35293578
}
35303579
buildsql->AddField(field);
35313580
}
@@ -3535,6 +3584,13 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
35353584
}
35363585
}
35373586

3587+
if (bHasTxsHashField) {
3588+
BuildField update_field(sTxsHashFillField);
3589+
std::string updateStr = (boost::format("concat(%1%,\",%2%\")") % sTxsHashFillField % to_string(tx.getTransactionID())).str();
3590+
update_field.SetFieldValue(updateStr, FieldValue::fCommand);
3591+
buildsql->AddField(update_field);
3592+
}
3593+
35383594
if (conditions.isArray() && conditions.size() > 0)
35393595
buildsql->AddCondition(conditions);
35403596

@@ -3557,15 +3613,15 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
35573613
break;
35583614
case BuildSQL::BUILD_CANCEL_ASSIGN_SQL:
35593615
break;
3560-
//case BuildSQL::BUILD_UPDATE_SQL:
3561-
// result = GenerateUpdateSql(raw_json, buildsql.get());
3562-
// break;
3616+
//case BuildSQL::BUILD_UPDATE_SQL:
3617+
// result = GenerateUpdateSql(raw_json, buildsql.get());
3618+
// break;
35633619
case BuildSQL::BUILD_DELETE_SQL:
35643620
result = GenerateDeleteSql(raw_json, buildsql.get());
35653621
break;
3566-
case BuildSQL::BUILD_RECREATE_SQL:
3567-
result = GenerateCreateTableSql(raw_json, buildsql.get());
3568-
break;
3622+
case BuildSQL::BUILD_RECREATE_SQL:
3623+
result = GenerateCreateTableSql(raw_json, buildsql.get());
3624+
break;
35693625
default:
35703626
break;
35713627
}
@@ -3585,7 +3641,7 @@ std::pair<int /*retcode*/, std::string /*sql*/> STTx2SQL::ExecuteSQL(const rippl
35853641
ret = { -1, (boost::format("Execute `%1%` unsuccessfully. %2%")
35863642
% buildsql->asString()
35873643
% buildsql->last_error().second).str() };
3588-
}
3644+
}
35893645

35903646
return ret;
35913647
}

0 commit comments

Comments
 (0)