fsprojects / SQLProvider

A general F# SQL database erasing type provider, supporting LINQ queries, schema exploration, individuals, CRUD operations and much more besides.
https://fsprojects.github.io/SQLProvider
Other
570 stars 144 forks source link

SaveContextSchema not generating schema file. #639

Closed mcspud closed 4 years ago

mcspud commented 4 years ago

Description

Hi all,

I have just done an F# POC in my company over the last 3 days. Honestly, Type Providers are perhaps the single best programming thing I've ever encountered, hence this POC.

None of us are .NET programmers and never have been, so its likely I am doing something stupid here as we are totally ignorant to this ecosystem.

Problem: We need to have an SQL postgres schema file referenced for our docker builds.
We want to generate a schema file so we can pin an offline version to the SqlDataProvider so we have repeatable builds and we can stop docker whinging. I am currently doing the equivalent versions of this with both the JsonProvider and XmlProviders. I went through this thread and can see that this feature has been implemented.

I can't get the .schema file to generate.

[<Literal>]
let ConnectionString =
    "Server=localhost;"    +
    "Database=betting_aggregator;" +
    "User Id=postgres;"            +
    "Password=password;"

type Sql =
    SqlDataProvider<
        ContextSchemaPath     = "./postgres.schema",
        ConnectionString      = ConnectionString,
        DatabaseVendor        = Common.DatabaseProviderTypes.POSTGRESQL,
        CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL>

At the very bottom of my "Database.fs" file I have the following:

let saveContext() =
    Sql.GetDataContext().SaveContextSchema()

saveContext() |> fun _ -> printf("db stuff ran")

Note that the Provider successfully connects to the database and gives me the exact behaviour I want (its really quite magical).

When I do dotnet run from the terminal, it prints out my little success message so I know saveContext has been run and boots up the Suave app. I would expect that this would build the .schema file as an artefact of the run.

I've set the ContextSchemaPath value based on what VSCode is telling me what to do if I don't include it in the Provider.

image

If I do include it, it updates the Infopanel but unfortunately I'm still not getting the result I'm expecting. I also don't understand what the "Write dot after SaveContextSchema() to save the schema at design time." means.

Screen Shot 2019-09-16 at 12 10 50 am

Expected behavior

I'm expecting a postgres.schema file to be generated the ~/<Project Dir>/postgres.schema folder, or whatever value is specified in the ContextSchemaPath value.

I've tried setting the path to many different directories, including doing full file system greps to see if it exists.

Actual behavior

No schema file being generated, either at the path specified in the ContextSchemaPath value, nor anywhere that I can find.

Known workarounds

None currently

Related information

Thanks for the work with this great package!

Thorium commented 4 years ago

http://fsprojects.github.io/SQLProvider/core/parameters.html#ContextSchemaPath might help? If not, we need to improve the docs. :-)

Thorium commented 4 years ago

Basically SaveContextSchema() is called from your code editor and it acts like a design-time save-button. Because there is no way to have a save-button in IDE (Visual Studio or whatever else) that could be presented from the typeprovider.

mcspud commented 4 years ago

Hi there, thanks for the quick response!

I have tried to adapt what I saw at your [documentation link] (http://fsprojects.github.io/SQLProvider/core/parameters.html#ContextSchemaPath ) and have had no success - specifically using the __SOURCE_DIRECTORY__ value and changing directory separators (I'm not sure how .netcore handles the difference between windows / and *nix \ directory tokens).

You say

Basically SaveContextSchema() is called from your code editor and it acts like a design-time save-button.

I am not entirely sure of the meaning of design-time, but I assume it analogous to compile-time and run-time. I assume that is how the Provider works, giving you access to your database types literally as your design your program (again, very magical and very cool!). If that is correct, then at very the bottom of my Database.fs file I have the following line:

Sql.GetDataContext().SaveContextSchema() |> fun _ -> printf "SaveContextSchema" |> ignore It is a stand alone expression and has no let bindings etc.

I assume that VSCode would be calling this at some point (it definitely does when I do dotnet run, I can see the SaveContextSchema in the terminal)

Using the slightly modified version from the link you provided, my provider looks like this:

let ContextSchemaPath =
    __SOURCE_DIRECTORY__ + @"/postgres.schema"

type Sql =
    SqlDataProvider<
        ContextSchemaPath     = ContextSchemaPath,
        ConnectionString      = ConnectionString,
        DatabaseVendor        = Common.DatabaseProviderTypes.POSTGRESQL,
        CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL>

Still no file being generated, but I'm probably doing something really dumb/obvious. :)

If you can point me in the right direction I'll happily update the documentation with a worked example as a PR.

Thanks again!

Thorium commented 4 years ago

As far as I remember it should work like this: If the file is there, it's used offline. If the file is not there, it will write it on-the-fly at the moment you type "SaveContextSchema()" to your editor. Maybe there is even a tooltip that could help?

Ping @tforkmann and @object, if I remember correctly you do use this feature, right? (I don't use it.)

mcspud commented 4 years ago

As far as I remember it should work like this: If the file is there, it's used offline. If the file is not there, it will write it on-the-fly at the moment you type "SaveContextSchema()" to your editor.

Yes, reading the thread about the initial work above it looks like that is how it should behave, with the idea that you "comment out" SaveContextSchema() when you do build the project (or do it via some CICD process).

I've tried that and unfortunately have had no luck.

mcspud commented 4 years ago

I have just upgraded to .netcore 3.0 (SDK 3.0.100) and this works perfectly now. Thanks again for the great package.