From 6b85992cdd3088238ab0e8f7528f9e233b33fbbd Mon Sep 17 00:00:00 2001 From: Gergul Date: Wed, 8 Nov 2023 23:45:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../ConsoleApplicationTest.cpp | 122 +++++++++++++----- SQLit3/SQLit3.cpp | 83 ++++++------ SQLit3/SQLit3.h | 26 ++-- 4 files changed, 149 insertions(+), 84 deletions(-) diff --git a/.gitignore b/.gitignore index 817e9cc..5692ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ /SQLit3/tmp /x64 /Win32 +/ConsoleApplicationTest/1.db +/ConsoleApplicationTest/2.db diff --git a/ConsoleApplicationTest/ConsoleApplicationTest.cpp b/ConsoleApplicationTest/ConsoleApplicationTest.cpp index dd01042..8c02446 100644 --- a/ConsoleApplicationTest/ConsoleApplicationTest.cpp +++ b/ConsoleApplicationTest/ConsoleApplicationTest.cpp @@ -4,52 +4,51 @@ #include #include "..\SQLit3\SQLit3.h" -int main() +int test_normal() { - Database* db = SQLit3::Ins().CreateDatabase(); - bool b = db->Open("F:\\1.db", "", Database::SQLIT3_OPEN_DEFAULT); - if (!b) - { - std::cout << "打开数据库失败"<< db->GetLastErrorCode() + Database* db = SQLit3::Ins().CreateDatabase(); + bool b = db->Open("1.db", "12345678", Database::SQLIT3_OPEN_DEFAULT); + if (!b) + { + std::cout << "打开数据库失败" << db->GetLastErrorCode() << ":" << db->GetLastErrorMsg() << std::endl; - return 1; - } - b = db->Execute("select 1"); + return 1; + } //b = db->ResetPassword("12345678"); - __int64 maxId = 0; - b = db->QueryInt64("SELECT MAX(id) FROM Url2FileCache", &maxId); + b = db->Execute("CREATE TABLE IF NOT EXISTS t1 (\"a\" TEXT,\"b\" integer,\"c\" real);"); + b = db->Execute("INSERT INTO t1 (\"a\", \"b\", \"c\") VALUES ('abc', 1, 2.0);"); + __int64 changedRow = db->GetChangeRowCount(); - b = db->Execute("CREATE TABLE IF NOT EXISTS \"t1\" (\"a\" TEXT,\"b\" integer,\"c\" real);"); - b = db->Execute("INSERT INTO \"main\".\"t1\" (\"a\", \"b\", \"c\") VALUES ('abc', 1, 2.0);"); - __int64 changedRow = db->GetChangeRowCount(); + __int64 countRows = 0; + b = db->QueryInt64("SELECT COUNT(1) FROM t1", &countRows); - SqlStatement* stmt = db->StatementPrepare("SELECT a,c FROM \"main\".\"t1\" where b=? or b=$cv"); - if (stmt) - { + SqlStatement* stmt = db->StatementPrepare("SELECT a,c FROM t1 where b=? or b=$cv"); + if (stmt) + { b = stmt->BindInt(0, 1); int idx = stmt->GetParamIndexByName("$cv"); b = stmt->BindDouble(idx, 2); int colCount = stmt->GetColumnCount(); - while (stmt->Next() == SqlStatement::SQLIT3_READ_HAS_ROW) + while (stmt->Next() == SqlStatement::SQLIT3_EXEC_HAS_ROW) { for (int i = 0; i < colCount; i++) - { - const char* columnName = stmt->GetColumnName(i); - auto type = stmt->GetType(i); + { + const char* columnName = stmt->GetColumnName(i); + auto type = stmt->GetType(i); switch (type) { case SqlStatement::SQLIT3_VALUE_INTEGER: { __int64 v = stmt->GetInt64(i); - std::cout << columnName << "=" << v << std::endl; + std::cout << columnName << "=" << v << "\t"; break; } case SqlStatement::SQLIT3_VALUE_FLOAT: { double v = stmt->GetDouble(i); - std::cout << columnName << "=" << v << std::endl; + std::cout << columnName << "=" << v << "\t"; break; } case SqlStatement::SQLIT3_VALUE_BLOB: @@ -59,32 +58,97 @@ int main() char* pBuf = new char[dataLen + 1]; memcpy(pBuf, data, dataLen); pBuf[dataLen] = '\0'; - std::cout << columnName << "=" << pBuf << std::endl; + std::cout << columnName << "=" << pBuf << "\t"; delete[] pBuf; break; } case SqlStatement::SQLIT3_VALUE_NULL: { - std::cout << columnName << "=" << std::endl; + std::cout << columnName << "=" << "\t"; break; } - case SqlStatement::SQLIT3_VALUE_TEXT: + case SqlStatement::SQLIT3_VALUE_TEXT: default: { int dataLen = 0; auto data = stmt->GetText(i, &dataLen); - std::cout << columnName << "=" << data << std::endl; + std::cout << columnName << "=" << data << "\t"; break; } } } + + std::cout << std::endl; } db->StatementFinalize(stmt); - } + } - b = db->Close(); + b = db->Close(); SQLit3::Ins().DestoryDatabase(db); + return 0; +} + +#include + +int test_blob(const char* exefile) +{ + Database* db = SQLit3::Ins().CreateDatabase(); + bool b = db->Open("2.db", "12345678", Database::SQLIT3_OPEN_DEFAULT); + if (!b) + { + std::cout << "打开数据库失败" << db->GetLastErrorCode() + << ":" << db->GetLastErrorMsg() << std::endl; + return 1; + } + //b = db->ResetPassword("12345678"); + + b = db->Execute("CREATE TABLE IF NOT EXISTS test_blob (\"a\" integer NOT NULL,\"b\" blob, PRIMARY KEY (\"a\"));"); + + __int64 id = 0; + db->QueryInt64("SELECT MAX(a) FROM test_blob", &id); + + SqlStatement* stmt = db->StatementPrepare("INSERT INTO test_blob(\"a\", \"b\") VALUES (?, ?);"); + if (stmt) + { + stmt->BindInt64(0, id + 1); + + // 打开二进制文件 + std::ifstream inFile(exefile, std::ios::binary); + // 检查文件是否打开成功 + if (inFile) + { + inFile.seekg(0, std::ios::end); + std::streampos ps = inFile.tellg(); + inFile.seekg(0, std::ios_base::beg); + // 读取文件内容 + char* buffer = new char[ps]; + inFile.read(buffer, ps); + // 关闭文件 + inFile.close(); + + stmt->BindBlob(1, buffer, ps); + SqlStatement::ExecStatus es = stmt->Next(); + delete[] buffer; + __int64 changedRow = db->GetChangeRowCount(); + } + + db->StatementFinalize(stmt); + } + + const void* data = NULL; + int dataLen = 0; + b = db->QueryBlob("SELECT b FROM test_blob LIMIT 0,1", &data, &dataLen); + + b = db->Close(); + SQLit3::Ins().DestoryDatabase(db); + return 0; +} + +int main(int argc, char** argv) +{ + test_normal(); + test_blob(argv[0]); return 0; } diff --git a/SQLit3/SQLit3.cpp b/SQLit3/SQLit3.cpp index 9deb74c..ebdd0ef 100644 --- a/SQLit3/SQLit3.cpp +++ b/SQLit3/SQLit3.cpp @@ -18,14 +18,14 @@ class SqlStatementImp sqlite3_finalize(m_stmt); } - virtual bool BindBlob(int paramIdx, const void* data, int dataLen, FN_ReleaseBuff dfn = NULL) override + virtual bool BindBlob(int paramIdx, const void* data, int dataLen) override { - return sqlite3_bind_blob(m_stmt, paramIdx + 1, data, dataLen, dfn) == SQLITE_OK; + return sqlite3_bind_blob(m_stmt, paramIdx + 1, data, dataLen, SQLITE_STATIC) == SQLITE_OK; } - virtual bool BindBlob64(int paramIdx, const void* data, __int64 dataLen, FN_ReleaseBuff dfn = NULL) override + virtual bool BindBlob64(int paramIdx, const void* data, __int64 dataLen) override { - return sqlite3_bind_blob64(m_stmt, paramIdx + 1, data, dataLen, dfn) == SQLITE_OK; + return sqlite3_bind_blob64(m_stmt, paramIdx + 1, data, dataLen, SQLITE_STATIC) == SQLITE_OK; } virtual bool BindDouble(int paramIdx, double v) override @@ -48,24 +48,24 @@ class SqlStatementImp return sqlite3_bind_null(m_stmt, paramIdx + 1) == SQLITE_OK; } - virtual bool BindText(int paramIdx, const char* text, int textLen, FN_ReleaseBuff dfn = NULL) override + virtual bool BindText(int paramIdx, const char* text, int textLen) override { - return sqlite3_bind_text(m_stmt, paramIdx + 1, text, textLen, dfn) == SQLITE_OK; + return sqlite3_bind_text(m_stmt, paramIdx + 1, text, textLen, SQLITE_STATIC) == SQLITE_OK; } - virtual bool BindText16(int paramIdx, const void* text, int textLen, FN_ReleaseBuff dfn = NULL) override + virtual bool BindText16(int paramIdx, const void* text, int textLen) override { - return sqlite3_bind_text16(m_stmt, paramIdx + 1, text, textLen, dfn) == SQLITE_OK; + return sqlite3_bind_text16(m_stmt, paramIdx + 1, text, textLen, SQLITE_STATIC) == SQLITE_OK; } - virtual bool BindText64(int paramIdx, const char* text, __int64 textLen, TextEncoding encoding, FN_ReleaseBuff dfn = NULL) override + virtual bool BindText64(int paramIdx, const char* text, __int64 textLen, TextEncoding encoding) override { - return sqlite3_bind_text64(m_stmt, paramIdx + 1, text, textLen, dfn, encoding) == SQLITE_OK; + return sqlite3_bind_text64(m_stmt, paramIdx + 1, text, textLen, SQLITE_STATIC, encoding) == SQLITE_OK; } - virtual bool BindPointer(int paramIdx, void* pointer, const char* valueType, FN_ReleaseBuff dfn = NULL) override + virtual bool BindPointer(int paramIdx, void* pointer, const char* valueType) override { - return sqlite3_bind_pointer(m_stmt, paramIdx + 1, pointer, valueType, dfn) == SQLITE_OK; + return sqlite3_bind_pointer(m_stmt, paramIdx + 1, pointer, valueType, SQLITE_STATIC) == SQLITE_OK; } virtual bool BindZeroBlob(int paramIdx, int n) override @@ -98,7 +98,7 @@ class SqlStatementImp return sqlite3_column_name(m_stmt, iCol); } - virtual ReadStatus Next(int timeout = 0) override + virtual ExecStatus Next(int timeout = 0) override { int res = sqlite3_step(m_stmt); @@ -117,18 +117,18 @@ class SqlStatementImp switch (res) { case SQLITE_ROW: - return SQLIT3_READ_HAS_ROW; + return SQLIT3_EXEC_HAS_ROW; break; case SQLITE_OK: case SQLITE_DONE: - return SQLIT3_READ_DONE; + return SQLIT3_EXEC_DONE; break; case SQLITE_BUSY: - return SQLIT3_READ_TIMEOUT; + return SQLIT3_EXEC_TIMEOUT; break; case SQLITE_ERROR: default: - return SQLIT3_READ_ERROR; + return SQLIT3_EXEC_ERROR; break; } } @@ -146,6 +146,7 @@ class SqlStatementImp virtual const void* GetBlob(int iCol, int* size) override { + *size = sqlite3_column_bytes(m_stmt, iCol); return sqlite3_column_blob(m_stmt, iCol); } @@ -295,16 +296,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) *ret = stmt->GetInt(0); @@ -320,16 +321,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) *ret = stmt->GetInt64(0); @@ -345,16 +346,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) *ret = stmt->GetDouble(0); @@ -370,16 +371,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) { @@ -404,16 +405,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) { @@ -438,16 +439,16 @@ class DatabaseImp if (!stmt) return false; - SqlStatement::ReadStatus status = stmt->Next(); - if (status != SqlStatement::SQLIT3_READ_DONE && - status != SqlStatement::SQLIT3_READ_HAS_ROW) + SqlStatement::ExecStatus status = stmt->Next(); + if (status != SqlStatement::SQLIT3_EXEC_DONE && + status != SqlStatement::SQLIT3_EXEC_HAS_ROW) { StatementFinalize(stmt); return false; } int nCount = stmt->GetColumnCount(); - if (status == SqlStatement::SQLIT3_READ_HAS_ROW) + if (status == SqlStatement::SQLIT3_EXEC_HAS_ROW) { if (nCount > 0) { diff --git a/SQLit3/SQLit3.h b/SQLit3/SQLit3.h index 0a623a0..14a709d 100644 --- a/SQLit3/SQLit3.h +++ b/SQLit3/SQLit3.h @@ -32,27 +32,25 @@ class SqlStatement SQLIT3_ENCODING_UTF16_ALIGNED = 8, /* sqlite3_create_collation only */ }; - enum ReadStatus + enum ExecStatus { - SQLIT3_READ_HAS_ROW = 100, // - SQLIT3_READ_DONE = 101, //Ѷȡ - SQLIT3_READ_TIMEOUT = 5, //ȡݳʱݿæ - SQLIT3_READ_ERROR = 1, //ȡ + SQLIT3_EXEC_HAS_ROW = 100, // + SQLIT3_EXEC_DONE = 101, //Ѷȡ + SQLIT3_EXEC_TIMEOUT = 5, //ȡݳʱݿæ + SQLIT3_EXEC_ERROR = 1, //ȡ }; - typedef void(*FN_ReleaseBuff)(void* p); - public: - virtual bool BindBlob(int paramIdx, const void* data, int dataLen, FN_ReleaseBuff dfn = NULL) = 0; - virtual bool BindBlob64(int paramIdx, const void* data, __int64 dataLen, FN_ReleaseBuff dfn = NULL) = 0; + virtual bool BindBlob(int paramIdx, const void* data, int dataLen) = 0; + virtual bool BindBlob64(int paramIdx, const void* data, __int64 dataLen) = 0; virtual bool BindDouble(int paramIdx, double v) = 0; virtual bool BindInt(int paramIdx, int v) = 0; virtual bool BindInt64(int paramIdx, __int64 v) = 0; virtual bool BindNull(int paramIdx) = 0; - virtual bool BindText(int paramIdx, const char* text, int textLen, FN_ReleaseBuff dfn = NULL) = 0; - virtual bool BindText16(int paramIdx, const void* text, int textLen, FN_ReleaseBuff dfn = NULL) = 0; - virtual bool BindText64(int paramIdx, const char* text, __int64 textLen, TextEncoding encoding, FN_ReleaseBuff dfn = NULL) = 0; - virtual bool BindPointer(int paramIdx, void* pointer, const char* valueType/*="ValueList"*/, FN_ReleaseBuff dfn = NULL) = 0; + virtual bool BindText(int paramIdx, const char* text, int textLen) = 0; + virtual bool BindText16(int paramIdx, const void* text, int textLen) = 0; + virtual bool BindText64(int paramIdx, const char* text, __int64 textLen, TextEncoding encoding) = 0; + virtual bool BindPointer(int paramIdx, void* pointer, const char* valueType/*="ValueList"*/) = 0; virtual bool BindZeroBlob(int paramIdx, int n) = 0; virtual bool BindZeroBlob64(int paramIdx, __int64 n) = 0; virtual int GetParamIndexByName(const char* paramName) = 0; @@ -60,7 +58,7 @@ class SqlStatement virtual int GetColumnCount() = 0; virtual const char* GetColumnName(int iCol) = 0; - virtual ReadStatus Next(int timeout = 0) = 0; + virtual ExecStatus Next(int timeout = 0) = 0; virtual void Reset() = 0; virtual SqlValueType GetType(int iCol) = 0;