I am reading an application written in C++, calling stored procedures from remote sql server 2005 db.
I found it is using two different methods to make the remote SP calls.
use dbfcmd
int ProcessMsg1(PDBPROCESS dbproc){
dbfcmd(dbproc,"exec message1_proc '%s'",blk->msgtype);
dbsqlexec(dbproc);
if (dbretstatus(dbproc)==-1)
printf("dbsqlexec failed.\n");
}
use dbrpcinit, dbrpcparam, dbrpcsend
int ProcessMsg2(PDBPROCESS dbproc){
dbrpcinit(dbproc, "message2_proc", (DBSMALLINT)0);
dbrpcparam(dbproc, "#MType", 0, SQLCHAR, 4, 4, blk->msgtype);
if ((dbrpcsend(dbproc) == FAIL))
printf("dbrpcsend failed.\n");
}
I could not find an comparison of two methods from google. Any one can explain the difference of two methods and when have to use what?
The first one is using string concatenation, a recipe for SQL Injection disasters, plan cache bloat, excessive server side parsing etc., albeit the effect of these is reduced in this case as a stored procedure is being called.
The second one uses a Prepared Statement, i.e. the right way to do it.
Related
I have a .lua file as follows:
timeout = 3000
index = 15
function Test()
A(index, timeout)
B()
end
Test()
A and B fuctions are implemented in the c++. It will be excuted with a 'luaL_dofile(L, "test.lua");' in c++.But the timeout and the index will change at different times.
The question is how to modify the params in real time?
I'm going to write two c++ programs.First one is to sent .lua string to the sencond one. The second c++ program implemets the A and B and will dofile the lua script. But the timeout and the index will changes very often. How to do that? My solution is to parse the index and timeout string ,then write the current value to the file in the first c++ program.Any better solution?
Instead of modifying a lua script over and over to call A with different arguments, you should probably just list all arugments in a single script.
local listOfIndices = {1,5,23,124,25,}
local timeout = 3000
for _,index in ipairs(listOfIndices) do
A(index, timeout)
B()
end
Otherwise having 10000 different indices will result in 10000 file write and read operations.
If you're on Windows you might want to give this a read https://learn.microsoft.com/de-de/windows/win32/ipc/interprocess-communications?redirectedfrom=MSDN
I can think of better ways to have two programs communicate, than sending Lua scripts through files.
Also I'm not sure why you need two applications here, why not add whatever applicaton 2 does to application 1 as a library?
I have an sqlite database that doesn't change.
Multiple processes that open a database connection each in SQLITE_OPEN_READONLY mode using sqlite3_open_v2. Each process is single threaded
The connections are made from an MSVC project using the official C/C++ Interface's single amalgamated C source file.
According to the SQLite FAQ multiple processes running SELECTs is fine
Each process after opening the database creates 4 prepared SELECT statements each with 2 bindable values.
Over the course of the execution the statements (one at a time) have the following called on them repeatedly as required
sqlite3_bind_int
sqlite3_bind_int
sqlite3_step (while SQLITE_ROW is returned)
sqlite3_column_int (while there was a row)
sqlite3_reset
The prepared statements are reused so finalize isn't called on each of them until near the end of the program. Finally the database is closed at the very end of execution.
The problem is any of these operations can fail with error code = 5: 'database is locked'
Error code 5 is SQLITE_BUSY and the website states that
"indicates a conflict with a separate database connection, probably in a separate process"
The rest of the internet seems to agree that multiple READONLY connections is fine. I've gone over and over the source and can't see that anything is wrong (I can't post it here sadly, I know, not helpful)
So I'm turning it to you guys, what could I possibly be missing?
EDIT 1:
Database is on a local drive, File system is NTFS, OS is Windows 7.
EDIT 2:
Wrapping all sqlite3 calls in infinite loops that check if SQLITE_BUSY was returned and then remake the call alleviates the problem. I don't consider this a fix but if that truly is the right thing to do then I'll do that.
So the working answer I have used is to wrap all the calls to sqlite in functions that loop that function while SQLITE_BUSY is returned. There doesn't seem to be a simple alternative.
const int bindInt(sqlite3_stmt* stmt, int parameterIndex, int value)
{
int ret;
do
ret = sqlite3_bind_int(stmt, parameterIndex, value);
while (ret == SQLITE_BUSY)
return ret;
}
I have some C++ code on Windows that uses plain old ADO (not ADO.NET) to retrieve data from a bunch of SQL Server databases. The code uses forward-only cursors to allow for fire hose cursors for maximum data throughput on queries that produce large Recordsets.
The code that processes the results looks like this, using the #import-generated wrapper for ADO 2.7:
ADODB::_RecordsetPtr records("ADODB.Recordset");
records->Open(cmd, _variant_t(static_cast<IDispatch *>(m_DBConnection)), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText);
if (!(records->BOF && records->EOF))
{
... Loop over the recordset and extract data from each record ...
}
Profiling shows that close to 40% of the above loop is spent in the call to BOF and this is having a massive impact on the overall database code's read performance. Because the code uses forward only cursors, it's not possible to check the RecordCount property as it is always -1 when using a forward only cursor.
Is there another way to either check for an empty Recordset that is not using the BOF/EOF check, or a way to speed up this check?
The other alternative that I can think of at the moment is to use one of the other cursor types and check how that will affect data throughput.
I have a problem related to passing arguments to a C++ compiled executable. The program emulate the behaviour of a particular inference engine: the setup of the engine is load at runtime from an XML file, and then I want to call it from command line with different input values.
The characteristic of the input are:
Every time that I call the program, the input structure is different, because the system itself is different.
The input is a set of couple {name, value}, one for each part of the system.
I have to separate the configuration XML from the input.
I call the program from a PHP or Node.js server, since it return a result that I expose to the outside through an API.
Input value are obtained from an HTTP post request.
By now I have tried these solutions:
Pass it from the command line ex: "./mysoftware input1 value1 input2 value2 ...etc". A little unconfortable, since I have up to 200 input.
Create a file with all the couples name,value and then call the program that parse the file and then destroy at the end. This is a bottleneck of performance for my API, because at every call I have to create and destruct a file.
Does anyone know a better way to approach this problem?
3. Pass the values to the program via the standard input stream and read them from std::cin inside your C++ program.
I want to execute an untrusted .lua file in its own environment by calling lua_setfenv() so that it cannot affect any of my code.
The documentation for that function though only explains how to call a function, not how to execute a file.
Currently to run the file I use:
int error = luaL_loadfile(mState, path.c_str()) || lua_pcall(mState, 0, 0, 0);
Do I have to call the "dofile" lua function from the C API with lua_setfenv, or is there a more elegant way to do it?
See the discussion at the Lua User's Wiki of sandboxing, and the more general topic of script security. There are a number of subtle and not so subtle issues with this kind of thing. It can be done, but protecting against code such as for i=1,1e39 do end requires more than just restricting what functions are available to a sandbox.
The general technique is to create a function environment for the sandbox that has a whitelist of permitted functions in it. In some cases, that list might even be empty, but letting the user have access to pairs(), for example, is almost certainly harmless. The sandbox page has a list of the system functions broken down by their safety as a handy reference for constructing such a whitelist.
You then use lua_setfenv() to apply the function environment to the user's script which you loaded (but haven't yet executed) with lua_loadfile() or lua_loadstring() as appropriate. With the environment attached, you could execute it with lua_pcall() and friends. Before execution, some people have actually scanned the loaded bytecode for operations that they don't want to permit. That can be used to absolutely forbid loops or writing to global variables.
One other note is that the load functions will generally load either precompiled bytecode or Lua text. It turns out to be a lot safer if you never permit precompiled bytecode, as a number of ways to make the VM misbehave have been identified that all depend on handcrafting invalid bytecode. Since bytecode files begin with a well-defined byte sequence that is not plain ASCII text, all you need to do is read the script into a string buffer, test for the absense of the marker, and only pass it to lua_loadstring() if it is not bytecode.
There has been a fair amount of discussion at the Lua-L mailing list over the years of this kind of thing, so searching there is also likely to be helpful.
By the way, this is what I ended up doing:
/* Loads, compiles and executes an unstrusted file. */
bool Lua::RunUntrustedFile(const string& path)
{
if(luaL_loadfile(mState, path.c_str()))
{
ErrorLog(lua_tostring(mState, 1));
Pop(1);
return false;
}
Lua::SetMaximumInstructions(100000000);
lua_newtable(mState);
lua_setglobal(mState, "upload");
ASSERT(Lua::GetStackSize() == 1);
lua_getglobal(mState, "upload");
ASSERT_ALWAYS(lua_setfenv(mState, 1) != 0);
ASSERT(Lua::GetStackSize() == 1);
if(lua_pcall(mState, 0, 0, 0))
{
Lua::ClearMaximumInstructions();
ErrorLog(lua_tostring(mState, -1));
Pop(1);
return false;
}
ASSERT(Lua::GetStackSize() == 0);
Lua::ClearMaximumInstructions();
return true;
}
"Support" functions:
static void Pop(int elements = 1) { lua_pop(mState, elements); }
/* Sets a maximum number of instructions before throwing an error */
static void SetMaximumInstructions(int count) {
lua_sethook(mState, &Lua::MaximumInstructionsReached, LUA_MASKCOUNT, count);
}
static void ClearMaximumInstructions() {
lua_sethook(mState, &Lua::MaximumInstructionsReached, 0, 0);
}
static void MaximumInstructionsReached(lua_State *, lua_Debug *)
{
Error("The maximum number of instructions has been reached");
}
static int GetStackSize() { return lua_gettop(mState); }
luaL_loadfile() will load the chunk, then call lua_setfenv() to set the environment table, then call lua_pcall() to execute the chunk. See recent answer given by Judge Maygarden at Calling lua functions from .lua's using handles?