Sqlite database encryption with wxsqlite3 run time error - c++

I downloaded the prebuilt binaries from here(wxSQLite3 3.5.9) and also I downloaded the sqlite3.h file version 3.21.0, I added the header file and .dll and .lib file to my project.
I copied the 32 bit version of dll and lib file, and copied them in my solution and also added the .lib file to Additional Dependencies in Linker->Input in project properties.
I created this sample application with C++:
#define SQLITE_HAS_CODEC
#include "sqlite3.h"
#include <string>
#include <iostream>
using namespace std;
int main()
{
sqlite3* db;
sqlite3_open("test1.db", &db);
sqlite3_key(
db, /* Database to be rekeyed */
"test", sizeof("test") /* The key, and the length of the key in bytes */
);
std::string createQuery =
"CREATE TABLE IF NOT EXISTS items (userid INTEGER PRIMARY KEY, ipaddr TEXT, username TEXT, useradd TEXT, userphone INTEGER, age INTEGER, "
"time TEXT NOT NULL DEFAULT (NOW()));";
sqlite3_stmt* createStmt;
std::cout << "Creating Table Statement" << endl;
sqlite3_prepare(db, createQuery.c_str(), createQuery.size(), &createStmt, NULL);
cout << "Stepping Table Statement" << endl;
if (sqlite3_step(createStmt) != SQLITE_DONE) cout << "Didn't Create Table!" << endl;
string insertQuery =
"INSERT INTO items (time, ipaddr,username,useradd,userphone,age) VALUES('7:30', '192.187.27.55', 'vivekanand', 'kolkatta', '04456823948', 74);";
// WORKS!
sqlite3_stmt* insertStmt;
cout << "Creating Insert Statement" << endl;
sqlite3_prepare(db, insertQuery.c_str(), insertQuery.size(), &insertStmt, NULL);
cout << "Stepping Insert Statement" << endl;
if (sqlite3_step(insertStmt) != SQLITE_DONE) cout << "Didn't Insert Item!" << endl;
return 0;
}
when I run this program I get this error at run time:
But If I comment this section of code
sqlite3_key(
db, /* Database to be rekeyed */
"test", sizeof("test") /* The key, and the length of the key in bytes */
);
It works just fine, what am I doing wrong?

The C/C++ code seems to be alright. And if the test application could be compiled correctly, obviously a valid link library was used. However, the runtime error message indicates that the correct DLL was not loaded.
This indicates that the pre-compiled SQLite DLL was not copied into the same directory where the executable of the test application resides, or it was not in the search path of the application. However, some SQLite DLL was found in the search path, but most likely an "official" SQLite DLL that does not include the encryption extension.
Make sure that the SQLite DLL that includes the encryption extension is accessible by the test application.
The pre-compiled binaries from the wxSQLite3 releases definitely include the entry points sqlite3_key and sqlite3_rekey.

Related

Linking external libraries in C++ in Visual Studio Code

Good afternoon! I have a following program in C++, in VS Code. The program reads all data from a table called student. I compile this program with the command g++ retrieveDataFromTable.cpp -I "C:\Program Files\MySQL\MySQL Server 8.0\include" -L "C:\Program Files\MySQL\MySQL Server 8.0\lib" -l mysql -o test, and it perfectly gets compiled. It's my first time that I use an external library in my programs. So, I watched some videos about how linking works, and how to add an external library to our program. Basically, in those videos they used Visual Studio or Codeblocks for adding libraries, but I'm using VS Code. Eventually, I managed to make the program work, but I have some questions. First one is about the way I include header file "mysql.h". I mean it does not look professional. If I were to run this program in other device, of course that would not make any sense. So would anybody like to help me out how I could make it better? My second question is that the program does terminate if I did not have libmysql.dll in my project folder. I'm guessing that it's because I do dynamic linking with the library (please, correct me if I'm wrong). So does anybody know about how I could link this particular library statically? In general, I would really appreciate if anyone would give me some piece of advice about how I could improve this program, and what I should learn to know about these kind of things. Thank you)
#include <iostream>
#include "C:/Program Files/MySQL/MySQL Server 8.0/include/mysql.h"
struct CONNECTION
{
const char *server = "localhost";
const char *user = "root";
const char *password = "password";
const char *database = "project";
};
MYSQL *connection_to_database(CONNECTION connection)
{
MYSQL *newConnection = mysql_init(NULL);
if (!newConnection)
{
std::cout << "Failed to create an object" << std::endl;
std::cout << mysql_error(newConnection) << std::endl;
exit(0);
}
if (!mysql_real_connect(newConnection, connection.server, connection.user,
connection.password, connection.database, 3306, NULL, 0))
{
std::cout << "Failed to connect to database:" << std::endl;
std::cout << mysql_error(newConnection) << std::endl;
exit(0);
}
return newConnection;
}
MYSQL_RES *execute_query(MYSQL *connection, const std::string query)
{
if (mysql_query(connection, query.c_str()))
{
std::cout << "MYSQL query error:\n"
<< mysql_error(connection) << std::endl;
exit(0);
}
return mysql_store_result(connection);
}
int main()
{
CONNECTION id;
MYSQL* connection = connection_to_database(id);
MYSQL_RES* res = execute_query(connection, "SELECT * FROM students");
int rows = mysql_affected_rows(connection);
std::cout << rows << " rows were affected" << std::endl;
int columns = mysql_num_fields(res);
std::cout << columns << " columns in the table" << std::endl;
MYSQL_ROW row;
while((row = mysql_fetch_row(res)))
{
for (int i = 0; i < columns; i++){
std::cout << row[i] << " ";
}
std::cin.get();
}
return 0;
}
I looked some questions but I could not find something useful.
How about using CMake?
You can easily link external libraries into your target executable.
On top of that, is it perfectly supported on vscode by CMake tools extension.
cmake_minimum_required(VERSION 3.25)
project(myProject)
include_directories(${CMAKE_SOURCE_DIR}/include)
link_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} libmysql.so)
Thank you guys for your answers! I managed to solve this problem, but I need to do some research why it actually worked (if you could help me I would really appreciate it). Basically I made three directories: build, include, lib. "include" and "lib" directories I copied from MYSQL Server 8.0 directory. The outputs of cmake are stored in "build" directory. I have the following command in CMakeLists.txt:
cmake_minimum_required(VERSION 3.25)
project(myProject)
include_directories(${CMAKE_SOURCE_DIR}/include)
link_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} mysql)
And it builds successfully. HOWEVER (!!!) when I try to run it, it just terminates. So I put libmysql.dll in "build" directory and then it ran. I'm really new to these things guys, and this solution of mine probably is not professional. If you guys could recommend me how to improve this procedure, or how to manage to make the program work without libmysql.dll file, I would really appreciate it.

SQLException 32104 in OCCI

I am trying to use OCCI to connect my program to an oracle database but I am getting an SQLException 32104 when I try the createEnvironment function.
My code:
#include <OpenXLSX.hpp>
#include <occi.h>
#include <string>
using namespace OpenXLSX;
using namespace oracle::occi;
int main() {
std::string user = "";
std::string pass = "";
std::string conn_str = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.2.159)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)))";
std::cout << "Initializing Database Connection ......" << std::endl;
try {
Environment* env = Environment::createEnvironment(Environment::DEFAULT);
//Connection *conn = env->createConnection(user, pass ,conn_str);
} catch(SQLException &e) {
std::cout << "Error Message: " << e.getErrorCode() << std::endl;
std::cout << e.getMessage() << std::endl;
}
std::cout << "Initializing Database Connection ......";
std::cout << " OK" << std::endl;
XLDocument doc;
doc.open("Template.xlsx");
auto wks = doc.workbook().worksheet("Extruder Data Log");
int row_number = 4;
char column_letter = 'A';
char column_letter2 = 'A';
std::string loc;
loc = column_letter;
loc += std::to_string(4);
wks.cell(loc).value() = "Hello, OpenXLSX!";
doc.save();
//env->terminateConnection(conn);
//Environment::terminateEnvironment(env);
std::cout << "Program Terminated: Press Enter ...";
std::string wait;
std::cin >> wait;
return 0;
}
I am using CMake to compile:
cmake_minimum_required(VERSION 3.15)
project(Atlas)
set(CMAKE_CXX_STANDARD 17)
# Set the build output location to a common directory
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/lib)
add_subdirectory(OpenXLSX)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OpenXLSX/headers)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OpenXLSX)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OCCI)
link_directories(${CMAKE_PREFIX_PATH})
find_package(OpenXLSX REQUIRED)
find_library(OCCI NAMES oraocci21.lib oci.lib oramysql.lib oraocci21d.lib ociw32.lib)
add_executable(Atlas Atlas.cpp)
target_link_libraries(Atlas OpenXLSX::OpenXLSX)
target_link_libraries(Atlas ${OCCI})
I have the dlls in the output directory where the executable and libraries end up outputting to.
I figure that it should run, but I am getting a Microsoft C++ exception: oracle::occi::SQLException
and on debugging it shows that it is message 32104 which I know means that it cannot get the error.
The Debug window show that it loads the oraocci21.dll but not any of the other OCCI dlls.
If anyone can let me know what I'm doing wrong I would be incredibly grateful since I have scoured the internet trying to figure this out.
EDIT
Figured out this error, I hadn't moved all of the dlls from the instant client. I was only including the dlls that corresponded to the library names.
I included ocijdbc21.dll, orannzsbb.dll, and oraociicus.dll to the folder with my executable and it now runs past the createEnvironment(Environment::DEFAULT) part.
With this edit, though, I am now running into Error 24960 which says that OCI_ATTR_USERNAME is more than length 255 which it is not.
If anyone can help with that please let me know but I hope that anyone else running across this who needs help sees the part about the dlls.
If it helps to answer my question, I am using instant client base 21_3 and sdk 21_3. I am also using MSVC 16 2019 for compilation with C++17 as the version of C++. My Oracle Database is running on 19c and I can connect to it remotely.
So I figured it out.
I was using this command for cmake:
cmake --build . --target ALL_BUILD --config Debug
This release config command should work because I have debugged the program:
cmake --build . --target ALL_BUILD --config Release
For some reason, I can only assume that OCCI did not like my debugger
version or something like that. If someone could please comment on why this happens I would like to learn.

