C++ copy sqlite blob from one database to another - c++

I am trying to copy some blob data from one sqlite table to another in C++. However, once the data has been copied over to the new table, it seems to be getting corrupted. The said data contains some jpeg images. The code I am using to copy from TABLE1 to TABLE2 is shown below:
// Read the blob from the database
int64_t rowID = 0;
sscanf( id.c_str(), "%llu", &rowID );
sqlite3_blob* blobHandle = NULL;
if( sqlite3_blob_open( m_dbHandle_temp, "main", m_currentTileTable.c_str(), "tile_data", rowID, 0, &blobHandle ) != SQLITE_OK )
{
sqlite3_blob_close( blobHandle ); // An SQLite blob will be initialised regardless of the success of 'sqlite3_blob_open'
return false;
}
tiles_insert_statement.append( ")" );
// Copy blob to database
sqlite3_stmt *stmt = 0;
const char* tail;
sqlite3_prepare_v2( m_dbHandle, tiles_insert_statement.c_str(), strlen( tiles_insert_statement.c_str() )+1, &stmt, &tail );
int bindSuccess = sqlite3_bind_blob( stmt, 1, blobHandle, sqlite3_blob_bytes( blobHandle ), SQLITE_TRANSIENT );
if( sqlite3_step( stmt ) != SQLITE_DONE )
printf( "Error message: %s\n", sqlite3_errmsg( m_dbHandle ) );
sqlite3_finalize( stmt );
// close handles
sqlite3_blob_close( blobHandle );
Is there anything I am doing wrong in the above code, the reason I say that it is getting corrupted is because, I am reading the blobs on an android device to be displayed in an image viewer. The blobs in the TABLE 1 can be read and displayed fine, however the ones in TABLE 2 do not display anything. Any help is greatly appreaciated.
SOLUTION:
// Read the blob from the database
int64_t rowID = 0;
sscanf( id.c_str(), "%llu", &rowID );
sqlite3_blob* blobHandle = NULL;
if( sqlite3_blob_open( m_dbHandle_temp, "main", m_currentTileTable.c_str(), "tile_data", rowID, 0, &blobHandle ) != SQLITE_OK )
{
sqlite3_blob_close( blobHandle ); // An SQLite blob will be initialised regardless of the success of 'sqlite3_blob_open'
return false;
}
unsigned int length = sqlite3_blob_bytes( blobHandle );
// TODO - instances of this class OWN the buffer.
// Delete the buffer in the destructor ;)
unsigned char* buffer = new unsigned char[ length ];
if( sqlite3_blob_read( blobHandle, buffer, length, 0 ) != SQLITE_OK )
{
return false;
}
tiles_insert_statement.append( ")" );
sqlite3_stmt *stmt = 0;
const char* tail;
sqlite3_prepare_v2( m_dbHandle, tiles_insert_statement.c_str(), strlen( tiles_insert_statement.c_str() )+1, &stmt, &tail );
int bindSuccess = sqlite3_bind_blob( stmt, 1, buffer, length, SQLITE_TRANSIENT );
if( sqlite3_step( stmt ) != SQLITE_DONE )
printf( "Error message: %s\n", sqlite3_errmsg( m_dbHandle ) );
sqlite3_finalize( stmt );
// close handles
sqlite3_blob_close( blobHandle );

sqlite3_bind_blob expects a pointer to the actual blob data; it is not possible to use a blob handle for that.
To get the blob data as a memory chunk, execute a query like SELECT tile_data FROM MyTable WHERE ... and read the value with sqlite3_column_blob.

Related

C++ ADO Excel record deletion

I am doing excel file operations with C++ ADO.
I could select, update and insert.
It cannot be deleted.
enter code here
CString strFile = _T("C:\\temp\\sample.xlsx");
CString s;
try
{
CString strCon;
strCon.Format( _T( "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=%s;Extended Properties=Excel 12.0 xml" ) , strFile );
con.CreateInstance(__uuidof(Connection));
con->Open(_bstr_t(strCon), "", "", adConnectUnspecified);
_RecordsetPtr rs;
rs.CreateInstance(__uuidof(Recordset));
rs->CursorLocation = adUseClient;
rs->Open(_variant_t( "SELECT * FROM [test$] WHERE [ID]='A1'" ), con.GetInterfacePtr(), adOpenForwardOnly, adLockOptimistic, adCmdText );
if( !rs->GetadoEOF() )
{
rs->Delete(adAffectCurrent);
rs->Close();
}
}
catch(_com_error& e)
{
s=e.ErrorMessage();
}
if( con != NULL ) con->Close();
con = NULL;
Exception occurs in delete

