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

Placeholder replacement #14

Merged
merged 17 commits into from
Nov 14, 2016
Merged

Placeholder replacement #14

merged 17 commits into from
Nov 14, 2016

Conversation

ukupat
Copy link
Contributor

@ukupat ukupat commented Nov 2, 2016

I created two different placeholder token regexes (based on if placeholder has a name or not), but there is only one token type: PLACEHOLDER.

I haven't updated README.md yet, lets see what is your opinion on current solution.

Info about N1QL parameterized queries http://developer.couchbase.com/documentation/server/current/sdk/n1ql-query.html

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 861c22a on placeholder-replacement into acd77b6 on master.

this.QUOTED_VARIABLE_REGEX = this.createVariableRegex(cfg.variableTypes, this.createStringPattern(cfg.stringTypes));
this.INDEXED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(cfg.indexedPlaceholderTypes);
this.PLAIN_NAMED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(cfg.namedPlaceholderTypes, "[a-zA-Z0-9._$]+");
this.STRING_NAMED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't really like the name PLAIN_NAMED. Perhaps better IDENT_NAMED to emphasize that the name is an identifier.

Speaking of identifiers though, the regex [a-zA-Z0-9._$]+ isn't fully covered by tests - we don't test for the special characters ., _ and $. I wonder, do we even really need to support . and $.

type: sqlTokenTypes.VARIABLE,
regex: this.QUOTED_VARIABLE_REGEX
type: sqlTokenTypes.PLACEHOLDER,
regex: this.INDEXED_PLACEHOLDER_REGEX
});
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

We could generalize these three methods - the only difference between them is the regex.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if we want to do it now when we have two different placeholder types. WDYT @nene ?

Copy link
Collaborator

@nene nene Nov 10, 2016

Choose a reason for hiding this comment

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

Added a different suggestion which might need a different generalization of the same thing.

" third,\n" +
" first;\n"
);
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should order other tests also similarly, so that all tests for @variables are grouped together like the above tests for $variables.

0: "first",
1: "second",
2: "third"
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should also have a test that uses plain array instead of object with numeric keys.

if (!this.params) {
return placeholder;
}
const matches = placeholder.match(/\w+(\s+\w+)*/);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't really understand why this regex is the way it is.

I understand that the goal is to detect whether it's a named placeholder. However it doesn't quite work - for example when I have a placeholder that does not consist of just spaces and word characters:

SELECT @'$^&*'

It might be simpler to differentiate between named and indexed placeholders inside tokenizer.

Another thing to consider is escape sequences inside strings:

SELECT @"hello \" world"

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b1992a0 on placeholder-replacement into acd77b6 on master.

@ukupat
Copy link
Contributor Author

ukupat commented Nov 8, 2016

@nene covered your requested changes.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling e606409 on placeholder-replacement into d60431f on master.

if (matches) {
return this.params[matches[0]];
if (key) {
return this.params[key];
Copy link
Collaborator

Choose a reason for hiding this comment

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

We really have three placeholder token types: STRING, INDENT, INDEXED. Currently the INDEXED and INDENT are thrown together (although they're really quite different). By having three distinct types, we could express the three different choices in much clearer way:

switch(type) {
    case INDEXED:
    case STRING:
    case IDENT:
}

Also, I think parsing the contents of the string and indent placeholders should really belong to Tokenizer. The Formatter should not care about the specific syntax that placeholders have. It's also common practice for Lexer to provide both a raw value and some computed value of a token like string. In that scenario we actually won't need 3 token types as STRING and INDENT can be represented with one.

Finally I still think that we should take at least some minimal care about escaping. As the Lexer allows escape sequences like \" in strings, the parameter replacement should also support them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, we should add some additional tests for the quoted placeholders, something like testing:

SELECT :"^*& weird \" var   "

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added one test @nene

type: sqlTokenTypes.VARIABLE,
regex: this.QUOTED_VARIABLE_REGEX
type: sqlTokenTypes.PLACEHOLDER,
regex: this.INDEXED_PLACEHOLDER_REGEX
});
}
Copy link
Collaborator

@nene nene Nov 10, 2016

Choose a reason for hiding this comment

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

Added a different suggestion which might need a different generalization of the same thing.

@ukupat
Copy link
Contributor Author

ukupat commented Nov 11, 2016

I did my best to resolve @nene requested changes.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 2d5c48f on placeholder-replacement into d60431f on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 9ac4d75 on placeholder-replacement into d60431f on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 2f76764 on placeholder-replacement into d60431f on master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 7b5f380 on placeholder-replacement into d60431f on master.

@@ -208,6 +208,10 @@ export default class Tokenizer {
return token;
}

getEscapedPlaceholderKey({key, stringChar}) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think a better name would be: quoteChar

sqlFormatter.format("SELECT ? FROM table1", {
params: ["bar"]
}));
```
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should use a more real-life example. One normally uses placeholders in conditions of WHERE clause like:

SELECT * FROM tbl WHERE foo = ?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 96b92af on placeholder-replacement into d60431f on master.

@ukupat ukupat added the feature label Nov 14, 2016
@nene nene merged commit b4b16e7 into master Nov 14, 2016
@ukupat ukupat deleted the placeholder-replacement branch November 14, 2016 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants