-
Notifications
You must be signed in to change notification settings - Fork 2
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
Array parameters and extending the library #12
Comments
Hello James Do you mean Arrays type? Wdyt @natalie-perret-1986? |
@absolutejam @akhansari Hi there 🙋♀️,
You're absolutely right, it's not supported atm, I'm kinda busy right now, and in all honesty I can't remember exactly why, but I gave it some thought last year, and from what I can recollect, there is bit of work involved for supporting arrays. One way to put it is that it's fairly easy to add the support, BUT, it's hard to get it right from an API standpoint (in terms of consistency), I need to re-think about it cause it's a wee fuzzy as I'm in the middle of a lot of things at work.
Yea, there is something somewhere like that in my tiny brain, but again the so-called "right design" is hard to nail.
This is also something I thought about and yea in theory, this is the way I envisioned adding support for not-yet-supported types but again there was something that didn't really click at the time. Is that okay if I'm getting back to you two this coming Sat. (probably night / evening)? |
Thanks for the feedback 😄 I totally understand - As soon as you implement it, it gets relied upon and becomes a lot harder to change! There's no rush, I can totally understand being swamped 😓 I have forked it locally for now and I've added the following temporary workarounds for my usage... Extended | IntegerArray of int32 array
| UuidArray of Guid array
| NpgsqlOther of NpgsqlParameter Extended | IntegerArray value ->
parameter.Value <- value
parameter.NpgsqlDbType <- NpgsqlDbType.Array ||| NpgsqlDbType.Integer
| UuidArray value ->
parameter.Value <- value
parameter.NpgsqlDbType <- NpgsqlDbType.Array ||| NpgsqlDbType.Uuid
| NpgsqlOther p ->
parameter <- p Obviously I've only tackled a couple of array types that I needed as well as adding a back-door. I'm not sure what greater ramifications this could have, but this seems to be working just fine for me at the moment. Happy to chat about this here or on Slack, and I'm happy to contribute changes & tests where required. |
WIP - sticky notes Passively tinkering: https://www.npgsql.org/efcore/mapping/array.html
@absolutejam It would be a great addition in terms of extensibility for the library, when it comes to using parameters that aren't yet fully baked-in. This also could be done for other I like I'm still giving it a few more days to see if there is any sort of caveats that we may have missed out. Thanks again for opening this issue, really appreciated! |
and there she is, back 👩🚀 It's nice to take some time to think about a design, and I might have found something that in terms of consistency isn't all grand-like. Assuming new DU cases like below, in the case of a broad generic system to support whatever | IntegerArray of int32 array
| UuidArray of Guid array
| NpgsqlOther of NpgsqlParameter My issue is that if you pass a Vp.FSharp.Sql.PostgreSql/Vp.FSharp.Sql.PostgreSql/Types.fs Lines 104 to 109 in e6f7957
Which makes things not only inconsistent but also counter-intuitive and to some extent might even mislead the developers using the library. So in order to make things slightly more consistent, I'd suggest , instead, to have the DU case as follows: //... whatever goes here
| NpgsqlOther of (NpgsqlDbType * obj)
//... some other things go here
| NpgsqlOther (dbType, value) ->
// plain and simple
parameter.Value <- value
parameter.NpgsqlDbType <- dbType @absolutejam @akhansari wdyt? Btw, I'm still not too convinced about the name, i.e. Note: |
Makes sense to me! I left it fully open initially in case there was some super-advanced stuff needed to be done with the raw And from my super in-depth testing, I think the boxing is automatic in this case: type Foo =
| CaseA of string
| CaseB of string * obj
> let x [| CaseB ("x", 10); CaseB ("y", "apple") |];;
val x : Foo [] = [|B ("x", 10); B ("y", "apple")|]
> match x.[0] with
- | CaseB (_, second) -> second
- | _ -> failwith "lol";;
val it : obj = 10 I'll leave the naming to you... that's the hardest part 😈 Did you want to bother with explicit array parameters, or just leave these to the open-ended case? |
I just wanted something consistent with the rest of the pre-existing design, if I were to pass
I think I'm gonna start with that raw / open / whatever ( In all seriousness, these below are what I'm struggling with:
Pseudo-rationale
😕
Note: don't edit GitHub comments using a browser on a smartphone |
What a terrible dilemma 😐 |
Why not CustomType |
For the same reasons |
And so I hereby decide, Pseudo-rationale, part 2: for the grand sake of the mighty consistency and argumentum ad verecundiam. It is usually expected in F# libraries that when you have a bunch of DU cases already defined for fixed types but eventually boiling down to the same type bts in your implementation, that Yes, this is pretty much an empirical slash appeal from authority thingy, but at least the case is now closed. Note 1: 3-4am edits are bad. |
Should anyone present know of any reason that this design decision should not be joined in holy matrimony, speak now or forever hold your peace. |
Keep this issue open because we can add array support but a more generic approach is preferred so that users aren't forced to fork the repo to do so. |
In retrospect, again, some more food for thought: |
@absolutejam 🙋♀️ long time no see, you might be interested in https://github.com/veepee-oss/Vp.FSharp.Sql.PostgreSql/pull/16/files With the impl available in the PR, this is what it would look like: // Valid stuff in regard to PG / .NET type consistency, but no safeguard when it comes to the initial intent
PostgreSqlDbValue.Array (NpgsqlDbType.Integer, [| 123; 456 |]) |> ignore // Valid
PostgreSqlDbValue.Array (NpgsqlDbType.Text, [| "abc"; "def" |]) |> ignore // Valid
// Valid stuff in regard to PG / .NET type consistency, safeguard when it comes to the initial intent via generics
PostgreSqlDbValue.Array<int32> (NpgsqlDbType.Integer, [| 123; 456 |]) |> ignore // Valid
PostgreSqlDbValue.Array<string> (NpgsqlDbType.Text, [| "abc"; "def" |]) |> ignore // Valid
// Invalid stuff in regard to PG / .NET type consistency
PostgreSqlDbValue.Array (NpgsqlDbType.Text, [| 123; 456 |]) |> ignore // Invalid (runtime)
PostgreSqlDbValue.Array (NpgsqlDbType.Integer, [| "abc"; "def" |]) |> ignore // Invalid (runtime)
PostgreSqlDbValue.Array<int32> (NpgsqlDbType.Text, [| 123; 456 |]) |> ignore // Invalid (runtime)
PostgreSqlDbValue.Array<string> (NpgsqlDbType.Integer, [| "abc"; "def" |]) |> ignore // Invalid (runtime)
// Invalid stuff in regard to PG / .NET type consistency, safeguard when it comes to the initial intent via generics
PostgreSqlDbValue.Array<string> (NpgsqlDbType.Text, [| 123; 456 |]) |> ignore // Invalid (compilation)
PostgreSqlDbValue.Array<int32> (NpgsqlDbType.Integer, [| "abc"; "def" |]) |> ignore // Invalid (compilation) |
Morning!
I've been working towards moving all of my DB access in F# to using your libraries, especially in the case of replacing EF Core. Kudos on the great work; the API is really clean and the docs are great!
I don't know if I'm looking in the wrong place or if it's not available, but I'm trying to add a string array parameter which seems to be supported by the underlying Npgsql library, but I can't seem to find the DU representation in the docs or source.
First of all, If I've totally overlooked something, please let me know and I'll be happy to contribute docs or whatever is needed. But if this isn't available, is it worth extending the DU to allow this scenario, but also consider a way for extensibility outside of source changes?
For example, a DU case that is simply
NpgsqlOther of NpgsqlParameter
(orunit -> NpgsqlParameter
) , or possibly a function that is called with the overall Npgsql connection (Or whatever other mutable object it uses for state tracking) prior to execution, to perform any additional transformations outside of the scope of the API?The text was updated successfully, but these errors were encountered: