We've done some changes to this issue recently, so I'd like to clarify
what exactly has happened, when and why.
A bit of history first:
1) Initially, data library allowed end user to pass variables,
references and literals to use() function:
int i = 0;
session << "select * from table where field1 = ? and field2 = ?",
2) With introduction of ODBC connector, the semantics behind the
interface changed (compared to SQLite's copy semantics) and framework
assumed passed values to still be in their places at execution time.
Obviously, passing something that goes out of scope before statement
execution is something not to do in this scenario.
3) Additionally, with stored procedure support introduction, entities
passed to the framework could be of IN, OUT (or both) type, which
further aggravated the issue, especially in conjunction with a C API
like ODBC which has no notion of constness.
4) Due to (2) and (3), (1) became very troublesome because end user
could pass temporaries or const values which could, in turn, not exist
or get written to at execution time. So, I decided to tidy up things,
ban passing references to use() and introduced bind() (which makes a
copy of whatever is passed as parameter to use() ). It was this change
that triggered the current mailing list thread.
Recently, in order to alleviate the restriction introduced by 4),
there have been some changes to the SVN trunk code regarding this
subject. While it was a valid decision to provide increased safety, we
have decided that complete ban on passing const reference is a bit too
much of restriction. Although some refactoring in the guts of Data
libraries have been done, the existing interface semantics remains as
is, with addition of useRef() function that accepts const references
(and expects the user to be aware of the dangers).
Generally speaking, an end user should adhere to following rules:
1) pass literals to bind() only
2) pass const references to useRef()
3) pass values and non-const references to use()
For code samples of what (not) to do, see SQLiteTest::testBinding():
The history of recent Binding.h changes can be found here:
Revisions 541, 542, 545 contain the relevant changes.
Any feedback and/or opinion on the issue is welcome.
On Thu, Jan 24, 2008 at 6:22 AM, Mark Marsh <poco@...> wrote:
> I see what you mean but I see it as the reverse - 'use() a value' which to
> me implies that the value is used by the function but not altered and
> 'bind() a variable' which to me implies that the variable is used for
> returning results. Maybe I'm just thinking backwards - it wouldn't be the
> first time...
> Whatever you call the functions, it's a big improvement on .Net which is
> what I'm using at the moment :-)
> On Jan 24, 2008 2:13 AM, Alex Fabijanic < aleskx@...> wrote:
>> On Jan 23, 2008 9:01 AM, Mark Marsh < poco@...> wrote:
>>> The changes make sense but I'm not so sure about the naming - what do you
>>> think about calling the functions input and output?
>> The problem with those names is that they do not describe what these
>> functions do. Both use() and bind() are input functions. They just have
>> different semantics behind them - use() uses the reference to the supplied
>> value, while bind() makes a copy of it and "binds" it to the binding owned
>> by statement. This brings with it the benefit that the statement owns the
>> bound storage after the original goes out of scope and has a performance
>> downside if storage is a huge container. Regarding the names that you have
>> proposed, we already have something along the lines - in(), out() and io()
>> to deal with parameters passed to stored procedures that can read from and
>> write data into the supplied buffers.
>> At any rate, I'm willing to consider more proposals for the naming of
>> bind(). If anyone has any, let me know.