-
-
Notifications
You must be signed in to change notification settings - Fork 41
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
Added support for array parameters #12
Conversation
Your fix breaks the default behavior. The test you wrote is incorrect: var query = SQL
.SELECT("*")
.WHERE("VALUE IN ({0})", new object[] { "a", "b", "c" }); The above code should NOT transform var query = SQL
.SELECT("*")
.WHERE("VALUE IN ({0})", "a", "b", "c"); So, you are really not using an array parameter here. You'd have to do this: var query = SQL
.SELECT("*")
.WHERE("VALUE IN ({0})", new object[] { new object[] { "a", "b", "c" } }); The wiki article can be a bit confusing because it uses an array of a value type: int[] ids = { 1, 2, 3 };
var query = SQL
.SELECT("*")
.FROM("Products")
.WHERE("CategoryID IN ({0})", ids); On this case, the C# compiler does not cast int[] ids = { 1, 2, 3 };
var query = SQL
.SELECT("*")
.FROM("Products")
.WHERE("CategoryID IN ({0})", new object[] { ids }); Hope all of this makes sense. I haven't worked on this issue because I don't think it can be easily fixed in a backwards-compatible way. I've thought about something like |
Verify single parameter case, added test for string arrays. Changed arrays to match sample from wiki.
Do you have a test for the default behavior? I'm afraid I don't understand what it is meant to be based on your comments. I've updated my tests to cover the single value case, and using arrays, both int as in the wiki example and strings (2d28107).
|
Those 2 tests should fail. You either don't understand how |
Clearly we do not understand what your original intent for this feature is. Can you provide a test or sample usage that our
In all working cases presented above, the SQL that is generated is exactly what we expect to see. |
I've added a couple of tests to the master branch. This one fails with your changes: [TestMethod]
public void Multiple_Parameters() {
var query = SQL
.SELECT("{0}, {1}", 1, 2);
Assert.AreEqual("SELECT {0}, {1}", query.ToString());
Assert.AreEqual(2, query.ParameterValues.Count);
} |
That makes more sense now and seems like another obvious use pattern that we hadn't considered (yet). Let me see what we can do with that. |
Includes a test to verify that the implementation is broken for a specific implementation.
The last check in gets your test working again, but adds a new test to verify that another scenario is (still) broken. IMHO, it's better than it was since it now handles most of the usual cases. I started to explore how various combinations show up in the method to see if I could see any solutions.
I'm thinking right now that it might be able to be solved something like:
I'm sure there are a whole bunch of things I'm not considering there. When I get time I'll see how far I can get with it (since the original fix solves our problem for the way we are using the library I really need to get back to my day job). |
This is just all around a bad idea. |
That last case should not work, because the number of placeholders is greater than the number of parameters. As I already mentioned, you cannot fix this without breaking array-to-list placeholder substitution. Perhaps if you explain your particular use case I can give better advice. |
Our use cases are simply 1 placeholder and one array or value, or maybe n placeholders and n values. On further reflection, #12 (comment) is not valid (it isn't supported for string.Format, so I don't think SqlBuilder should either). For #12 (comment) however, I can see that being desirable:
Where we'd like the 'ids' to expand the {1} automatically and adjust {2} appropriately (to in this case {1}, {2}, {3} and {4} respectively). I'd call that a "nice to have" since it can be worked around by chaining calls. The current fix, supporting either explicitly listed values ( |
That case is already supported, I wasn't sure so I added a test: [TestMethod]
public void Adjust_Other_Placeholders_When_Using_Array_Parameter() {
var query = SQL
.SELECT("*")
.WHERE("c IN ({0}) AND c <> {1}", new object[] { new int[] { 1, 2, 3 }, 4 });
Assert.IsTrue(query.ToString().Contains("{3}"));
Assert.AreEqual(4, query.ParameterValues.Count);
} |
I see that test passes with both the original code and the update here. To summarize, this update additionally supports:
My opinion is that the changes now add an additional desirable feature and do not break any of the existing behavior. |
The first case is, as you say, a deviation from The second case is exactly the same as the first case, since |
You should write it like this: |
I think for now we are going to use the code as-is in my forked version here. It adds the desired behavior we need, doesn't break anything and just adds some weird capabilities that you shouldn't use (and hopefully if anyone tries testing will pick up on it). |
#10