What is the defined behavior of SQLite when interleaving statements that affect each other? - sqlite

In SQLite if I prepare a SELECT statement and begin stepping through it, then before the last row of the results is reached I execute another statement that has an effect on the SELECT statement that I am stepping through, what is the expected result?
I can't find anything in the SQLite documentation about what is supposed to happen but it seems like an extremely common case when programming in a multi-threaded environment.
Below is a c++ file that can be compiled and run on Windows to demonstrate the situation.
#include "stdafx.h"
#include "sqlite3.h"
#include <Windows.h>
#include <iostream>
#include <Knownfolders.h>
#include <Shlobj.h>
#include <wchar.h>
#include <comdef.h>
using namespace std;
int exec_sql(sqlite3 *db, const char* sql)
{
char *errmsg;
int result = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (result != SQLITE_OK) {
cout << errmsg << endl;
return -1;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Running jsqltst with SQLite version: ";
cout << sqlite3_libversion();
cout << endl;
PWSTR userhome;
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Profile, NULL, NULL, &userhome))) {
cout << "Failed getting user home dir\n";
return -1;
}
wcout << "User home: " << userhome << endl;
wchar_t *ws1 = userhome, *ws2 = L"\\test.sqlite";
wstring dbpath_str(ws1);
dbpath_str += wstring(ws2);
_bstr_t dbpath(dbpath_str.c_str());
cout << "DB path: " << dbpath << endl;
sqlite3 *db;
int result = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
if (result != SQLITE_OK) {
cout << sqlite3_errmsg(db) << endl;
return -1;
}
const char * create_stmt = "CREATE TABLE IF NOT EXISTS atable (id INTEGER PRIMARY KEY, name TEXT, number INTEGER);";
if (exec_sql(db, create_stmt) != 0) {
return -1;
}
const char * delete_stmt = "DELETE FROM atable;";
if (exec_sql(db, delete_stmt) != 0) {
return -1;
}
const char * insert_stmt = "INSERT INTO atable (name,number) VALUES ('Beta',77),('Alpha',99);";
if (exec_sql(db, insert_stmt) != 0) {
return -1;
}
sqlite3_stmt* select_ss;
const char * select_stmt = "SELECT * FROM atable;";
result = sqlite3_prepare_v2(db, select_stmt, -1, &select_ss, NULL);
if (result != SQLITE_OK) {
cout << sqlite3_errmsg(db) << endl;
return -1;
}
int i = 0;
boolean gotrow;
do {
result = sqlite3_step(select_ss);
gotrow = result == SQLITE_ROW;
if (gotrow) {
i++;
cout << "I got a row!" << endl;
if (i == 1) {
if (exec_sql(db, insert_stmt) != 0) {
return -1;
}
}
}
} while (gotrow);
cout << "Last result: " << result << ", errstr: " << sqlite3_errstr(result) << endl;
result = sqlite3_finalize(select_ss);
if (result != SQLITE_OK) {
cout << sqlite3_errmsg(db) << endl;
return -1;
}
return 0;
}

SQLite's behaviour for concurrent statements in the same transaction is neither documented nor defined.
As you have seen, newly inserted records might be seen when a SELECT's cursor has not yet reached that part of the table.
However, if SQLite needed to create a temporary result table for sorting or grouping, later changes in the table will not appear in that result.
Whether you have a temporary table or not might depend on decisions made by the query optimizer, so this is often not predictable.
If multiple threads access the same connection, SQLite will lock the DB around each sqlite3_step call.
This prevent data corruption, but you will still have the problem that automatic transaction end when their last active statement ends, and that explicit transaction will fail the COMMIT if there is some other active statement.
Multi-threaded programs are better off using (at least) one connection per thread.

Related

Reading from character device with Qt

