// File: /workspace/github_c_makefile_star2_O3/barabo[P]advanced-shell-history/src/database.cpp
// Function: ash::Database::exec(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int) const
ResultSet * Database::exec(const string & query, const int limit) const {
  // Load the relevant configured values.
  Config & config = Config::instance();

  int max_retries = config.get_int("DB_MAX_RETRIES", -1);
  if (max_retries <= 0) max_retries = 5;
  int tries = max_retries + 1, fetched = 0;

  ResultSet::HeadersType headers;
  ResultSet::DataType results;
  stringstream ss;
  sqlite3_stmt * ps = prepare_stmt(query);
  unsigned int rows, columns = sqlite3_column_count(ps);

  // YES, this is a GOTO target.  This is used to implement the retry logic.
  // If a query fails because of a lock, it may goto this block to retry.
try_sql:
  fetched = 0;
  for (rows = 0; fetched < limit || limit <= 0; ++rows) {
    int result = sqlite3_step(ps);
    switch (result) {
      // TODO(cpa): add more cases to handle errors.
      case SQLITE_ROW:
        // build the list of header names, if this is the first row fetched.
        if (headers.empty()) {
          for (size_t c = 0; c < columns; ++c) {
            ss.str("");
            ss << sqlite3_column_name(ps, c);
            headers.push_back(ss.str());
          }
        }
        // Add the row data.
        results.push_back(ResultSet::RowType());
        for (size_t c = 0; c < columns; ++c) {
          ss.str("");
          if (sqlite3_column_text(ps, c)) {
            ss << sqlite3_column_text(ps, c);
          }
          results.back().push_back(ss.str());
        }
        ++fetched;
        continue;  // for loop
      case SQLITE_CONSTRAINT:
        // Note: there is no point retrying this type of error.
        LOG(DEBUG) << "constraint violation executing: '" << query << "'";
        goto finalize;
      case SQLITE_DONE:
        goto finalize;
      case SQLITE_LOCKED:  // Fallthrough.
      case SQLITE_BUSY: {
        // Abort if we are out of attempts.
        if (tries <= 0) {
          LOG(FATAL) << "Failed to unlock db: " << sqlite3_errmsg(db)
                     << "\nGave up after " << max_retries << " failures."
                     << "\nExecuting: '" << query << "'\n";
        }

        // Sleep some random number of milliseconds.
        ash_sleep();

        // Reset the prepared statement.
        sqlite3_finalize(ps);
        ps = prepare_stmt(query);

        // Decrement the try count and jump.
        --tries;
        LOG(WARNING) << "Database was locked, tries remaining: " << tries;
        goto try_sql;
      }
      default:
        sqlite3_finalize(ps);
        // TODO(cpa): remove this cerr line once the FATAL errors are redirected to stderr by default.
        cerr << "unknown sqlite3_step code: " << result << " executing '"
             << query << "'\nError:\n" << sqlite3_errmsg(db) << endl;
        LOG(FATAL) << "unknown sqlite3_step code: " << result
                   << " executing '" << query << "'\nError:\n"
                   << sqlite3_errmsg(db);
    }  // switch
  }  // for loop

  // Yes, another GOTO target.  This is used because there is a switch statement
  // within a for loop and it's convenient to break the loop within the switch.
finalize:
  sqlite3_finalize(ps);

  return rows ? new ResultSet(headers, results) : 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x518, %rsp            # imm = 0x518
movl %edx, 0x2c(%rsp)
movq %rsi, 0x10(%rsp)
movq %rdi, 0x18(%rsp)
callq 0x69cd0
movq %rax, %r14
leaq 0x80(%rsp), %rbx
movq %rbx, -0x10(%rbx)
leaq 0x13550(%rip), %rsi     # 0x7daf8
leaq 0x13557(%rip), %rdx     # 0x7db06
leaq 0x70(%rsp), %rdi
callq 0x68bce
leaq 0x70(%rsp), %rsi
movq %r14, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x69bfc
movl %eax, %ebp
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a5dc
callq 0x8390
testl %ebp, %ebp
movl $0x5, %eax
cmovgl %ebp, %eax
movq %rax, 0x30(%rsp)
leaq 0x58(%rsp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
xorl %eax, %eax
movq %rax, 0x10(%rcx)
movq %rax, 0x50(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
leaq 0x390(%rsp), %rdi
callq 0x8290
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x6b8b0
movq %rax, %r15
movq %rax, %rdi
callq 0x1059c
movl %eax, %ecx
movq 0x30(%rsp), %rax
incl %eax
movl %eax, 0x8(%rsp)
movl %ecx, 0x24(%rsp)
movl %ecx, %eax
movq %rax, 0x38(%rsp)
leaq 0x70(%rsp), %rbp
movl $0x0, 0x28(%rsp)
xorl %edx, %edx
movl %edx, 0xc(%rsp)
movq %r15, %rdi
callq 0xf576
movl %eax, %r12d
cmpl $0x63, %eax
jle 0x6a893
cmpl $0x64, %r12d
leaq 0x58(%rsp), %r14
jne 0x6a8ac
cmpl $0x0, 0x24(%rsp)
sete %al
cmpq %r14, 0x58(%rsp)
setne %cl
orb %al, %cl
jne 0x6a76f
xorl %r12d, %r12d
movq %rbx, 0x70(%rsp)
movq %rbp, %rdi
leaq 0x13d07(%rip), %rdx     # 0x7e3b0
movq %rdx, %rsi
callq 0x68bce
leaq 0x3a8(%rsp), %rdi
movq %rbp, %rsi
callq 0x85c0
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a6d0
callq 0x8390
movq %r15, %rdi
movl %r12d, %esi
callq 0x10889
movq %rax, %r13
testq %rax, %rax
je 0x6a700
movq %r13, %rdi
callq 0x8190
leaq 0x3a0(%rsp), %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x8470
jmp 0x6a727
movq 0x3a0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x3a0(%rsp), %rcx
leaq (%rcx,%rax), %rdi
movl 0x3c0(%rsp,%rax), %esi
orl $0x1, %esi
callq 0x86b0
movq %rbp, %rdi
leaq 0x3a8(%rsp), %rsi
callq 0x8630
movq %r14, %rdi
movq %rbp, %rsi
callq 0x6c134
movq %rax, %rdi
movq %r14, %rsi
callq 0x8070
incq 0x68(%rsp)
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a761
callq 0x8390
incq %r12
cmpq %r12, 0x38(%rsp)
jne 0x6a69a
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
movq $0x0, 0x80(%rsp)
leaq 0x40(%rsp), %rdi
movq %rbp, %rsi
callq 0x6be9c
movq %rbp, %rdi
callq 0x68b48
movl 0xc(%rsp), %edx
cmpl $0x0, 0x24(%rsp)
je 0x6a88c
xorl %r12d, %r12d
movq %rbx, 0x70(%rsp)
movq %rbp, %rdi
leaq 0x13bf7(%rip), %rdx     # 0x7e3b0
movq %rdx, %rsi
callq 0x68bce
leaq 0x3a8(%rsp), %rdi
movq %rbp, %rsi
callq 0x85c0
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a7e0
callq 0x8390
movq %r15, %rdi
movl %r12d, %esi
callq 0x10789
testq %rax, %rax
je 0x6a847
movq %r15, %rdi
movl %r12d, %esi
callq 0x10789
movq %rax, %r13
testq %rax, %rax
je 0x6a820
movq %r13, %rdi
callq 0x8190
leaq 0x3a0(%rsp), %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x8470
jmp 0x6a847
movq 0x3a0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x3a0(%rsp), %rcx
leaq (%rcx,%rax), %rdi
movl 0x3c0(%rsp,%rax), %esi
orl $0x1, %esi
callq 0x86b0
movq 0x48(%rsp), %r14
movq %rbp, %rdi
leaq 0x3a8(%rsp), %rsi
callq 0x8630
addq $-0x18, %r14
movq %r14, %rdi
movq %rbp, %rsi
callq 0x6bec8
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a87a
callq 0x8390
incq %r12
cmpq %r12, 0x38(%rsp)
movl 0xc(%rsp), %edx
jne 0x6a7aa
incl %edx
jmp 0x6aa5f
leal -0x5(%r12), %eax
cmpl $0x2, %eax
jb 0x6aa7e
cmpl $0x13, %r12d
jne 0x6a8b6
jmp 0x6abe1
cmpl $0x65, %r12d
je 0x6ac38
movq %r15, %rdi
callq 0xea51
movl $0x1b, %edx
movq 0x2971e(%rip), %rdi     # 0x93fe8
leaq 0x135d4(%rip), %rsi     # 0x7dea5
callq 0x8470
movq 0x2970b(%rip), %rdi     # 0x93fe8
movl %r12d, %esi
callq 0x86d0
movq %rax, %r13
movl $0xc, %edx
movq %rax, %rdi
leaq 0x135ca(%rip), %rsi     # 0x7dec1
callq 0x8470
movq 0x10(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r13, %rdi
callq 0x8470
movq %rax, %r13
movl $0x9, %edx
movq %rax, %rdi
leaq 0x135ac(%rip), %rsi     # 0x7dece
callq 0x8470
movq 0x18(%rsp), %rax
movq 0x28(%rax), %rdi
callq 0x12cc6
movq %rax, %r14
testq %rax, %rax
je 0x6a955
movq %r14, %rdi
callq 0x8190
movq %r13, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x8470
jmp 0x6a970
movq (%r13), %rax
movq -0x18(%rax), %rax
movq %r13, %rdi
addq %rax, %rdi
movl 0x20(%r13,%rax), %esi
orl $0x1, %esi
callq 0x86b0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x83c0
movsbl %al, %esi
movq %r13, %rdi
callq 0x8040
movq %rax, %rdi
callq 0x8250
movq %rbp, %rdi
movl $0x4, %esi
callq 0x6fef2
movl $0x1b, %edx
leaq 0x78(%rsp), %rdi
leaq 0x134ef(%rip), %rsi     # 0x7dea5
callq 0x8470
leaq 0x78(%rsp), %rdi
movl %r12d, %esi
callq 0x86d0
movq %rax, %r12
movl $0xc, %edx
movq %rax, %rdi
leaq 0x134e7(%rip), %rsi     # 0x7dec1
callq 0x8470
movq 0x10(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r12, %rdi
callq 0x8470
movq %rax, %r12
movl $0x9, %edx
movq %rax, %rdi
leaq 0x134c9(%rip), %rsi     # 0x7dece
callq 0x8470
movq 0x18(%rsp), %rax
movq 0x28(%rax), %rdi
callq 0x12cc6
movq %rax, %r14
testq %rax, %rax
je 0x6aa38
movq %r14, %rdi
callq 0x8190
movq %r12, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x8470
jmp 0x6aa53
movq (%r12), %rax
movq -0x18(%rax), %rax
movq %r12, %rdi
addq %rax, %rdi
movl 0x20(%r12,%rax), %esi
orl $0x1, %esi
callq 0x86b0
movq %rbp, %rdi
callq 0x70392
movl 0xc(%rsp), %edx
movl 0x2c(%rsp), %ecx
testl %ecx, %ecx
setle %al
incl 0x28(%rsp)
cmpl %ecx, %edx
setl %cl
orb %al, %cl
jne 0x6a658
jmp 0x6ac38
cmpl $0x0, 0x8(%rsp)
leaq 0x78(%rsp), %r14
jg 0x6ab82
movq %rbp, %rdi
movl $0x4, %esi
callq 0x6fef2
movl $0x15, %edx
leaq 0x78(%rsp), %rdi
leaq 0x1339b(%rip), %rsi     # 0x7de47
callq 0x8470
movq 0x18(%rsp), %rax
movq 0x28(%rax), %rdi
callq 0x12cc6
movq %rax, %r12
testq %rax, %rax
je 0x6aae1
movq %r12, %rdi
callq 0x8190
leaq 0x78(%rsp), %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x8470
jmp 0x6ab02
movq 0x78(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x78(%rsp), %rcx
leaq (%rcx,%rax), %rdi
movl 0x98(%rsp,%rax), %esi
orl $0x1, %esi
callq 0x86b0
movl $0xf, %edx
leaq 0x78(%rsp), %rdi
leaq 0x1334a(%rip), %rsi     # 0x7de5d
callq 0x8470
leaq 0x78(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x86d0
movq %rax, %r12
movl $0xa, %edx
movq %rax, %rdi
leaq 0x131cd(%rip), %rsi     # 0x7dd06
callq 0x8470
movl $0xd, %edx
movq %r12, %rdi
leaq 0x13320(%rip), %rsi     # 0x7de6d
callq 0x8470
movq 0x10(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r12, %rdi
callq 0x8470
movl $0x2, %edx
movq %rax, %rdi
leaq 0x13306(%rip), %rsi     # 0x7de7b
callq 0x8470
movq %rbp, %rdi
callq 0x70392
callq 0x6b03c
movq %r15, %rdi
callq 0xea51
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x6b8b0
movq %rax, %r15
movq %rbp, %rdi
movl $0x2, %esi
callq 0x6fef2
movl $0x26, %edx
movq %r14, %rdi
leaq 0x132c1(%rip), %rsi     # 0x7de7e
callq 0x8470
movl 0x8(%rsp), %esi
decl %esi
movq %r14, %rdi
movl %esi, 0x8(%rsp)
callq 0x86d0
movq %rbp, %rdi
callq 0x70392
jmp 0x6a64e
leaq 0x70(%rsp), %rdi
xorl %esi, %esi
callq 0x6fef2
leaq 0x78(%rsp), %rbx
leaq 0x1322c(%rip), %rsi     # 0x7de25
movl $0x21, %edx
movq %rbx, %rdi
callq 0x8470
movq 0x10(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %rbx, %rdi
callq 0x8470
leaq 0x13772(%rip), %rsi     # 0x7e393
movl $0x1, %edx
movq %rax, %rdi
callq 0x8470
leaq 0x70(%rsp), %rdi
callq 0x70392
movq %r15, %rdi
callq 0xea51
cmpl $0x0, 0x28(%rsp)
je 0x6ac68
movl $0x40, %edi
callq 0x83f0
movq %rax, %r14
leaq 0x58(%rsp), %rsi
leaq 0x40(%rsp), %rdx
movq %rax, %rdi
callq 0x69f14
jmp 0x6ac6b
xorl %r14d, %r14d
leaq 0x390(%rsp), %rdi
callq 0x87e8
leaq 0x40(%rsp), %rdi
callq 0x68af0
leaq 0x58(%rsp), %rdi
callq 0x68b92
movq %r14, %rax
addq $0x518, %rsp            # imm = 0x518
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6ad69
jmp 0x6ad69
movq %rax, %r15
movq %r14, %rdi
jmp 0x6ad60
movq %rax, %r15
leaq 0x70(%rsp), %rdi
callq 0x70392
jmp 0x6ad6c
movq %rax, %r15
jmp 0x6ad83
jmp 0x6ad69
movq %rax, %r15
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6ad8d
callq 0x8390
jmp 0x6ad8d
movq %rax, %r15
jmp 0x6ad8d
jmp 0x6ad69
movq %rax, %r15
leaq 0x70(%rsp), %rdi
callq 0x70392
jmp 0x6ad6c
jmp 0x6ad69
movq %rax, %r15
leaq 0x70(%rsp), %rdi
callq 0x70392
jmp 0x6ad6c
movq %rax, %r15
jmp 0x6ad79
jmp 0x6ad69
movq %rax, %r15
leaq 0x70(%rsp), %rdi
callq 0x68b48
jmp 0x6ad6c
jmp 0x6ad69
jmp 0x6ad69
movq %rax, %r15
leaq 0x70(%rsp), %rdi
callq 0x70392
jmp 0x6ad6c
jmp 0x6ad69
jmp 0x6ad53
jmp 0x6ad69
jmp 0x6ad53
jmp 0x6ad69
jmp 0x6ad53
jmp 0x6ad69
jmp 0x6ad69
movq %rax, %r15
movq 0x70(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6ad6c
callq 0x8390
jmp 0x6ad6c
jmp 0x6ad69
movq %rax, %r15
leaq 0x390(%rsp), %rdi
callq 0x87e8
leaq 0x40(%rsp), %rdi
callq 0x68af0
leaq 0x58(%rsp), %rdi
callq 0x68b92
movq %r15, %rdi
callq 0x8720
movq %rax, %rdi
callq 0x68a31
nop