Poco::Data::Keywords::use not working for PostgreSQL? - poco-libraries

I'm trying to insert values in PostgreSQL with POCO. I'm trying to do it with Poco::Data::Keywords::use:
try
{
Poco::Data::PostgreSQL::Connector::registerConnector();
Poco::Data::Session session(Poco::Data::PostgreSQL::Connector::KEY,
"host=localhost port=5433 user=test password=test dbname=test_db");
int test1_id = 1;
int test2_id = 2;
int id = 0;
session << "insert into test (test1_id, test2_id) values (?, ?) returning id",
Poco::Data::Keywords::use(test1_id),
Poco::Data::Keywords::use(test2_id),
Poco::Data::Keywords::into(id),
Poco::Data::Keywords::now;
std::cout << "id = " << id << std::endl;
}
catch (const Poco::Exception& ex)
{
std::cout << "exception: " << ex.displayText() << std::endl;
}
But I'm getting an exception:
exception: PostgreSQL: [PostgreSQL]: postgresql_stmt_prepare error: ERROR: syntax error at or near ","
LINE 1: ... into test (test1_id, test2_id) values (?, ?) retur...
^
insert into test (test1_id, test2_id) values (?, ?) returning id
If I'm inserting other way:
session << "insert into presentation (test1_id, test2_id) values ('"
<< test1_id << "', '" << test2_id << "') returning id",
Poco::Data::Keywords::into(id),
Poco::Data::Keywords::now;
It works fine. What am I doing wrong with first way?

Works
session << "insert into test (test1_id, test2_id) values ($1, $2) returning id",
Poco::Data::Keywords::use(test1_id),
Poco::Data::Keywords::use(test2_id),
Poco::Data::Keywords::into(id),
Poco::Data::Keywords::now;

Its crazy, POCO does not provide any guide for PostgreSQL placeholders.
Here the solution
Basically: use $<place_holder_index> instead of '?'

Related

SQLITE c++ in Visual Studio

#include <iostream>
#include <SQLiteCpp/SQLiteCpp.h>
#include <SQLiteCpp/VariadicBind.h>
int main() {
std::cout << "SQlite3 version " << SQLite::VERSION << " (" << SQLite::getLibVersion() << ")" << std::endl;
std::cout << "SQliteC++ version " << SQLITECPP_VERSION << std::endl;
try {
SQLite::Database db("my.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
}
}
On debugging it shows the error saying "Unable to start the program 'C:\SQLITE\SQLITE\x64\Debug\SQLite.exe' - The system cannot find the file specified"
I am not sure what to do in this case.
I am trying to create a sql database and create a table on it and make a relation table out of the tables that I will be creating. But I am not able to create a database due to this issue and cannot move forward with my task

Get length scale factor of STEP CAD file with OpenCASCADE

I am trying to get the length unit conversion factor in OpenCASCADE, when importing a STEP format CAD file. In my test file the entity #184 sets the length to meters and during import will be converted to milimeters used by OpenCASCADE internally by default
...
#184=(
LENGTH_UNIT()
NAMED_UNIT(*)
SI_UNIT($,.METRE.)
);
...
I belive the function below is how it should be done, but no matter what i try the "Length_Unit" STEP entity is not matched, and therefore I can't get the scaling factor.
void step_unit_scaling(std::string const &file_name) {
STEPControl_Reader reader;
reader.ReadFile( file_name.c_str() );
const Handle(Interface_InterfaceModel) Model = reader.Model();
Handle(StepData_StepModel) aSM = Handle(StepData_StepModel)::DownCast(Model);
Standard_Integer NbEntities = Model->NbEntities();
for (int i=1; i<=NbEntities; i++) {
Handle(Standard_Transient) enti = aSM->Entity(i);
if (enti->IsKind (STANDARD_TYPE(StepBasic_LengthMeasureWithUnit))) {
Handle(StepBasic_LengthMeasureWithUnit) MWU = Handle(StepBasic_LengthMeasureWithUnit)::DownCast(enti);
Standard_Real scal_mm = MWU->ValueComponent();
std::cout << " --- !!! MATCH !!! --- scal_mm = " << scal_mm << std::endl;
}
}
}
Does anyone know if this is the correct approach, or if there perhaps is a better way.
If you search for an entity of a given type, you should check the types to find an error. The following line will show the actual entity type.
std::cout << "Entity type " << enti->DynamicType()->Name() << std::endl;
When I play with STEP files here, I see that your STEP line leads to an entity of type StepBasic_SiUnitAndLengthUnit. With this code I can test for some expected SI units:
if (enti->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit)))
{
Handle(StepBasic_SiUnitAndLengthUnit) unit =
Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(enti);
if (unit->HasPrefix() &&
(StepBasic_SiUnitName::StepBasic_sunMetre == unit->Name()) &&
(StepBasic_SiPrefix::StepBasic_spMilli == unit->Prefix()))
{
std::cout << "SI Unit is millimetre." << std::endl;
}
else if (!unit->HasPrefix() &&
(StepBasic_SiUnitName::StepBasic_sunMetre == unit->Name()))
{
std::cout << "SI Unit is metre." << std::endl;
}
else
{
std::cout << "I did not understand that unit..." << std::endl;
}
}

QSqlQuery.next() return false but has data in database. Why?

I have data in my sqlite database. Insert statement executed successfully. But when want to get data from db i found nothing and this error "QSqlError("", "", "")". I have checked my query is active and not valid. How to solve this issue ?
Here is my code:
void FindDialog::find()
{
QString roll_number = ui->txt_RN->text ();
int roll = roll_number.toInt ();
const QString findstmnt = "SELECT Roll_Number, Name FROM student_info WHERE Roll_Number = :roll";
scon->getQuery ()->prepare (findstmnt);
scon->getQuery ()->bindValue ("roll", roll);
if(scon->getQuery ()->exec ()){
qDebug() << "Active: " << scon->getQuery ()->isActive ();
qDebug() << "Valid: " << scon->getQuery ()->isValid ();
if(scon->getQuery ()->isActive ()){
if(scon->getQuery ()->next ()){
qDebug() << "Has Data: " << scon->getQuery ()->next ();
} else {
qDebug() << scon->getQuery ()->lastError ();
}
}
} else {
qDebug() << scon->getQuery ()->lastError ();
}
The name of the parameter is not roll but :roll.
When you bind the value to the wrong parameter name, the actual parameter has its initial value, which is NULL.
So the query will never find any row because no value compares equal to NULL.

What strlen(pointer of char) is returning?

I got the following code :
char sir[1000], *psir;
cout << "Introduceti sirul de caractere: ";
strcpy(sir ,"merge") ;
int dim;
dim = sizeof(sir);
cout << "Dimensiunea zonei de memorie asociata variabilei masiv sir:"\
<< dim << endl;
dim = strlen(sir);
cout << "Lungimea sirului de caractere introdus:" << dim << endl;
psir = new char[dim + 1];
dim = strlen(psir);
When I run this code ,i get 22,on the last statement and I don't see why.
Can someone explain?
You're creating a new char array with New, which is great. But its not initialized, so asking about its contents would yield unexpected answers.

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

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.

Resources