How to get word list using ISpLexicon::GetWords?

I'm developping a Text-To-Speech application using Microsoft SAPI. I found out that it is possible to add customized prononciations of words in a dictionnary (correct me if I'm wrong). I implemented a function which allows to add words into this dictionnary. Here is my code:
int addPrononciation( const char* addPron, const char* phon )
{
hr = cpLexicon.CoCreateInstance( CLSID_SpLexicon );
hr = cpContainerLexicon.CoCreateInstance( CLSID_SpLexicon );
hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
cpEnum->Item( saveVoice, &cpVoiceToken ); //get saveVoice token defined at line 136
cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice
hr = cpContainerLexicon->AddLexicon( cpLexicon, eLEXTYPE_APP );
langId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
hr = SpCreatePhoneConverter( langId, NULL, NULL, &cpPhoneConv );
int wchars_num = MultiByteToWideChar( CP_ACP, 0, addPron, -1, NULL, 0 );
wchar_t* pronWstr = new wchar_t[ wchars_num ];
MultiByteToWideChar( CP_ACP, 0, addPron, -1, pronWstr, wchars_num );
int phonWchars_num = MultiByteToWideChar( CP_ACP, 0, phon, -1, NULL, 0 );
wchar_t* phonWstr = new wchar_t[ phonWchars_num ];
MultiByteToWideChar( CP_ACP, 0, phon, -1, phonWstr, phonWchars_num );
if(SUCCEEDED( hr ))
{
hr = cpPhoneConv->PhoneToId( phonWstr, wszId );
hr = cpVoice->Speak( phonWstr, SPF_DEFAULT, NULL );
hr = cpLexicon->AddPronunciation( pronWstr, langId, SPPS_Noun, wszId );
hr = cpVoice->Speak( pronWstr, SPF_DEFAULT, NULL );
if( SUCCEEDED( hr ) )
{
printf( "Success\n" );
}
else
{
printf( "Failed\n" );
}
}
cpEnum.Release();
cpVoiceToken.Release();
cpContainerLexicon.Release();
cpLexicon.Release();
cpPhoneConv.Release();
delete new wchar_t[ wchars_num ];
delete new wchar_t[ phonWchars_num ];
return true;
}
Now I would like to list these words using ISpLexicon::GetWords.
I already read the documentation on the Microsoft website and tried to implement the function, but I can't figure out how to initialize the variable spWordList.
Here is my code:
ZeroMemory( &spWordList, sizeof( spWordList ) );
if( SUCCEEDED( hr ) )
{
hr = cpLexicon->GetWords( eLEXTYPE_APP, &dwGeneration, &dwCookie, &spWordList );
printf( "Words: %ls\n", spWordList ); //print words but the output is null
}
CoTaskMemFree( spWordList.pvBuffer );
I'm triying to print the words, but the output is null. I think the spWordList variable is not initialized. Here is a screenshot of the variable values.
How can I initialize it?
I found out how to initialize spWordList. You have to replace eLEXTYPE_APP with eLEXTYPE_USER. However, you can keep both of them like I did. Below you will find an example on how it lists the words.
ZeroMemory( &spWordList, sizeof( spWordList ) );
hr = S_FALSE;
if( hr == S_FALSE )
{
hr = cpLexicon->GetWords( eLEXTYPE_USER | eLEXTYPE_APP, &dwGeneration, &dwCookie, &spWordList );
for( spWord = spWordList.pFirstWord; spWord != NULL; spWord = spWord->pNextWord )
{
for( spWordPron = spWord->pFirstWordPronunciation; spWordPron != NULL; spWordPron = spWordPron->pNextWordPronunciation )
{
printf( "Words in dictionnary: %i\n", dwGeneration );
printf( "Word: %ls\n", spWord->pszWord );
//you can also display the pronunciation of words if you wish
}
}
}
CoTaskMemFree( spWordList.pvBuffer );
In the code, I loop through the entire dictionnary. Notice that the listed words are displayed randomly. I'll update my answer if I find other important information about ISpLexicon::GetWords

How to do password authentication for a user using LDAP?