I'm not very good at character devices, so I need your help. A have a char device(let's call it /dev/my_light) which is a light sensor. I have to read the data from this file and transform it to the brightness value and then pass it to the brightness manager that changes the brightness of my screen. The problem is that when I read the value for some period of time I get old values from the file.I assume there is a buffer(again not sure how character devices exactly work). Whereas when I use cat /dev/my_light I see new data! Is it possible to get rid off the buffer and read new values that were written to the file just right now. Here is my code in Qt:
void MySensor::updateMySensor()
{
Packet packet;
packet.startByte = 0;
packet.mantissa = 0;
packet.exp = 0;
d->device = ::open(d->path.toStdString().c_str(), O_RDONLY);
if (d->device == -1)
{
qDebug() << Q_FUNC_INFO << "can't open the sensor";
return;
}
ssize_t size = ::read(d->device, &packet, sizeof(packet));
close(d->device);
if (size == -1)
{
qDebug() << errno;
return;
}
packet.exp &= 0x0F;
float illumination = pow(2, packet.exp) * packet.mantissa * 0.045;
if(d->singleShot) emit lightSensorIsRunning(true);
emit illuminationRead(illumination);
}
The mySensor function is called every second. I tried to call it each 200 msec but it didn't help. The value of illumination stays old for about 7 seconds(!) whereas the value that I get from cat is new just immediately.
Thank you in advance!
I can't test with your specific device, however, I'm using the keyboard as a read only device.
The program attempts to connect to keyboard and read all keys pressed inside and outside the window. It's a broad solution you'll have to adapt to meet your demands.
Note that I'm opening the file with O_RDONLY | O_NONBLOCK which means open in read only mode and no wait for the event be triggered(some notifier needed to know when data is ready!) respectively.
You'll need super user privilege to run this example!
#include <QtCore>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const char *device_name = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
int descriptor = open(device_name, O_RDONLY | O_NONBLOCK);
if (descriptor < 0)
{
qDebug() << "Error" << strerror(errno);
return a.exec();
}
QFile device;
if (!device.open(descriptor, QFile::ReadOnly))
{
qDebug() << "Error" << qPrintable(device.errorString());
return a.exec();
}
QSocketNotifier notifier(device.handle(), QSocketNotifier::Read);
QObject::connect(&notifier, &QSocketNotifier::activated, &notifier, [&](int socket){
Q_UNUSED(socket)
struct input_event ev;
QByteArray data = device.readAll();
qDebug() << "Event caught:"
<< "\n\nDATA SIZE" << data.size()
<< "\nSTRUCT COUNT" << data.size() / int(sizeof(input_event))
<< "\nSTRUCT SIZE" << sizeof(input_event);
qDebug() << ""; //New line
while (data.size() >= int(sizeof(input_event)))
{
memcpy(&ev, data.data(), sizeof(input_event));
data.remove(0, int(sizeof(input_event)));
qDebug() << "TYPE" << ev.type << "CODE" << ev.code << "VALUE" << ev.value << "TIME" << ev.time.tv_sec;
}
qDebug() << ""; //New line
});
return a.exec();
}

How to use Intel realsense camera's (ZR300) with pre-made video or image instead live capture

