Skip to content
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

Perform multiple commands in a single exec #113

Open
straight-shoota opened this issue Oct 13, 2019 · 2 comments
Open

Perform multiple commands in a single exec #113

straight-shoota opened this issue Oct 13, 2019 · 2 comments

Comments

@straight-shoota
Copy link
Member

In some use cases, you simply want to send a number of SQL commands to the server and have them executed in bulk. A basic example for this would be running a *.sql file.

DB.exec "CREATE TABLE foo (foo int); INSERT INTO foo VALUES (42);"

Currently, this is not really supported in crystal-db because QueryMethods#exec is implemented to always build a statement first and then execute it. But a statement can only be a single command.

So in order to execute commands in bulk there needs to be a way to bypass the statement creation and directly execute the query. This obviously makes it impossible to bind query arguments. But that's not an issue for bulk commands.
In fact, executing a query without arguments directly is usually much faster than building and executing a statement first. Golangs's pg driver for example uses simple queries as a performance improvement whenever there are no query arguments.

crystal-pg driver already provides a Connection#exec_all method which executes a simple query, supporting bulk commands. But this is only a driver-specific implementation. It requires a separate method and only works with pg.
It would be great to have a single interface with #exec allowing to execute multiple commands as long as no query arguments are used. This could be improved inside crystal-pg by overriding PG::Connection#exec, but Database#exec can't be overridden by a driver (or, shouldn't).

I suppose this could be implemented by changing QueryMethods#exec to delegate to a new methods #simple_exec when args are empty.

Connection#simple_exec would need to be implemented by the driver and it might fall back to build(query).exec. This could probably be used as default implementation.

Database#simple_exec would checkout a connection and delegate to the same method.

@straight-shoota
Copy link
Member Author

@bcardiff WDYT?

@bcardiff
Copy link
Member

The exec returns ExecResult, so the simple_exec would need to return the same struct if we want the crystal-db to do the optimization. Although crystal-pg already needs to ignore last_insert_id.

Maybe we can add a Database/Connection#run : Nil that takes no argument. And each driver could override the implementation if doing an exec of unprepared statements is not the best thing to do.

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

2 participants