OCCI in Oracle database - Couldn't find entry point of procedure OCIPIsDescRebuilt in OCI.dll library

I've decided to connect my C++ game with Oracle database using OCCI (Oracle C++ Call Interface). I've finally managed to compile my program with occi.h included but now, when I run the program, I get the message:
Couldn't find entry point of procedure OCIPIsDescRebuilt in OCI.dll library.
Here is a small part of my code in which I try to connect with database:
#include <occi.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
using namespace std;
using namespace oracle::occi;
int main()
{
Environment *env = Environment::createEnvironment(Environment::DEFAULT);
Connection *conn = env->createConnection("system", "password","localhost:1521");
cout << "Podaj nick gracza nr 1: ";
cin >> nick[1];
cout << "Podaj nick gracza nr 2: ";
cin >> nick[2];
Statement *stmt = conn->createStatement();
stmt->executeUpdate("INSERT INTO uzytkownicy VALUES('1','A',nick[1])");
stmt->executeUpdate("INSERT INTO uzytkownicy VALUES('1','B',nick[2])");
ResultSet *rs = stmt->executeQuery("SELECT * FROM basket_tab");
cout << "The basket has:" << endl;
while (rs->next())
{
string fruit = rs->getString(1); // get the first column as string
int quantity = rs->getInt(2); // get the second column as int
cout << quantity << " " << fruit << endl;
}
env->terminateConnection(conn);
Environment::terminateEnvironment(env);
}
I use MS Visual Studio 2010 and Oracle Database Express Edition 11g Release 2 (11.2). Apart from Oracle® C++ Call Interface Programmer's Guide, 11g Release 2 (11.2), I also used materials from these sites:
Mark Williams Blog
This Thread Blog
How can I solve this problem? Maybe there is a simplier way (as for configuration) to connect with database using C++ program than through OCCI?
I was able to get rid of this error by copying the oci.dll file from the Oracle 12c Instant Client to the bin/Debug or bin/Release directory of my application so it would get loaded instead of the oci.dll that is in the default Oracle 11 client that gets installed.

Connecting to MS Access database using C++ using Visual Studio 2008