I want to use pre-made files instead of live capture in the following program to track the person.
what is realsense SDK API used to load pre-made files and catch the frame by frame?
Is it possible to use to detect/track person any general video/image files which captured using any other camera's ?
Example Program:
Example Source Link
Source
#include <thread>
#include <iostream>
#include <signal.h>
#include "version.h"
#include "pt_utils.hpp"
#include "pt_console_display.hpp"
#include "pt_web_display.hpp"
#include "or_console_display.hpp"
#include "or_web_display.hpp"
using namespace std;
using namespace rs::core;
using namespace rs::object_recognition;
// Version number of the samples
extern constexpr auto rs_sample_version = concat("VERSION: ",RS_SAMPLE_VERSION_STR);
// Doing the OR processing for a frame can take longer than the frame interval, so we
// keep track of whether or not we are still processing the last frame.
bool is_or_processing_frame = false;
unique_ptr<web_display::pt_web_display> pt_web_view;
unique_ptr<web_display::or_web_display> or_web_view;
unique_ptr<console_display::pt_console_display> pt_console_view;
unique_ptr<console_display::or_console_display> or_console_view;
void processing_OR(correlated_sample_set or_sample_set, or_video_module_impl* impl, or_data_interface* or_data,
or_configuration_interface* or_configuration)
{
rs::core::status st;
// Declare data structure and size for results
rs::object_recognition::localization_data* localization_data = nullptr;
//Run object localization processing
st = impl->process_sample_set(or_sample_set);
if (st != rs::core::status_no_error)
{
is_or_processing_frame = false;
return;
}
// Retrieve recognition data from the or_data object
int array_size = 0;
st = or_data->query_localization_result(&localization_data, array_size);
if (st != rs::core::status_no_error)
{
is_or_processing_frame = false;
return;
}
//Send OR data to ui
if (localization_data && array_size != 0)
{
or_console_view->on_object_localization_data(localization_data, array_size, or_configuration);
or_web_view->on_object_localization_data(localization_data, array_size, or_configuration);
}
is_or_processing_frame = false;
}
int main(int argc,char* argv[])
{
rs::core::status st;
pt_utils pt_utils;
rs::core::image_info colorInfo,depthInfo;
rs::core::video_module_interface::actual_module_config actualModuleConfig;
rs::person_tracking::person_tracking_video_module_interface* ptModule = nullptr;
rs::object_recognition::or_video_module_impl impl;
rs::object_recognition::or_data_interface* or_data = nullptr;
rs::object_recognition::or_configuration_interface* or_configuration = nullptr;
cout << endl << "Initializing Camera, Object Recognition and Person Tracking modules" << endl;
if(pt_utils.init_camera(colorInfo,depthInfo,actualModuleConfig,impl,&or_data,&or_configuration) != rs::core::status_no_error)
{
cerr << "Error: Device is null." << endl << "Please connect a RealSense device and restart the application" << endl;
return -1;
}
pt_utils.init_person_tracking(&ptModule);
//Person Tracking Configuration. Set tracking mode to 0
ptModule->QueryConfiguration()->QueryTracking()->Enable();
ptModule->QueryConfiguration()->QueryTracking()->SetTrackingMode((Intel::RealSense::PersonTracking::PersonTrackingConfiguration::TrackingConfiguration::TrackingMode)0);
if(ptModule->set_module_config(actualModuleConfig) != rs::core::status_no_error)
{
cerr<<"error : failed to set the enabled module configuration" << endl;
return -1;
}
//Object Recognition Configuration
//Set mode to localization
or_configuration->set_recognition_mode(rs::object_recognition::recognition_mode::LOCALIZATION);
//Set the localization mechnizm to use CNN
or_configuration->set_localization_mechanism(rs::object_recognition::localization_mechanism::CNN);
//Ignore all objects under 0.7 probabilty (confidence)
or_configuration->set_recognition_confidence(0.7);
//Enabling object center feature
or_configuration->enable_object_center_estimation(true);
st = or_configuration->apply_changes();
if (st != rs::core::status_no_error)
return st;
//Launch GUI
string sample_name = argv[0];
// Create console view
pt_console_view = move(console_display::make_console_pt_display());
or_console_view = move(console_display::make_console_or_display());
// Create and start remote(Web) view
or_web_view = move(web_display::make_or_web_display(sample_name, 8000, true));
pt_web_view = move(web_display::make_pt_web_display(sample_name, 8000, true));
cout << endl << "-------- Press Esc key to exit --------" << endl << endl;
while (!pt_utils.user_request_exit())
{
//Get next frame
rs::core::correlated_sample_set* sample_set = pt_utils.get_sample_set(colorInfo,depthInfo);
rs::core::correlated_sample_set* sample_set_pt = pt_utils.get_sample_set(colorInfo,depthInfo);
//Increment reference count of images at sample set
for (int i = 0; i < static_cast<uint8_t>(rs::core::stream_type::max); ++i)
{
if (sample_set_pt->images[i] != nullptr)
{
sample_set_pt->images[i]->add_ref();
}
}
//Draw Color frames
auto colorImage = (*sample_set)[rs::core::stream_type::color];
pt_web_view->on_rgb_frame(10, colorImage->query_info().width, colorImage->query_info().height, colorImage->query_data());
//Run OR in a separate thread. Update GUI with the result
if (!is_or_processing_frame) // If we aren't already processing or for a frame:
{
is_or_processing_frame = true;
std::thread recognition_thread(processing_OR, *sample_set,
&impl, or_data, or_configuration);
recognition_thread.detach();
}
//Run Person Tracking
if (ptModule->process_sample_set(*sample_set_pt) != rs::core::status_no_error)
{
cerr << "error : failed to process sample" << endl;
continue;
}
//Update GUI with PT result
pt_console_view->on_person_info_update(ptModule);
pt_web_view->on_PT_tracking_update(ptModule);
}
pt_utils.stop_camera();
actualModuleConfig.projection->release();
return 0;
}
After installing the Realsense SKD, check the realsense_playback_device_sample for how to load the RSSDK capture file.
The short answer is not really. Beside the images that are captured from the other camera, you also need to supply the camera intrinsic and extrinsic settings in order to calculate the depth of and object and call the person tracking module.

"usage:\n\tll '(a+a)'" meaning in ll1 parser program

I am unable to understand what is the role of "usage:\n\tll '(a+a)'" in the code. What is its function?? I am using g++ compiler to compile the code. If more than 2 arguments are passed in command prompt then problem occurs.
#include <iostream>
#include <map>
#include <stack>
enum Symbols {
TS_L_PARENS,
TS_R_PARENS,
TS_A,
TS_PLUS,
TS_EOS,
TS_INVALID,
NTS_S,
NTS_F
};
enum Symbols lexer(char c)
{
switch(c)
{
case '(': return TS_L_PARENS;
case ')': return TS_R_PARENS;
case 'a': return TS_A;
case '+': return TS_PLUS;
case '\0': return TS_EOS;
default: return TS_INVALID;
}
}
int main(int argc, char **argv)
{
using namespace std;
if (argc < 2)
{
cout << **"usage:\n\tll '(a+a)'"** << endl;
return 0;
}
map< enum Symbols, map<enum Symbols, int> > table;
stack<enum Symbols> ss; // symbol stack
char *p; // input buffer
ss.push(TS_EOS); // terminal, $
ss.push(NTS_S); // non-terminal, S
p = &argv[1][0];
table[NTS_S][TS_L_PARENS] = 2;
table[NTS_S][TS_A] = 1;
table[NTS_F][TS_A] = 3;
while(ss.size() > 0)
{
if(lexer(*p) == ss.top())
{
cout << "Matched symbols: " << lexer(*p) << endl;
p++;
ss.pop();
}
else
{
cout << "Rule " << table[ss.top()][lexer(*p)] << endl;
switch(table[ss.top()][lexer(*p)])
{
case 1: // 1. S → F
ss.pop();
ss.push(NTS_F); // F
break;
case 2: // 2. S → ( S + F )
ss.pop();
ss.push(TS_R_PARENS); // )
ss.push(NTS_F); // F
ss.push(TS_PLUS); // +
ss.push(NTS_S); // S
ss.push(TS_L_PARENS); // (
break;
case 3: // 3. F → a
ss.pop();
ss.push(TS_A); // a
break;
default:
cout << "parsing table defaulted" << endl;
return 0;
break;
}
}
}
cout << "finished parsing" << endl;
return 0;
}
cout is the function, "usage:\n\tll '(a+a)'" is a string literal passed to the function. This bit in your question prints:
usage:
ll '(a+a)'

Not able to store binary data in sqlite using QT