I am writing a client app (using OpenLDAP libraries) for which the users gets authenticated via LDAP server.
Here is the sample, hard coded, program that fails to compare userPassword for a user.
#include <stdio.h>
#include <ldap.h>
#define LDAP_SERVER "ldap://192.168.1.95:389"
int main( int argc, char **argv ){
LDAP *ld;
int rc;
char bind_dn[100];
LDAPMessage *result, *e;
char *dn;
int has_value;
sprintf( bind_dn, "cn=%s,dc=ashwin,dc=com", "manager" );
printf( "Connecting as %s...\n", bind_dn );
if( ldap_initialize( &ld, LDAP_SERVER ) )
{
perror( "ldap_initialize" );
return( 1 );
}
rc = ldap_simple_bind_s( ld, bind_dn, "ashwin" );
if( rc != LDAP_SUCCESS )
{
fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc) );
return( 1 );
}
printf( "Successful authentication\n" );
rc = ldap_search_ext_s(ld, "dc=ashwin,dc=com", LDAP_SCOPE_SUBTREE, "sn=ashwin kumar", NULL, 0, NULL, NULL, NULL, 0, &result);
if ( rc != LDAP_SUCCESS ) {
fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
}
for ( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) {
if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
printf( "dn: %s\n", dn );
has_value = ldap_compare_s( ld, dn, "userPassword", "secret" );
switch ( has_value ) {
case LDAP_COMPARE_TRUE:
printf( "Works.\n");
break;
case LDAP_COMPARE_FALSE:
printf( "Failed.\n");
break;
default:
ldap_perror( ld, "ldap_compare_s" );
return( 1 );
}
ldap_memfree( dn );
}
}
ldap_msgfree( result );
ldap_unbind( ld );
return( 0 );
}
userPassword if it is plain in LDAP server, it works.
the same password if it is MD5 encrypted, ldap_compare_s fails. And that's because I am passing the cleartext password to compare.
How do I get this sample program working?
Am I doing this right? Is it correct to use ldap_compare_s to authenticate user via LDAP?
P.S: This is the first time I am working on LDAP.
This is not really the right way to perform a password check on LDAP, what you should do is attempt to bind using the dn obtained from the first search and the password supplied.
i.e. you perform a second bind to verify the password. If the bind fails then the password is incorrect.
Something akin to:
if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
printf( "dn: %s\n", dn );
/* rebind */
ldap_initialize(&ld2, LDAP_SERVER);
rc = ldap_simple_bind_s(ld2, dn, "secret");
printf("%d\n", rc);
if (rc != 0) {
printf("Failed.\n");
} else {
printf("Works.\n");
ldap_unbind(ld2);
}
ldap_memfree( dn );
}
For security reasons indicating that the username is incorrect (i.e. the search for the user account fails) is generally considered excessive disclosure, and should be avoided.

MS Kinect FaceTracker creating IFTResult

