@@ -48,7 +48,7 @@ namespace ripple {
4848
4949class 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
23542377namespace 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
33273352std::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