I need some serious help trying to connect to an Access database using VS 2008's C++. I have done this in C# but I cant figure this out in C++. I need to use C++ for the connection because I am grabbing data using pre-compiled C++ code. I would really appreciate some help with this. Thanks
I would like to odbc, but if you have another recommendation then I could change my mind.I am trying to connect to an Access database, the Northwind sample database, by following this example,
http://msdn.microsoft.com/en-us/library/cc811599.aspx
I am using a Windows 7 OS with Visual C++ 2008 for the compiler and IDE. The program is a console application. This example is specified for Access 2007 .accdb file types. Once I get it running correctly I will switch the path name, queries, and table names to my database. Below is the code that fails to build. I don't know what is causing this:
Includes-->
fstream
cmath
complex
iostream
iomanip
vector
limits
stdlib.h
stdio.h
time.h
fcntl.h
string.h
ctype.h
icrsint.h
using namespace std;
#import C:\\Program Files\\Common Files\\system\\ado\\msado15.dll rename("EOF",
"AdoNSEOF")
_bstr_t bstrConnect="Provider=Microsoft.ACE.OLEDB.12.0;Data "
"Source=C:\\Users\\lriley\\Documents\\Northwind 2007.mdb;";
HRESULT hr;
int main()
{
::CoInitialize(NULL);
const char* DAM = "ADO";
ADODB::_ConnectionPtr pConn("ADODB.Connection");
hr = pConn->Open(bstrConnect, "admin", "", ADODB::adConnectUnspecified);
if(SUCCEEDED(hr))
{
cout<<DAM<<": Successfully connected to database. Data source name:\n "
<<pConn->GetConnectionString()<<endl;
// Prepare SQL query
_bstr_t query = "SELECT Customers.[Company], Customers.[First Name] FROM "
"Customers;";
cout <<DAM<<": SQL query \n "<<query<<endl;
// Execute
ADODB::_RecordsetPtr pRS("ADODB.Recordset");
hr = pRS->Open(query,
_variant_t((IDispatch *) pConn, true),
ADODB::adOpenUnspecified,
ADODB::adLockUnspecified,
ADODB::adCmdText);
if(SUCCEEDED(hr))
{
cout<<DAM<<": Retrieve schema info for the given result set: "<< endl;
ADODB::Fields* pFields = NULL;
hr = pRS->get_Fields(&pFields);
if(SUCCEEDED(hr) && pFields && pFields->GetCount() > 0)
{
for(long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
{
cout << " | "<<_bstr_t(pFields->GetItem(nIndex)->GetName());
}
cout << endl;
}
else
{
cout << DAM << ": Error: Number of fields in the " <<
"result is set to zero." << endl;
}
cout<<DAM<<": Fetch the actual data: " << endl;
int rowCount = 0;
while (!pRS->AdoNSEOF)
{
for(long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
{
cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetValue());
}
cout<< endl;
pRS->MoveNext();
rowCount++;
}
cout<<DAM<<": Total Row Count: " << rowCount << endl;
}
pRS->Close();
pConn->Close();
cout<<DAM<<": Cleanup Done" << endl;
}
else
{
cout<<DAM<<" : Unable to connect to data source: "<<bstrConnect<<endl;
}
::CoUninitialize();
return 0;
}
I recieve the following error when I try to build it:
fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add #include "stdafx.h" to your source?
c:\users\lriley\documents\visual studio 2008\projects\test12\test12\test12.cpp
Any help would be appreciated.
Thanks
Dante
Well, it's been a while, but you are going to need something like: http://msdn.microsoft.com/en-us/library/ms714562%28v=vs.85%29.aspx, look at SQLConnect..., a lot of variations to a theme, but the 2nd parameter is basically the path to your access db (*.mdb) file.
good luck.
You just have to give in file properties *. Cpp
-> Precompiled Header-No Precompiled Headers
Use precompiled header file - Stdafx.h xxxx

oracle occi getString gives _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

I am trying to do a getString on a ResultSet from a OCCI Oracle query but I always get the _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) assertion. My project is Multi-Threaded Debug and I have tried to set it to Single-Thread Debug, as I found suggested online, but that makes no difference.
I'm a bit at a loss what is causing this assertion to occur. Can someone help?
It seems I only have it with the getString() function, not with any other.
oracle::occi::Environment* environment;
oracle::occi::Connection* con;
oracle::occi::Statement* stmt;
oracle::occi::ResultSet* res;
try{
environment = oracle::occi::Environment::createEnvironment(oracle::occi::Environment::DEFAULT);
con = environment->createConnection("db", "pssw", "DATABASE");
std::cout << "created connection" << std::endl;
std::stringstream query;
query << "SELECT MOD_KEY, MOD_SCRIPTLANGUAGE, MOD_SOURCE, MOD_CODE, MOD_STYLE, MOD_TYPE ";
query << "FROM DB.MEDICAL_OBS_DEF ";
query << "WHERE MOD_KEY = 735";
stmt = con->createStatement(query.str());
res = stmt->executeQuery();
res->setMaxColumnSize(3,100);
std::cout << "executed query" << std::endl;
std::string mystring;
while (res->next())
{
/*mystring = */res->getString(3); ///_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) Assert!
}
std::cout << "printed resultset" << std::endl;
stmt->closeResultSet(res);
con->terminateStatement(stmt);
environment->terminateConnection(con);
}catch(oracle::occi::SQLException &e){
std::cout<<e.what();
}
Have you linked to the debug versions of Oracle DLLs (oraocci11d.lib and oraocci11d.dll)?
It seems that your program uses the memory debugging option of Visual Studio while the Oracle DLLs you're using don't. So the error occurs because the run-time library thinks there's a memory allocation/deallocation problem.
What compiler are you using?
Make sure to download properly occi version
http://www.oracle.com/technetwork/database/occidownloads-083553.html
You must use DLL runtime:
DLL multithread Debug (/MDd) for debug with oraocci11d.lib and oraocci11d.dll
DLL multithread (/MD) for release with oraocci11.lib and oraocci11.dll
if you DB using UTF8 character set
try using following
Environment *environment = Environment::createEnvironment("AL32UTF8","UTF8");