We can only replay if we have the full SQL, including parameters. That means 1) event logged a bindings array 2) event logged a nbindings integer, and it's 0 If there's non-zero bindings and we don't have them, we can't replay. Another complication is transactions - we don't want to play one back until we have all the statements collected, and see a commit event. Anything wi
| 767 | blocks gets logged before the txn log entry as well. |
| 768 | */ |
| 769 | void handle_sql(cdb2_hndl_tp *db, cson_value *event_val) { |
| 770 | int rc; |
| 771 | if (!is_replayable(event_val)) { |
| 772 | cson_free_value(event_val); |
| 773 | return; |
| 774 | } |
| 775 | |
| 776 | const char *cnonce = get_strprop(event_val, "cnonce"); |
| 777 | if (cnonce == nullptr) { // no cnonce if comdb2api -- just replay it |
| 778 | replay(db, event_val); |
| 779 | cson_free_value(event_val); |
| 780 | return; |
| 781 | } |
| 782 | |
| 783 | const char *sql = get_strprop(event_val, "sql"); |
| 784 | if (sql == NULL) |
| 785 | return; |
| 786 | if (strcmp(sql, "commit") == 0 || strcmp(sql, "rollback") == 0) { |
| 787 | if (!is_part_of_transaction(cnonce)) { |
| 788 | std::cerr << "Error: Commit/rollback record without cnonce in txn list (possibly already commited)" |
| 789 | << std::endl; |
| 790 | } else { |
| 791 | replay_transaction(db, event_val); |
| 792 | } |
| 793 | cson_free_value(event_val); |
| 794 | } else if (strcmp(sql, "begin") == 0 || is_part_of_transaction(cnonce)) { |
| 795 | add_to_transaction(event_val); // new entry in list, or append |
| 796 | } else { // normal 'sql' statement entry which are not part of a transaction |
| 797 | replay(db, event_val); // replay immediately |
| 798 | cson_free_value(event_val); |
| 799 | } |
| 800 | } |
| 801 | |
| 802 | /* TODO: error messages? */ |
| 803 | void handle_newsql(cdb2_hndl_tp *db, cson_value *val) { |
nothing calls this directly
no test coverage detected