Skip to content

Ability to get sqlite3 handle in sqlite::database #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mathieugarcia opened this issue Jan 22, 2016 · 9 comments
Closed

Ability to get sqlite3 handle in sqlite::database #29

mathieugarcia opened this issue Jan 22, 2016 · 9 comments

Comments

@mathieugarcia
Copy link

Hi,

I think it would be beneficial to have an accessor the the sqlite3 "db_" member in sqlite::database. I need to call a specific function but I don't want to mess with the sqlite3 initialization myself.

Is that something you think is worth adding ?

Thank you !

@aminroosta
Copy link
Collaborator

Hi Mathieu,
If your specific function is a general problem that needs to be addressed by the library, you can explain it here and we will try to add it to the library.

the sqlite3 * _db; filed is private, if you really need this member field just make it public.
but don't send a PR for that, because i don't want to expose internal slqite3 stuff to the library users.

Thanks.

@Killili
Copy link
Collaborator

Killili commented Jan 22, 2016

Funny, i was just thinking about that. There are some cases i would like to get that handle out of the lib myself but i like that the lib is handling all the connection disconnection stuff.

So i would propose a change that would be more in line with the C++ ideology in terms of resources and RAII and capsule the sqlite3* in a std::shared_pointer with a custom destructor to close the DB properly when nobody is using it. This way we can expose the sqlite3* to the outside world (with an accessor of course) and still be sure it will be handled correctly.

@aminroosta
Copy link
Collaborator

Hi Killili,

What are the specific use-case you have for the handle? If there is a general problem we should address it via library itself.

I dont think making things complicated to access a member field will help average users. Professional users will probably hack their way into the library and add their custom tweaks.

But if there is a general problem or use-case we can definitely implement it.

Thanks ;)

Sent from Outlook Mobile

From: Killili

Sent: Friday, January 22, 6:37 PM

Subject: Re: [sqlite_modern_cpp] Ability to get sqlite3 handle in sqlite::database (#29)

To: aminroosta/sqlite_modern_cpp

Cc: amin roosta

Funny, i was just thinking about that. There are some cases i would like to get that handle out of the lib myself but i like that the lib is handling all the connection disconnection stuff.

So i would propose a change that would be more in line with the C++ ideology in terms of resources and RAII and capsule the sqlite3* in a std::shared_pointer with a custom destructor to close the DB properly when nobody is using it. This way we can expose the sqlite3* to the outside world (with an accessor of course) and still be sure it will be handled correctly.

Reply to this email directly or view it on GitHub.

@Killili
Copy link
Collaborator

Killili commented Jan 22, 2016

I have a use case where i need to run sqlite3_backup_init on an instance of our lib and a plain sqlite3* database. For now I have too init our lib with sqlite3* so that i have an outside copy of it and store it in a global variable to use it at that point.
If i just extract the sqlite3* from that, at that point known, instance of the lib and be sure that the instance will not close the handle while i do my backup, it would be realy nice.

And its not complicating things its making them more consistent with the direction of the standard. In this case "Try to avoid plain pointers". We somewhat do by encapsulating the pointer in our lib but as i and the OP see there are cases where we need to get to the "metal" of the sqlite API.

I will post a PR so you can see what im proposing and then decide.

@aminroosta
Copy link
Collaborator

Yeah, Sure.

I am only expressing my thoughts here ;)

Sent from Outlook Mobile

Killili added a commit that referenced this issue Jan 22, 2016
@Killili
Copy link
Collaborator

Killili commented Jan 22, 2016

Turns out it even cleans up sqlite::database a bit, no more _ownsConnection and stuff.
I included 2 diffrent initis of the shared_ptr and suggest moving the error throwing to a static database member instead of dbbinder.
And if youre ok with this i would add the shared_ptr to the dbbinder,too. For now its still plain.

A bit of a lame example why that change would be nice, it makes sense in the proper context here ;)

        sqlite3* other;
        std::shared_ptr<sqlite3> con;

        { // scope somewhere else
          // creates a database file 'dbfile.db' if it does not exists.
            database db("dbfile.db");
            con = db.get_sqlite3_connection();
        } // destroy db but keep con

        // reuse con
        sqlite3_backup_init(other, "main", con.get(), "main");

@aminroosta
Copy link
Collaborator

@Killili
Definitely a good change. Using shared_ptr<T> is the right thing to do.
I too think that throw_sqlite_error should be moved to database class.

Also i think we can use the same shared_ptr<T> technique to replace sqlite3_statement class.
What do you think?

And yeah please also update datatabase_binder class,
Just don't name it in the documentation, I don't want users to write code against this class.

@Killili please write your sqlite3_backup_init example in readme and explain a little bit about it, i have never used this feature of sqlite before :), its a practical use-case 👍

Thanks.

@Killili
Copy link
Collaborator

Killili commented Jan 23, 2016

Hi,
there is something realy wrong with datatabase_binder. I guess we are using some undefined behavior there.

so in database we have this:

database_binder operator<<(std::string const& sql) const {
    return database_binder(_db, sql);
}

as far as i see it this copy constructs a copy of the stack allocated database_binder object and then destroys that stack object but not before it hits a semicolon.

db << "sql" << something; // works

auto &pps = db << "sql"; // pps is a copy constructed instance of the original stack based one and the original is cleaned up after this line leaving pps hanging.
pps << something; // this is valid syntax but pps points to an unitialized object

@aminroosta
I'm not sure if that is why ppl should not use that class or if its a bug that needs fixing?

I see potential in fixing it, it would be a way to have prepared statments and reuse them as in:

std::unique_ptr<database_binder> pps = db << "REALLY COMPLEX SQL HERE"; // prepares the query plan
pps << input; // runs it once because operator <<(unique_ptr... , ) returns plain database_binder so it gets destroyed and resets pps
pps << input2; // runs again without planing overhead

Killili added a commit that referenced this issue Jan 23, 2016
Major Changes and General Overhaul of the everything.

-Refactored
exceptions into its own namespace
-removed rvalue references where they
are not needed
-made prepared statments possible
-made them
reusable
-removed some template magic
aminroosta added a commit that referenced this issue Jan 24, 2016
Changed the way arguments are chained #29
@Killili
Copy link
Collaborator

Killili commented Jan 24, 2016

See shared connections in the brand new V2 of this lib.

@Killili Killili closed this as completed Jan 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants