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

Add Filtering with QueryParameters #26

Merged
merged 6 commits into from
Apr 11, 2018
Merged

Add Filtering with QueryParameters #26

merged 6 commits into from
Apr 11, 2018

Conversation

EnriqueL8
Copy link
Contributor

@EnriqueL8 EnriqueL8 commented Apr 10, 2018

This PR enables filtering in the ORM. It uses the Query Parameters from Kitura.
By creating a struct as such:

struct MyQuery: QueryParams {
  let name: String
}

And calling the api as such:

Model.findAll(matching: MyQuery) { result, error in 
  ...
}

@EnriqueL8 EnriqueL8 changed the title Add Filtering to findAll Add Filtering to findAll Apr 10, 2018
@EnriqueL8 EnriqueL8 changed the title Add Filtering to findAll Add Filtering with QueryParameters Apr 10, 2018
@codecov-io
Copy link

codecov-io commented Apr 10, 2018

Codecov Report

Merging #26 into master will increase coverage by 0.31%.
The diff coverage is 22.83%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #26      +/-   ##
==========================================
+ Coverage   21.04%   21.36%   +0.31%     
==========================================
  Files           6        6              
  Lines        1259     1512     +253     
==========================================
+ Hits          265      323      +58     
- Misses        994     1189     +195
Flag Coverage Δ
#SwiftKueryORM 21.36% <22.83%> (+0.31%) ⬆️
Impacted Files Coverage Δ
Sources/SwiftKueryORM/Model.swift 22.64% <22.83%> (+0.1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cd8bd17...31e875a. Read the comment docs.

@ianpartridge
Copy link

Instead of filterOn: how about matching:?

@seabaylea
Copy link
Contributor

seabaylea commented Apr 11, 2018

Do we have an equivalent for delete, e.g.:

Model.deleteAll(matching: MyQuery) { error in 
  ...
}

do {
queryDictionary = try QueryEncoder().encode(queryParams)
} catch {
throw error

Choose a reason for hiding this comment

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

If you're just going to rethrow the error you don't need the do{} at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, will fix

throw RequestError(.ormQueryError, reason: "Could not extract values for Query Parameters")
}

var filter: Filter! = nil

Choose a reason for hiding this comment

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

This section is deeply mysterious...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll add a comment to explain

var dictionariesTitleToValue = [[String: Any?]]()

connection.connect { error in
if let error = error {

Choose a reason for hiding this comment

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

Could this be a guard to reduce the indentation level below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could be done, also in another refactoring PR?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure about the guard (sadly, I don't think you can guard and bind variable inside the block, only outside?) But the else looks redundant given the block returns

/// - Parameter matching: Optional QueryParams to use
/// - Returns: An array of model
static func findAll<Q: QueryParams>(using db: Database? = nil, matching queryParams: Q, _ onCompletion: @escaping ([Self]?, RequestError?) -> Void) {
guard let database = db ?? Database.default else {

Choose a reason for hiding this comment

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

"Getting a connection" is so common that maybe it should be factored out into a common function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can be done in another refactoring PR?

@EnriqueL8
Copy link
Contributor Author

This should be good to go? @ianpartridge @seabaylea

@EnriqueL8 EnriqueL8 merged commit 197684c into master Apr 11, 2018
@EnriqueL8 EnriqueL8 deleted the query_parameters branch April 11, 2018 15:50
var queryDictionary: [String: String] = try QueryEncoder().encode(queryParams)

var columns = table.columns.filter { queryDictionary[$0.name] != nil }
var values = Array(queryDictionary.values)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might want to check that columns and values line up if a user can specify an incorrect column name (one that is not in the table.columns) since the filter would drop that column but the corresponding value would not be dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very true, will make that check

var filter: Filter = (columns.removeFirst() == values.removeFirst())
for (column, value) in zip(columns, values) {
filter = filter && (column == value)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this way of constructing the filter vulnerable to SQL injection (cf https://github.com/IBM-Swift/Swift-Kuery#sql-injection-prevention-using-parameterization)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This issue is pending... #19 but yes that should have been looked at in this PR

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.

5 participants