Not able to store all binary data values into sqlite3 table using QT.
For this I have created a BLOB data column to store binary data table named as logTable.
I am trying to insert binary data to binary_data[] buffer, with values as 0x1 to 0xFF and 0x00 to 0xFF and so on till 1024 bytes. But when I execute the query to store the data, the table shows only 0x1 to 0xFF, but remaining character are not getting stored (since next immediate value is 0x00). I want to store all the binary data values?
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
conect_to_log_db("./log.db");
unsigned char binary_data[1024];
for(unsigned int i = 0, value = 1; i < 1024; i++, value++)
{
binary_data[i] = value;
}
store_to_log_db("01/02/2012,13:03:58", binary_data, 1024);
......
}
bool store_to_log_db(QString dateTime, unsigned char *data, unsigned int dataLength)
{
QSqlQuery objQuery(objLogsDB);
QString query = "CREATE TABLE IF NOT EXISTS logTable(logDateTime VARCHAR(19), packet BLOB, direction INTEGER)";
objQuery.exec(query);
QByteArray dataArr;
dataArr.resize(dataLength);
for(unsigned int i = 0; i < dataLength; i++)
{
dataArr[i] = data[i];
}
QVariant blobData = dataArr.data();
objQuery.prepare("INSERT INTO logTable VALUES(:logDateTime,:packet,:direction)");
objQuery.bindValue(":logDateTime",dateTime);
objQuery.bindValue(":packet",blobData,QSql::In | QSql::Binary);
objQuery.bindValue(":direction",1);
qDebug() << objQuery.exec();
return true;
}
after executing this code, the result of the table is till 254 characters when I output from sqlite using
$sqlite3 log.db
sqlite>.output try.txt
sqlite>select * from logTable;
$ls -l try.txt
size is 406 bytes
You must use .dump. The sqlite3 interactive client doesn't output BLOB columns.
$sqlite3 log.db
sqlite> .output try.txt
sqlite> .dump
sqlite> .quit
The code below is a self contained example of creating a simple blob-containing database.
// https://github.com/KubaO/stackoverflown/tree/master/questions/sqlite-blob-11062145
#include <QtSql>
int main()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./log.db");
if (!db.open()) { qDebug() << "can't open the database"; return 1; }
QSqlQuery query{db};
query.exec("DROP TABLE log");
if (!query.exec("CREATE TABLE log(packet BLOB)"))
qDebug() << "create table failed";
QVariant data[2] = {QByteArray{1024, 1}, QByteArray{2048, 2}};
query.prepare("INSERT INTO log VALUES(:packet)");
query.bindValue(":packet", data[0], QSql::In | QSql::Binary);
if (!query.exec()) qDebug() << "insert failed";
query.bindValue(":packet", data[1], QSql::In | QSql::Binary);
if (!query.exec()) qDebug() << "insert failed";
db.close();
if (!db.open()) { qDebug() << "can't reopen the database"; return 2; }
query.prepare("SELECT (packet) FROM log");
if (!query.exec()) qDebug() << "select failed";
for (auto const & d : data) if (query.next()) {
qDebug() << query.value(0).toByteArray().size() << d.toByteArray().size();
if (d != query.value(0)) qDebug() << "mismatched readback value";
}
db.close();
}

Qt: QGLShaderProgram turn off log messages

Is there a way to turn of log messages when calling QGLShaderProgram::link()?
http://qt-project.org/doc/qt-4.8/qglshaderprogram.html#link
Messages look like:
QGLShader::link: "Vertex shader(s) linked, fragment shader(s) linked.
"
Qt code looks like this:
src/opengl/qglshaderprogram.cpp:893
glLinkProgram(program);
value = 0;
glGetProgramiv(program, GL_LINK_STATUS, &value);
d->linked = (value != 0);
value = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
d->log = QString();
if (value > 1) {
char *logbuf = new char [value];
GLint len;
glGetProgramInfoLog(program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
QString name = objectName();
if (name.isEmpty())
qWarning() << "QGLShader::link:" << d->log;
else
qWarning() << "QGLShader::link[" << name << "]:" << d->log;
delete [] logbuf;
}
return d->linked;
}
So it seems the only possible solution is to redirect qWarning() as done in: How to redirect qDebug, qWarning, qCritical etc output?
qInstallMsgHandler([](QtMsgType , const char* ) { }); // empty message handler
bool result = program.link();
qInstallMsgHandler(0); // restore default message handling

Resources