On 21 November 2011 11:08, Mika Fischer <[email protected]> wrote:
> 2011/11/19 Mateusz Łoskot <[email protected]>:
>>        for (int i = 0; i != 10; i++)
>>        {
>>            sql << "insert into soci_test(val) values(:val)", use(i);
>>        }
>>
>>        statement st1 = (sql.prepare <<
>>            "update soci_test set val = val + 1");
>>        st1.execute(false);
>>        std::cout << st1.get_affected_rows() << std::endl;
>>
>> It prints1 instead of 10.
>>
>> Do you get correct results?
>
> No, but I do get correct result when I use execute(true). Since I was
> never quite sure what the bool flag to execute really does, I don't
> really know why the behavior is as it is. Maybe you can clarify what
> the bool really does.

I found a moment to take a closer look at this issue.

Here is a bit of explanation of the execute() flag with examples:
http://soci.sourceforge.net/doc/statements.html

Indeed, st.execute needs to be passed with true flag otherwise,
in case of SQLite3 backend it means "lazy evaluation" - SQL evaluation
is delayed until necessary.
Simply, it does nothing without follow-up with st.fetch()

execute(false) leads to call sqlite3_statement_backend::execute(0)
If you look at the sqlite3_statement_backend::execute, there is condition

        if (1 == number)
        {
            retVal = load_one();
        }
        else
        {
            retVal = load_rowset(number);
        }

loda_rowset evaluates SQL and if number==0 the call to sqlite3_step is skipped.

It is going to be tricky to distinguish when data exchange flag means
INSERT, UPDATE
or when it means lazy evaluation of SQL followed by fetch().

Possible solution is to replace for loop with do-while and make
load_rowset always
makes first call to sqlite3_step and set flag in statement as "prefetched".
Then st.fetch() checks the flag and either gets prefetched data or
calls sqlite3_step
and then gets data. Finally, st.fetch() resets the flag to not prefetched.
Then subsequent calls to st.fetch() will always call  sqlite3_step.

I may give it a try if I find some time.
Alternative for now is to always call execute(true) if you rely on
get_affected_rows.
Although, I understand it is backend specific behaviour.

Best regards,
-- 
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org
Member of ACCU, http://accu.org

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure 
contains a definitive record of customers, application performance, 
security threats, fraudulent activity, and more. Splunk takes this 
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
Soci-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/soci-users

Reply via email to