I have a fairly simple application that contains the following:
context->mFaceTracker = FTCreateFaceTracker();
hr = context->mFaceTracker->Initialize( &mVideoCameraConfig, &mDepthCameraConfig, NULL, NULL );
which works fine and returns S_OK and mFaceTracker is (as far as I can tell) initialized properly. However, the next line is:
hr = context->mFaceTracker->CreateFTResult( &context->mFTResult );
which always returns FT_ERROR_UNINITIALIZED, doesn't allocate the pointer, and has me puzzled. I've tried many different strategies for getting this to work from changing how the threading for the device and detector works, to changing my FTcontext object from a class to a struct to match the samples, all with no success. The Kinect SDK samples all work fine, but trying to use them in my own application doesn't seem to, despite my closely mirroring how they initialize the device and the Face Tracker. I'm curious if anyone else has run into this or similar problems around initializing either IFTFaceTracker or the IFTResult. Also, I'm curious how else I can test the IFTFaceTracker for correct intialization, other than testing the HRESULT that Initialize() returns. Thanks in advance,
=== edit
I've had a few request for more code. It's built on Cinder and is using this block for Cinder: https://github.com/BanTheRewind/Cinder-KinectSdk
I can't post all of the code, but I've posted at least most of the relevant Kinect initialization code here:
void Kinect::start( const DeviceOptions &deviceOptions )
{
if ( !mCapture ) {
// Copy device options
mDeviceOptions = deviceOptions;
string deviceId = mDeviceOptions.getDeviceId();
int32_t index = mDeviceOptions.getDeviceIndex();
// Clamp device index
if ( index >= 0 ) {
index = math<int32_t>::clamp( index, 0, math<int32_t>::max( getDeviceCount() - 1, 0 ) );
}
// Initialize device instance
long hr = S_OK;
if ( index >= 0 ) {
hr = NuiCreateSensorByIndex( index, &mSensor );
if ( FAILED( hr ) ) {
trace( "Unable to create device instance " + toString( index ) + ": " );
error( hr );
return;
}
} else if ( deviceId.length() > 0 ) {
_bstr_t id = deviceId.c_str();
hr = NuiCreateSensorById( id, &mSensor );
if ( FAILED( hr ) ) {
trace( "Unable to create device instance " + deviceId + ":" );
error( hr );
return;
}
} else {
trace( "Invalid device name or index." );
return;
}
// Check device
hr = mSensor != 0 ? mSensor->NuiStatus() : E_NUI_NOTCONNECTED;
if ( hr == E_NUI_NOTCONNECTED ) {
error( hr );
return;
}
// Get device name and index
if ( mSensor != 0 ) {
mDeviceOptions.setDeviceIndex( mSensor->NuiInstanceIndex() );
BSTR id = ::SysAllocString( mSensor->NuiDeviceConnectionId() );
_bstr_t idStr( id );
if ( idStr.length() > 0 ) {
std::string str( idStr );
mDeviceOptions.setDeviceId( str );
}
::SysFreeString( id );
} else {
index = -1;
deviceId = "";
}
flags |= NUI_INITIALIZE_FLAG_USES_COLOR;
}
hr = mSensor->NuiInitialize( flags );
if ( FAILED( hr ) ) {
trace( "Unable to initialize device " + mDeviceOptions.getDeviceId() + ":" );
error( hr );
return;
}
hr = mSensor->NuiSkeletonTrackingEnable( 0, flags );
if ( FAILED( hr ) ) {
trace( "Unable to initialize skeleton tracking for device " + mDeviceOptions.getDeviceId() + ": " );
error( hr );
return;
}
mIsSkeletonDevice = true;
mThread = CreateThread(NULL, 0, &Kinect::StaticThread, (PVOID)this, 0, 0);
}
}
DWORD WINAPI Kinect::StaticThread(PVOID lpParam)
{
Kinect* device = static_cast<Kinect*>(lpParam);
if (device)
{
return device->run();
}
return 0;
}
void run() {
if(mSensor) {
if(mEnabledFaceTracking)
{
if(mNeedFaceTracker) {
mFaceTracker = new FaceTracker(
mDeviceOptions.getVideoSize().x,
mDeviceOptions.getVideoSize().y,
mDeviceOptions.getDepthSize().x,
mDeviceOptions.getDepthSize().y,
1.0,
1 );
mNeedFaceTracker = false;
}
// make sure we have both color && depth buffers to work with
if(newDepth || newVideo)
{
FT_SENSOR_DATA sensorData(mFTColorImage, mFTDepthImage);
FT_VECTOR3D hint[2]; // this is initialized elsewhere
mFaceTracker->checkFaces( (NUI_SKELETON_FRAME*) &skeletonFrame, mFTColorImage, mFTDepthImage, 1.0, 0);
if(mFaceTracker->getNumFaces() > 0) {
cout << " we have a face " << mFaceTracker->getNumFaces() << endl;
mNewFaceTrackData = true;
mFaceData.clear();
for( int i = 0; i < mFaceTracker->getNumFaces(); i++) {
Face newFace;
mFaceTracker->getProjectedShape(0, newFace.scale, newFace.rotation, newFace.transform, newFace.screenPositions);
mFaceData.push_back(newFace);
}
}
}
}
Sleep( 8 );
}
}
It looks like you never call (or omitted including in the code sample) NuiImageStreamOpen(), such as this code snippet from the SingleFace sample, KinectSensor.cpp in the Init method:
hr = NuiImageStreamOpen(
colorType,
colorRes,
0,
2,
m_hNextVideoFrameEvent,
&m_pVideoStreamHandle );
if (FAILED(hr))
{
return hr;
}
hr = NuiImageStreamOpen(
depthType,
depthRes,
(bNearMode)? NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE : 0,
2,
m_hNextDepthFrameEvent,
&m_pDepthStreamHandle );
Calling those before you call CreateFTResult() may fix the uninitialized error.
Additionally, you call CreateThread() and then call run(), but there is no while loop so that thread will exit almost immediately, certainly without enough time for the Kinect to start providing data to the FaceTracking.
It doesn't look like you have included the Thread or event loop that is checking the sensor for new data, updating mFTColorImage and mFTDepthImage, and setting the newDepth and newVideo flags. This could be in the same thread that you create above (provided you create a while loop, and ignoring performance or other classes needing the Kinect data), or could be a different thread as in the SingleFace Kinect SDK sample.

SQLGetData issues using C++ and SQL Native Client

