20 #include <ripple/app/rdb/Download.h>
21 #include <soci/sqlite3/soci-sqlite3.h>
28 boost::filesystem::path
const& path)
31 boost::optional<std::string> pathFromDb;
32 boost::optional<std::uint64_t> size;
34 auto conn = std::make_unique<DatabaseCon>(
37 auto& session = *conn->checkoutDb();
39 session <<
"SELECT Path FROM Download WHERE Part=0;",
40 soci::into(pathFromDb);
48 if (pathFromDb != path.string())
50 session <<
"DROP TABLE Download;";
56 session <<
"SELECT SUM(LENGTH(Data)) FROM Download;",
66 soci::session& session,
79 dynamic_cast<soci::sqlite3_session_backend*
>(session.get_backend());
85 auto const blobMaxSize =
86 sqlite_api::sqlite3_limit(be->conn_, SQLITE_LIMIT_LENGTH, -1) -
92 session <<
"INSERT INTO Download VALUES (:path, zeroblob(0), 0, :part)",
93 soci::use(newpath), soci::use(part);
95 remainingInRow = blobMaxSize;
99 session <<
"SELECT Path,Size,Part FROM Download ORDER BY Part DESC "
101 soci::into(newpath), soci::into(rowSize), soci::into(part, rti);
103 if (!session.got_data())
109 remainingInRow = blobMaxSize - rowSize;
111 auto insert = [&session, &rowSize, &part, &fs = fileSize](
115 session <<
"UPDATE Download SET Data = CAST(Data || :data AS blob), "
116 "Size = :size WHERE Part = :part;",
117 soci::use(data), soci::use(updatedSize), soci::use(part);
122 size_t currentBase = 0;
124 while (currentBase + remainingInRow < data.size())
128 insert(data.substr(currentBase, remainingInRow));
129 currentBase += remainingInRow;
136 insert(data.substr(currentBase));
144 soci::rowset<std::string> rs =
145 (session.prepare <<
"SELECT Data FROM Download ORDER BY PART ASC;");
148 for (
auto it = rs.begin(); it != rs.end(); ++it)
149 fout.
write(it->data(), it->size());