| 1836 | } |
| 1837 | |
| 1838 | bool ProjectFileIO::WriteDoc(const char *table, |
| 1839 | const ProjectSerializer &autosave, |
| 1840 | const char *schema /* = "main" */) |
| 1841 | { |
| 1842 | auto db = DB(); |
| 1843 | |
| 1844 | TransactionScope transaction(mProject, "UpdateProject"); |
| 1845 | |
| 1846 | int rc; |
| 1847 | |
| 1848 | // For now, we always use an ID of 1. This will replace the previously |
| 1849 | // written row every time. |
| 1850 | char sql[256]; |
| 1851 | sqlite3_snprintf( |
| 1852 | sizeof(sql), sql, |
| 1853 | "INSERT INTO %s.%s(id, dict, doc) VALUES(1, ?1, ?2)" |
| 1854 | " ON CONFLICT(id) DO UPDATE SET dict = ?1, doc = ?2;", |
| 1855 | schema, table); |
| 1856 | |
| 1857 | sqlite3_stmt *stmt = nullptr; |
| 1858 | auto cleanup = finally([&] |
| 1859 | { |
| 1860 | if (stmt) |
| 1861 | { |
| 1862 | sqlite3_finalize(stmt); |
| 1863 | } |
| 1864 | }); |
| 1865 | |
| 1866 | rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr); |
| 1867 | if (rc != SQLITE_OK) |
| 1868 | { |
| 1869 | ADD_EXCEPTION_CONTEXT("sqlite3.query", sql); |
| 1870 | ADD_EXCEPTION_CONTEXT("sqlite3.rc", std::to_string(rc)); |
| 1871 | ADD_EXCEPTION_CONTEXT("sqlite3.context", "ProjectGileIO::WriteDoc::prepare"); |
| 1872 | |
| 1873 | SetDBError( |
| 1874 | XO("Unable to prepare project file command:\n\n%s").Format(sql) |
| 1875 | ); |
| 1876 | return false; |
| 1877 | } |
| 1878 | |
| 1879 | const MemoryStream& dict = autosave.GetDict(); |
| 1880 | const MemoryStream& data = autosave.GetData(); |
| 1881 | |
| 1882 | // Bind statement parameters |
| 1883 | // Might return SQL_MISUSE which means it's our mistake that we violated |
| 1884 | // preconditions; should return SQL_OK which is 0 |
| 1885 | if ( |
| 1886 | sqlite3_bind_zeroblob(stmt, 1, dict.GetSize()) || |
| 1887 | sqlite3_bind_zeroblob(stmt, 2, data.GetSize())) |
| 1888 | { |
| 1889 | ADD_EXCEPTION_CONTEXT("sqlite3.query", sql); |
| 1890 | ADD_EXCEPTION_CONTEXT("sqlite3.rc", std::to_string(rc)); |
| 1891 | ADD_EXCEPTION_CONTEXT("sqlite3.context", "ProjectGileIO::WriteDoc::bind"); |
| 1892 | |
| 1893 | SetDBError(XO("Unable to bind to blob")); |
| 1894 | return false; |
| 1895 | } |