I have a C++ application that uses SQL Native Client to connect to a MS SQL Server 2000.
I am trying to retrieve a result from a TEXT column containing more data than the buffer initially allocated to it provides. To clarify my issue, I'll outline what I'm doing (code below):
allocate buffer of 1024 bytes use
bind buffer to column using SQLBindColumn
execute a SELECT query using SQLExecute
iterate through results using SQLFetch
SQLFetch was unable to return the entire result to my buffer: I'd like to use SQLGetData to retrieve the entire column value
The above order of operations presents a problem: SQLGetData does not work on bound columns in my driver.
A working solution is to use the SQL_DATA_AT_EXEC flag as illustrated by the code below.
Begin code:
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <sqlncli.h>
#include <cstdio>
#include <string>
const int MAX_CHAR = 1024;
bool test_retcode( RETCODE my_code, const char* my_message )
{
bool success = ( my_code == SQL_SUCCESS_WITH_INFO || my_code == SQL_SUCCESS );
if ( ! success )
{
printf( "%s", my_message );
}
return success;
}
int main ( )
{
SQLHENV EnvironmentHandle;
RETCODE retcode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvironmentHandle );
test_retcode( retcode, "SQLAllocHandle(Env) failed!" );
retcode = SQLSetEnvAttr( EnvironmentHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER );
test_retcode( retcode, "SQLSetEnvAttr(ODBC version) Failed" );
SQLHDBC ConnHandle;
retcode = SQLAllocHandle( SQL_HANDLE_DBC, EnvironmentHandle, &ConnHandle );
test_retcode( retcode, "Could not allocate MS SQL 2000 connection handle." );
SQLSMALLINT driver_out_length;
retcode = SQLDriverConnect( ConnHandle,
NULL, // we're not interested in spawning a window
(SQLCHAR*) "DRIVER={SQL Native Client};SERVER=localhost;UID=username;PWD=password;Database=Test;",
SQL_NTS,
NULL,
0,
&driver_out_length,
SQL_DRIVER_NOPROMPT );
test_retcode( retcode, "SQLConnect() Failed" );
SQLHSTMT StatementHandle;
retcode = SQLAllocHandle(SQL_HANDLE_STMT, ConnHandle, &StatementHandle);
test_retcode( retcode, "Failed to allocate SQL Statement handle." );
char* buffer = new char[ MAX_CHAR ];
SQLINTEGER length = MAX_CHAR - 1;
// -- Bind Block
retcode = SQLBindCol( StatementHandle,
1,
SQL_C_CHAR,
(SQLPOINTER) NULL,
(SQLINTEGER) SQL_DATA_AT_EXEC,
&length );
test_retcode( retcode, "Failed to bind column." );
// -- End Bind Block
retcode = SQLExecDirect( StatementHandle, (SQLCHAR*) "SELECT VeryLong FROM LongData", SQL_NTS );
test_retcode( retcode, "SQLExecDirect failed." );
// -- Fetch Block
retcode = SQLFetch( StatementHandle );
if ( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO && retcode != SQL_NO_DATA )
{
printf( "Problem fetching row.\n" );
return 9;
}
printf( "Fetched data. length: %d\n", length );
// -- End Fetch Block
bool sql_success;
std::string data;
RETCODE r2;
do
{
r2 = SQLGetData( StatementHandle, 1, SQL_C_CHAR, buffer, MAX_CHAR, &length );
if ( sql_success = test_retcode( r2, "SQLGetData failed." ) )
{
data.append( buffer );
}
else
{
char* err_msg = new char[ MAX_CHAR ];
SQLSMALLINT req = 1;
SQLCHAR state[6];
SQLINTEGER error;
SQLINTEGER output_length;
int sql_state = SQLGetDiagRec( SQL_HANDLE_STMT, StatementHandle, req, state, &error, (SQLCHAR*) err_msg, (SQLINTEGER) MAX_CHAR, (SQLSMALLINT*) &output_length );
// state is: 07009, error_msg: "[Microsoft][SQL Native Client]Invalid Descriptor Index"
printf( "%s\n", err_msg );
delete err_msg;
return 9;
}
}
while ( sql_success && r2 != SQL_SUCCESS );
printf( "Done.\n" );
return 0;
}
Try to put SQLBindCol after SQLExecDirect.
For TEXT column use
retcode = SQLBindCol( StatementHandle, 1, SQL_C_CHAR,
(SQLPOINTER) NULL, (SQLINTEGER) SQL_DATA_AT_EXEC, &length );
in this way you can repeat SQLGetData to read entire TEXT data in multiple pieces