Skip to content

New db function: execMany() - execute many statements with detailed results #413

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
wants to merge 11 commits into from
Closed

New db function: execMany() - execute many statements with detailed results #413

wants to merge 11 commits into from

Conversation

cpainterwakefield
Copy link
Contributor

Consider this a feature request - I need functionality as implemented here for my particular use case. So I wrote some code for it - please let me know if this is something you are willing to incorporate into sql-js. Thanks!

@cpainterwakefield
Copy link
Contributor Author

Hi, just wondering if anyone has taken a look at this. These are features I need for my use case; I'd like to get some sense of whether or not you might include in sql-js in some form, either in current version or next. If in current version great, if in next version, I might fork and use my fork until the next version comes out. Thanks!

@Taytay
Copy link
Contributor

Taytay commented Sep 10, 2020

I haven't taken a detailed look at the code yet, and am not particularly qualified to do so, but I have needed something similar, so I appreciate the contribution. I did notice that the statements don't allow for parameters, which would limit its use in my case and might lead to folks doing some dangerous SQL string manipulation to get this to work in their case. Without knowing the code well, I don't know how hard it would be to make it support parameters, but that was the first thing to stood out to me.

@cpainterwakefield
Copy link
Contributor Author

It would be possible to include parameters, and obviously that would be preferable for use cases where SQL injection is a possibility. The main thing there would be to work out the interface details (how best to provide the parameters to the function - as an array of arrays matching the # of queries, or maybe just an array of parameters to be used in order?) Once that was decided, I don't think it would be terribly hard to expand the function to use the parameters.

Copy link
Member

@lovasoa lovasoa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made comments on the implementation details of the PR. But my overall feeling on this is that it tries to address a very specific use case, and that the same could be achieved on the user side if we offered a more generic API. We could have a simple Database.iter_statements API that takes a string and returns an iterable over Statement objects. This would be more general, and would allow users to replicate this functionality in an idiomatic manner. Users could also bind parameters to their statements as they see fit. And we could additionally create a normalized_sql method on Statement that wraps sqlite3_normalized_sql.

* many result elements as the number of statements in your sql string
* (statements are separated by a semicolon).
*
* Result objects may contain the following members:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may contain is not very clear. We should have a clear specification for what the function returns.

Comment on lines +798 to +799
* - success: true/false (all queries)
* - error: error message if success is false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need two fields here. Let's just have an error field with type string|null

* (even if empty)
* - values: query results, if query returns a
* result (even if empty)
* - rowsModified: rows affected, if query is INSERT, UPDATE, or DELETE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simply always include it, and set it to 0 if there is 0 modified rows.

*
@param {string} sql a string containing some SQL text to execute
@param {boolean} exitOnError whether or not to continue after error
@return {Object[]} as described above
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need a better type definition here.

* - error: error message if success is false
* - columns: column headers, if query returns a result
* (even if empty)
* - values: query results, if query returns a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to specify in what form the query results come.

* Result objects may contain the following members:
* - success: true/false (all queries)
* - error: error message if success is false
* - columns: column headers, if query returns a result
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to specify the type. And can't we always return it ? Just set it to the empty array when a query doesn't return results.

Comment on lines +909 to +910
// eslint-disable-next-line no-constant-condition
while (true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They advise to use for (;;) for that purpose, in the documentation: https://eslint.org/docs/rules/no-constant-condition

But this is a code smell anyway. Isn't there a way to reorganise the code to make the stopping condition explicit ?

Comment on lines +883 to +898
var answer = [];
var result;
var data;
var columns;
var stack;
var lastSql;
var nextSql;
var thisSql;
var normalizedSql;
var sqlType;
var stmt;
var pStmt;
var pzTail;
var returnCode;
var errorMessage;
var errorAnswer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know a lot of the code had this style after the automatic coffee to js translation, but we are now trying to have the variables declared at their first use site.

Comment on lines +939 to +940
// eslint-disable-next-line no-continue
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we have a simple if-else instead of disabling the lint ?

Comment on lines +970 to +971
// eslint-disable-next-line no-continue
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can avoid this continue too

@lovasoa
Copy link
Member

lovasoa commented Oct 15, 2020

Closed in favor of #429

@lovasoa lovasoa closed this Oct 15, 2020
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

Successfully merging this pull request may close these issues.

3 participants