Skip to content

Commit

Permalink
Publish v3.13.0 with the ability to suppress warnings via Sql.skipAna…
Browse files Browse the repository at this point in the history
…lysis
  • Loading branch information
Zaid-Ajaj committed Sep 4, 2020
1 parent 8510b40 commit 0da6fb1
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 72 deletions.
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ Analyzer that provides embedded **SQL syntax analysis** when writing queries usi
- Detecting parameters with type-mismatch
- Verifying the columns being read from the result set and their types
- Detecting nullable columns
- Built-in code fixes for the above
- Built-in code fixes and nice error messages
- Ability to write multi-line queries in `[<Literal>]` text and referencing it
- Ability to suppress the warnings when you know better than the analyzer ;)
- Free (MIT licensed)
- Supports VS Code with [Ionide](https://github.com/ionide/ionide-vscode-fsharp) via F# Analyzers SDK
- Supports Visual Studio
Expand Down Expand Up @@ -107,23 +108,26 @@ let activeUsers (connectionString: string) =
```
Just remember that these `[<Literal>]` strings have to defined in the same module where the query is written.

### Suppressing the generated warning messages

---
Use the `Sql.skipAnalysis` function from main library to tell the analyzer to skip the analysis of a code block like this one:
```fs
open Npgsql.FSharp
let badQuery connection =
connection
|> Sql.query "SELECT * FROM non_existing_table"
|> Sql.skipAnalysis
|> Sql.execute (fun read -> read.int64 "user_id")
```

### Developing

Make sure the following **requirements** are installed on your system:

- [dotnet SDK](https://www.microsoft.com/net/download/core) 3.0 or higher
- [Mono](http://www.mono-project.com/) if you're on Linux or macOS.
- Postgres database server

or

- [VSCode Dev Container](https://code.visualstudio.com/docs/remote/containers)

---

### Building


Expand Down
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 3.13.0 - 2020-09-04
* The ability to suppress warning messages generated by the analyzer

### 3.12.1 - 2020-08-31
* Remove NpgsqlFSharpAnalyzer.Core nuget package reference from the analyzer

Expand Down
20 changes: 10 additions & 10 deletions src/FParsec/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ open System.Reflection

[<assembly: AssemblyTitleAttribute("FParsec")>]
[<assembly: AssemblyProductAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyVersionAttribute("3.12.1")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-08-31T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.12.1")>]
[<assembly: AssemblyInformationalVersionAttribute("3.12.1")>]
[<assembly: AssemblyVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-09-04T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.13.0")>]
[<assembly: AssemblyInformationalVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
[<assembly: AssemblyMetadataAttribute("GitHash","b1592a80c9432a89e1edf34d5e8dbcb1e1f84338")>]
[<assembly: AssemblyMetadataAttribute("GitHash","8510b403b2b0a20a3207cc5c7637d8406f2aaee5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "FParsec"
let [<Literal>] AssemblyProduct = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyVersion = "3.12.1"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-08-31T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.12.1"
let [<Literal>] AssemblyInformationalVersion = "3.12.1"
let [<Literal>] AssemblyVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-09-04T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.13.0"
let [<Literal>] AssemblyInformationalVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
let [<Literal>] AssemblyMetadata_GitHash = "b1592a80c9432a89e1edf34d5e8dbcb1e1f84338"
let [<Literal>] AssemblyMetadata_GitHash = "8510b403b2b0a20a3207cc5c7637d8406f2aaee5"
20 changes: 10 additions & 10 deletions src/NpgsqlFSharpAnalyzer.Core/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ open System.Reflection

[<assembly: AssemblyTitleAttribute("NpgsqlFSharpAnalyzer.Core")>]
[<assembly: AssemblyProductAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyVersionAttribute("3.12.1")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-08-31T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.12.1")>]
[<assembly: AssemblyInformationalVersionAttribute("3.12.1")>]
[<assembly: AssemblyVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-09-04T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.13.0")>]
[<assembly: AssemblyInformationalVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
[<assembly: AssemblyMetadataAttribute("GitHash","b1592a80c9432a89e1edf34d5e8dbcb1e1f84338")>]
[<assembly: AssemblyMetadataAttribute("GitHash","8510b403b2b0a20a3207cc5c7637d8406f2aaee5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "NpgsqlFSharpAnalyzer.Core"
let [<Literal>] AssemblyProduct = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyVersion = "3.12.1"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-08-31T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.12.1"
let [<Literal>] AssemblyInformationalVersion = "3.12.1"
let [<Literal>] AssemblyVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-09-04T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.13.0"
let [<Literal>] AssemblyInformationalVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
let [<Literal>] AssemblyMetadata_GitHash = "b1592a80c9432a89e1edf34d5e8dbcb1e1f84338"
let [<Literal>] AssemblyMetadata_GitHash = "8510b403b2b0a20a3207cc5c7637d8406f2aaee5"
7 changes: 6 additions & 1 deletion src/NpgsqlFSharpAnalyzer.Core/SqlAnalysis.fs
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,12 @@ module SqlAnalysis =
/// Uses database schema that is retrieved once during initialization
/// and re-used when analyzing the rest of the Sql operation blocks
let analyzeOperation (operation: SqlOperation) (connectionString: string) (schema: InformationSchema.DbSchemaLookups) =
match findQuery operation with
let skipAnalysis =
operation.blocks
|> List.exists (fun block -> block = SqlAnalyzerBlock.SkipAnalysis)

if skipAnalysis then [ ]
else match findQuery operation with
| None ->
[ ]
| Some (query, queryRange) ->
Expand Down
42 changes: 42 additions & 0 deletions src/NpgsqlFSharpAnalyzer.Core/SyntacticAnalysis.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ module SyntacticAnalysis =
| _ -> None
| _ -> None

let (|Applied|_|) = function
| SynExpr.App(atomicFlag, isInfix, funcExpr, argExpr, applicationRange) ->
match argExpr with
| SynExpr.Ident ident -> Some (ident.idText, funcExpr.Range, applicationRange)
| SynExpr.LongIdent(isOptional, longDotId, altName, identRange) ->
match longDotId with
| LongIdentWithDots(listOfIds, ranges) ->
let fullName =
listOfIds
|> List.map (fun id -> id.idText)
|> String.concat "."

Some (fullName, funcExpr.Range, applicationRange)
| _ -> None
| _ -> None

let (|ParameterTuple|_|) = function
| SynExpr.Tuple(isStruct, [ SynExpr.Const(SynConst.String(parameterName, paramRange), constRange); Apply(funcName, exprArgs, funcRange, appRange) ], commaRange, tupleRange) ->
Some (parameterName, paramRange, funcName, funcRange, Some appRange)
Expand Down Expand Up @@ -161,6 +177,15 @@ module SyntacticAnalysis =
| _ ->
[ ]

let rec findSkipAnalysis expr =
match expr with
| Applied("Sql.skipAnalysis", range, appRange) ->
[ SqlAnalyzerBlock.SkipAnalysis ]
| SynExpr.App(exprAtomic, isInfix, funcExpr, argExpr, range) ->
[ yield! findSkipAnalysis funcExpr; yield! findSkipAnalysis argExpr ]
| _ ->
[ ]

let rec findFunc = function
| SqlStoredProcedure (funcName, range) ->
[ SqlAnalyzerBlock.StoredProcedure(funcName, range) ]
Expand Down Expand Up @@ -310,17 +335,20 @@ module SyntacticAnalysis =
yield! findQuery funcExpr
yield! findParameters funcExpr
yield! findFunc funcExpr
yield! findSkipAnalysis funcExpr
yield SqlAnalyzerBlock.ReadingColumns columns
]

[ { blocks = blocks; range = range; } ]

| Apply(("Sql.execute"|"Sql.executeAsync"|"Sql.executeRow"|"Sql.executeRowAsync"|"Sql.iter"|"Sql.iterAsync"), lambdaExpr, funcRange, appRange) ->
let columns = findReadColumnAttempts lambdaExpr
let x = 1
let blocks = [
yield! findQuery funcExpr
yield! findParameters funcExpr
yield! findFunc funcExpr
yield! findSkipAnalysis funcExpr
yield SqlAnalyzerBlock.ReadingColumns columns
]

Expand Down Expand Up @@ -348,6 +376,7 @@ module SyntacticAnalysis =

let blocks = [
yield! findQuery funcExpr
yield! findSkipAnalysis funcExpr
yield SqlAnalyzerBlock.Parameters(sqlParameters, range)
]

Expand All @@ -358,6 +387,18 @@ module SyntacticAnalysis =
yield! findFunc funcExpr
yield! findQuery funcExpr
yield! findParameters funcExpr
yield! findSkipAnalysis funcExpr
]

[ { blocks = blocks; range = range; } ]

| Apply("Sql.skipAnalysis", functionArg, range, appRange) ->
let blocks = [
yield! findFunc funcExpr
yield! findQuery funcExpr
yield! findParameters funcExpr
yield SqlAnalyzerBlock.SkipAnalysis
yield SqlAnalyzerBlock.ReadingColumns (findReadColumnAttempts funcExpr)
]

[ { blocks = blocks; range = range; } ]
Expand All @@ -367,6 +408,7 @@ module SyntacticAnalysis =
yield! findFunc funcExpr
yield! findQuery funcExpr
yield! findParameters funcExpr
yield! findSkipAnalysis funcExpr
yield SqlAnalyzerBlock.ReadingColumns (findReadColumnAttempts funcExpr)
]

Expand Down
1 change: 1 addition & 0 deletions src/NpgsqlFSharpAnalyzer.Core/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type SqlAnalyzerBlock =
| StoredProcedure of string * range
| Parameters of UsedParameter list * range
| ReadingColumns of ColumnReadAttempt list
| SkipAnalysis

type SqlOperation = {
blocks : SqlAnalyzerBlock list
Expand Down
20 changes: 10 additions & 10 deletions src/NpgsqlFSharpAnalyzer/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ open System.Reflection

[<assembly: AssemblyTitleAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyProductAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyVersionAttribute("3.12.1")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-08-31T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.12.1")>]
[<assembly: AssemblyInformationalVersionAttribute("3.12.1")>]
[<assembly: AssemblyVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-09-04T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.13.0")>]
[<assembly: AssemblyInformationalVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
[<assembly: AssemblyMetadataAttribute("GitHash","b1592a80c9432a89e1edf34d5e8dbcb1e1f84338")>]
[<assembly: AssemblyMetadataAttribute("GitHash","8510b403b2b0a20a3207cc5c7637d8406f2aaee5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyProduct = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyVersion = "3.12.1"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-08-31T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.12.1"
let [<Literal>] AssemblyInformationalVersion = "3.12.1"
let [<Literal>] AssemblyVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-09-04T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.13.0"
let [<Literal>] AssemblyInformationalVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
let [<Literal>] AssemblyMetadata_GitHash = "b1592a80c9432a89e1edf34d5e8dbcb1e1f84338"
let [<Literal>] AssemblyMetadata_GitHash = "8510b403b2b0a20a3207cc5c7637d8406f2aaee5"
20 changes: 10 additions & 10 deletions src/NpgsqlFSharpParser/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ open System.Reflection

[<assembly: AssemblyTitleAttribute("NpgsqlFSharpParser")>]
[<assembly: AssemblyProductAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyVersionAttribute("3.12.1")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-08-31T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.12.1")>]
[<assembly: AssemblyInformationalVersionAttribute("3.12.1")>]
[<assembly: AssemblyVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-09-04T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.13.0")>]
[<assembly: AssemblyInformationalVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
[<assembly: AssemblyMetadataAttribute("GitHash","b1592a80c9432a89e1edf34d5e8dbcb1e1f84338")>]
[<assembly: AssemblyMetadataAttribute("GitHash","8510b403b2b0a20a3207cc5c7637d8406f2aaee5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "NpgsqlFSharpParser"
let [<Literal>] AssemblyProduct = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyVersion = "3.12.1"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-08-31T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.12.1"
let [<Literal>] AssemblyInformationalVersion = "3.12.1"
let [<Literal>] AssemblyVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-09-04T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.13.0"
let [<Literal>] AssemblyInformationalVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
let [<Literal>] AssemblyMetadata_GitHash = "b1592a80c9432a89e1edf34d5e8dbcb1e1f84338"
let [<Literal>] AssemblyMetadata_GitHash = "8510b403b2b0a20a3207cc5c7637d8406f2aaee5"
2 changes: 2 additions & 0 deletions src/NpgsqlFSharpParser/Parser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ opp.AddOperator(InfixOperator("=", spaces, 9, Associativity.Left, fun left right
opp.AddOperator(InfixOperator("<>", spaces, 9, Associativity.Left, fun left right -> Expr.Not(Expr.Equals(left, right))))
opp.AddOperator(InfixOperator("||", spaces, 9, Associativity.Left, fun left right -> Expr.StringConcat(left, right)))
opp.AddOperator(InfixOperator("::", spaces, 9, Associativity.Left, fun left right -> Expr.TypeCast(left, right)))
opp.AddOperator(InfixOperator("->>", spaces, 9, Associativity.Left, fun left right -> Expr.JsonIndex(left, right)))

opp.AddOperator(PostfixOperator("IS NULL", spaces, 8, false, fun value -> Expr.Equals(Expr.Null, value)))
opp.AddOperator(PostfixOperator("IS NOT NULL", spaces, 8, false, fun value -> Expr.Not(Expr.Equals(Expr.Null, value))))

Expand Down
1 change: 1 addition & 0 deletions src/NpgsqlFSharpParser/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Expr =
| In of left:Expr * right:Expr
| As of left:Expr * right:Expr
| StringConcat of left:Expr * right:Expr
| JsonIndex of left:Expr * right:Expr
| TypeCast of left:Expr * right:Expr
| Not of expr:Expr
| Equals of left:Expr * right:Expr
Expand Down
2 changes: 1 addition & 1 deletion src/NpgsqlFSharpVs/source.extension.vsixmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011"
xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="FSharpLintVs.ef00bfc3-a899-45fc-aae8-afecf8673aaf" Version="3.12.1" Language="en-US" Publisher="Zaid Ajaj" />
<Identity Id="FSharpLintVs.ef00bfc3-a899-45fc-aae8-afecf8673aaf" Version="3.13.0" Language="en-US" Publisher="Zaid Ajaj" />
<DisplayName>NpgsqlFSharpVs</DisplayName>
<Description xml:space="preserve">F# Analyzer for embedded SQL syntax analysis, type-checking for parameters and result sets and nullable column detection when writing queries using Npgsql.FSharp.</Description>
<MoreInfo>https://github.com/Zaid-Ajaj/Npgsql.FSharp.Analyzer</MoreInfo>
Expand Down
20 changes: 10 additions & 10 deletions tests/NpgsqlFSharpAnalyzer.Tests/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ open System.Reflection

[<assembly: AssemblyTitleAttribute("NpgsqlFSharpAnalyzer.Tests")>]
[<assembly: AssemblyProductAttribute("NpgsqlFSharpAnalyzer")>]
[<assembly: AssemblyVersionAttribute("3.12.1")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-08-31T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.12.1")>]
[<assembly: AssemblyInformationalVersionAttribute("3.12.1")>]
[<assembly: AssemblyVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2020-09-04T00:00:00.0000000")>]
[<assembly: AssemblyFileVersionAttribute("3.13.0")>]
[<assembly: AssemblyInformationalVersionAttribute("3.13.0")>]
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
[<assembly: AssemblyMetadataAttribute("GitHash","b1592a80c9432a89e1edf34d5e8dbcb1e1f84338")>]
[<assembly: AssemblyMetadataAttribute("GitHash","8510b403b2b0a20a3207cc5c7637d8406f2aaee5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "NpgsqlFSharpAnalyzer.Tests"
let [<Literal>] AssemblyProduct = "NpgsqlFSharpAnalyzer"
let [<Literal>] AssemblyVersion = "3.12.1"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-08-31T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.12.1"
let [<Literal>] AssemblyInformationalVersion = "3.12.1"
let [<Literal>] AssemblyVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseDate = "2020-09-04T00:00:00.0000000"
let [<Literal>] AssemblyFileVersion = "3.13.0"
let [<Literal>] AssemblyInformationalVersion = "3.13.0"
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
let [<Literal>] AssemblyMetadata_GitHash = "b1592a80c9432a89e1edf34d5e8dbcb1e1f84338"
let [<Literal>] AssemblyMetadata_GitHash = "8510b403b2b0a20a3207cc5c7637d8406f2aaee5"
Loading

0 comments on commit 0da6fb1

Please sign in to comment.