Skip to content

Commit

Permalink
fix docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-a-morozov committed May 16, 2016
1 parent 5773dd0 commit 9f98846
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 88 deletions.
10 changes: 10 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
#### 1.8.2 - May 16, 2016
* Issue #192 - Invert order of release notes so most recent is on top
* Issue #195 - BREAKING CHANGE! Make connection parameter mandatory when literal connection string used at design time
* Issue #196 - BREAKING CHANGE! API based run-time configuration
* Issue #197
* Issue #199 - Support for Stored procedure and Functions Synonyms
* Issue #200 - Support for Table Synonyms
* Issue #201 - Units of measure kind support in SqlEnumProvider
* Issue #214 - BREAKING CHANGE! Add SqlCommand.Table type for ResultType.DataTable

#### 1.8.1 - March 3, 2016
* Issue #185

Expand Down
2 changes: 1 addition & 1 deletion docs/content/app.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="AdventureWorks2014" connectionString="Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True" />
<add name="AdventureWorks" connectionString="Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True" />
</connectionStrings>
</configuration>
77 changes: 41 additions & 36 deletions docs/content/configuration and Input.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ CommandText
open FSharp.Data

[<Literal>]
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let connStr = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"

//Inline T-SQL text convinient for short queries
type GetDate = SqlCommandProvider<"SELECT GETDATE() AS Now", connectionString>
type GetDate = SqlCommandProvider<"SELECT GETDATE() AS Now", connStr>

//More complex queries are better off extracted to stand-alone literals

Expand All @@ -71,10 +71,12 @@ let fibonacci = "
FROM Fibonacci
"

type FibonacciQuery = SqlCommandProvider<fibonacci, connectionString>
type FibonacciQuery = SqlCommandProvider<fibonacci, connStr>

(new FibonacciQuery())
.Execute(10L)
do
let cmd = new FibonacciQuery(connStr)

cmd.Execute(10L)
|> Seq.map Option.get
|> Seq.toArray
|> printfn "First 10 fibonacci numbers: %A"
Expand Down Expand Up @@ -103,7 +105,7 @@ For example, it can be handed over to DBA team for optimization. It's harder to
are mixed together (LINQ).
*)

let cmd = new SqlCommandProvider<"GetDate.sql", connectionString>()
let cmd = new SqlCommandProvider<"GetDate.sql", connStr>(connStr)
cmd.Execute() |> ignore

(**
Expand All @@ -118,7 +120,7 @@ Below is an example of SQL Table-Valued Function usage.
*)

type GetContactInformation =
SqlCommandProvider<"SELECT * FROM dbo.ufnGetContactInformation(@PersonId)", connectionString>
SqlCommandProvider<"SELECT * FROM dbo.ufnGetContactInformation(@PersonId)", connStr>

(**
### Syntax errors
Expand Down Expand Up @@ -147,9 +149,9 @@ type FizzOrBuzz = SqlCommandProvider<"
WHEN @x % 3 = 0 THEN 'Fizz'
WHEN @x % 5 = 0 THEN 'Buzz'
ELSE CONCAT(@x, '') --use concat to avoid nullable column
END", connectionString>
END", connStr>

let fizzOrBuzz = new FizzOrBuzz()
let fizzOrBuzz = new FizzOrBuzz(connStr)
printfn "Answer on interview:\n%A" [ for i = 1 to 100 do yield! fizzOrBuzz.Execute(i) ]

(**
Expand All @@ -164,7 +166,7 @@ Connection string can be provided either via literal (all examples above) or inl

//Inline
type Get42 =
SqlCommandProvider<"SELECT 42", @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True">
SqlCommandProvider<"SELECT 42", @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True">

(**
Expand All @@ -176,10 +178,10 @@ The other option is to supply connection string name from config file.
*)

//default config file name is app.config or web.config
type Get43 = SqlCommandProvider<"SELECT 43", "name=AdventureWorks2014">
type Get43 = SqlCommandProvider<"SELECT 43", "name=AdventureWorks">

//specify ANY other file name (including web.config) explicitly
type Get44 = SqlCommandProvider<"SELECT 44", "name=AdventureWorks2014", ConfigFile = "user.config">
type Get44 = SqlCommandProvider<"SELECT 44", "name=AdventureWorks", ConfigFile = "user.config">

(**
I would like to emphasize that `ConfigFile` is about ***design time only*.
Expand Down Expand Up @@ -223,7 +225,7 @@ let get42 = new Get42(runTimeConnStr)
//Factory or IOC of choice to avoid logic duplication. Use F# ctor static constraints.
module DB =
[<Literal>]
let connStr = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let connStr = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"

open System.Data.SqlClient

Expand All @@ -245,7 +247,7 @@ let dbCmd2: DB.MyCmd2 = DB.createCommand()
//Static type property ConnectionStringOrName that has exactly same value as passed into SqlCommandProvider helps.
module DataAccess =
[<Literal>]
let adventureWorks = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let adventureWorks = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"
[<Literal>]
let master = @"Data Source=.;Initial Catalog=master;Integrated Security=True"

Expand Down Expand Up @@ -279,32 +281,34 @@ let bitCoinName = "Bitcoin"

type DeleteBitCoin =
SqlCommandProvider<"DELETE FROM Sales.Currency WHERE CurrencyCode = @Code"
, connectionString>
, connStr>
type InsertBitCoin =
SqlCommandProvider<"INSERT INTO Sales.Currency VALUES(@Code, @Name, GETDATE())"
, connectionString>
, connStr>
type GetBitCoin =
SqlCommandProvider<"SELECT CurrencyCode, Name FROM Sales.Currency WHERE CurrencyCode = @code"
, connectionString>
, connStr>

do
let cmd = new DeleteBitCoin() in cmd.Execute(bitCoinCode) |> ignore
let conn = new System.Data.SqlClient.SqlConnection(connectionString)
let cmd = new DeleteBitCoin(connStr) in cmd.Execute(bitCoinCode) |> ignore
let conn = new System.Data.SqlClient.SqlConnection(connStr)
conn.Open()
let tran = conn.BeginTransaction()

let cmd = new SqlCommandProvider<"INSERT INTO Sales.Currency VALUES(@Code, @Name, GETDATE())"
, connectionString>()
let cmd =
new SqlCommandProvider<"
INSERT INTO Sales.Currency VALUES(@Code, @Name, GETDATE())
", connStr>(connStr)

use insert = InsertBitCoin. Create(transaction = tran)
use insert = InsertBitCoin.Create(conn, transaction = tran)
assert(insert.Execute(bitCoinCode, bitCoinName) = 1)

use get = new GetBitCoin(transaction = tran)
use get = new GetBitCoin(conn, transaction = tran)
assert( get.Execute(bitCoinCode) |> Seq.length = 1)

tran.Rollback()

assert( GetBitCoin.Create().Execute(bitCoinCode) |> Seq.length = 0)
assert( GetBitCoin.Create(connStr).Execute(bitCoinCode) |> Seq.length = 0)

(**
Expand All @@ -316,7 +320,7 @@ to create command instances.

open System

type AdventureWorks2012 = SqlProgrammabilityProvider<connectionString>
type AdventureWorks2012 = SqlProgrammabilityProvider<connStr>

(**
Expand All @@ -328,10 +332,10 @@ But there are rare cases when you prefer to handle NULL input values inside T-SQ
*)

type IncrBy = SqlCommandProvider<"SELECT @x + ISNULL(CAST(@y AS INT), 1) ",
connectionString,
connStr,
AllParametersOptional = true,
SingleRow = true>
let incrBy = new IncrBy()
let incrBy = new IncrBy(connStr)
//pass both params passed
incrBy.Execute(Some 10, Some 2) = Some( Some 12) //true
//omit second parameter. default to 1
Expand Down Expand Up @@ -361,9 +365,9 @@ END
</pre>
*)

type TableValuedSample = SqlCommandProvider<"exec myProc @x", connectionString>
type TableValuedSample = SqlCommandProvider<"exec myProc @x", connStr>
type TVP = TableValuedSample.MyTableType
let tvpSp = new TableValuedSample()
let tvpSp = new TableValuedSample(connStr)
//nullable columns mapped to optional ctor params
tvpSp.Execute(x = [ TVP(myId = 1, myName = Some "monkey"); TVP(myId = 2) ])

Expand All @@ -374,7 +378,7 @@ Same with `SqlProgrammabilityProvider<...>`
type T = AdventureWorks2012.dbo.``User-Defined Table Types``.MyTableType

do
use cmd = new AdventureWorks2012.dbo.MyProc()
use cmd = new AdventureWorks2012.dbo.MyProc(connStr)
cmd.Execute([ T(myId = 2); T(myId = 1) ]) |> printfn "%A"

(**
Expand All @@ -386,7 +390,7 @@ There is additional ExecuteSingle/ AsyncExecuteSingle to opt-in for singleton re
*)

do
use cmd = new AdventureWorks2012.dbo.uspGetWhereUsedProductID()
use cmd = new AdventureWorks2012.dbo.uspGetWhereUsedProductID(connStr)

//sync
cmd.Execute( StartProductID = 1, CheckDate = DateTime(2013,1,1)) |> printfn "%A"
Expand All @@ -404,19 +408,19 @@ do
*)

do
use cmd = new AdventureWorks2012.dbo.uspLogError()
use cmd = new AdventureWorks2012.dbo.uspLogError(connStr)
let errorLogId = ref -1
let recordsAffected = cmd.Execute(errorLogId)
printfn "errorLogId: %i" !errorLogId

do //tupled invocation syntax
//works only in VS 2015 or later because of F# compiler bug
use cmd = new AdventureWorks2012.dbo.uspLogError()
use cmd = new AdventureWorks2012.dbo.uspLogError(connStr)
let _, errorLogId = cmd.Execute()
printfn "errorLogId: %i" errorLogId

do //mutable bindgings
use cmd = new AdventureWorks2012.dbo.uspLogError()
use cmd = new AdventureWorks2012.dbo.uspLogError(connStr)
let mutable errorLogId = -1
let recordsAffected = cmd.Execute(&errorLogId)
printfn "errorLogId: %i" errorLogId
Expand All @@ -428,13 +432,14 @@ RETURN_VALUE will be the last byref parameter.
*)

do
use cmd = new SqlProgrammabilityProvider<connectionString, UseReturnValue = true>.dbo.uspLogError()
use cmd =
new SqlProgrammabilityProvider<connStr, UseReturnValue = true>.dbo.uspLogError(connStr)
let recordsAffected, errorLogId, returnValue = cmd.Execute()
printfn "recordsAffected: %i, errorLogId: %i, returnValue: %i" recordsAffected errorLogId returnValue

(**
Things get interesting when stored procedure return both set of rows and output parameters.
I won’t show any sample code because AdventureWorks database doesn’t have such procedure.
I won't show any sample code because AdventureWorks database doesn't have such procedure.
But the only change comparing to non-query stored procedure that instead of returning number
of affected records it returns F# list of records.
Notice that list is data structure as oppose to lazy evaluated seq<_> computation.
Expand Down
6 changes: 3 additions & 3 deletions docs/content/data modification.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ open FSharp.Data
open System

[<Literal>]
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"

(**
Expand Down Expand Up @@ -63,7 +63,7 @@ let businessEntityID, jobTitle, hireDate =
HumanResources.Employee
WHERE
BusinessEntityID = @id
", connectionString, ResultType.Tuples, SingleRow = true>(connectionString))
", connectionString, ResultType.Tuples, SingleRow = true>(connectionString)

jamesKramerId |> cmd.Execute |> Option.get

Expand All @@ -72,7 +72,7 @@ assert("Production Technician - WC60" = jobTitle)
let newJobTitle = "Uber " + jobTitle

let recordsAffrected =
use updatedJobTitle = new AdventureWorks.HumanResources.uspUpdateEmployeeHireInfo(connectionString))
use updatedJobTitle = new AdventureWorks.HumanResources.uspUpdateEmployeeHireInfo(connectionString)
updatedJobTitle.Execute(
businessEntityID,
newJobTitle,
Expand Down
4 changes: 2 additions & 2 deletions docs/content/debugging.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ open FSharp.Data
open System

[<Literal>]
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"

(**
Expand All @@ -25,7 +25,7 @@ let cmd = new SqlCommandProvider<"
FROM Sales.vSalesPerson
WHERE CountryRegionName = @regionName AND SalesYTD > @salesMoreThan
ORDER BY SalesYTD
" , connectionString>()
" , connectionString>(connectionString)

cmd.ToTraceString(topN = 3L, regionName = "United States", salesMoreThan = 1000000M)
|> printfn "Sql: %s"
Expand Down
29 changes: 20 additions & 9 deletions docs/content/faq.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
open FSharp.Data

[<Literal>]
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2014;Integrated Security=True"
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True"

(**
FAQ
Expand All @@ -25,7 +25,8 @@ consider wrapping it into stored procedure or function. Both accept default valu
By default SqlCommandProvider treat all parameters as mandatory.
*)

let echoOnly = new SqlCommandProvider<"SELECT ISNULL(@x, 42)", connectionString, SingleRow = true>()
let echoOnly =
new SqlCommandProvider<"SELECT ISNULL(@x, 42)", connectionString, SingleRow = true>(connectionString)
echoOnly.Execute( x = (* must pass int value here *) 1)

(**
Expand All @@ -47,7 +48,7 @@ No generics, no F# specific types/annotations which includes optional parameters
let echoOr42 =
new SqlCommandProvider<"
SELECT ISNULL(@x, 42)
", connectionString, SingleRow = true, AllParametersOptional = true>()
", connectionString, SingleRow = true, AllParametersOptional = true>(connectionString)

// Pass parameter value. Specifying Some constructor is mandatrory.
echoOr42.Execute( Some 1)
Expand Down Expand Up @@ -77,13 +78,18 @@ To work around this limitation, you can declare another variable in your script:
*)

// this one would fail with above mentionned error:
// let echoFail = new SqlCommandProvider<"select 'hello' + @name, 'your name is :' @name", connectionString, SingleRow = true>()
//let echoFail =
// new SqlCommandProvider<"
// select 'hello' + @name, 'your name is :' @name
// ", connectionString, SingleRow = true>(connectionString)

// this one is ok as @name parameter is used only once in the statement:
let echoOk = new SqlCommandProvider< @"
declare @theName nvarchar(max)
set @theName = @name
select 'hello' + @theName, 'your name is :' + @theName", connectionString, ResultType.Tuples, SingleRow = true>()
let echoOk =
new SqlCommandProvider< @"
declare @theName nvarchar(max)
set @theName = @name
select 'hello' + @theName, 'your name is :' + @theName
", connectionString, ResultType.Tuples, SingleRow = true>(connectionString)


(**
Expand All @@ -105,7 +111,12 @@ type SqlDataReader with
member this.ToRecords<'T>() =
seq {
while this.Read() do
let data = dict [ for i = 0 to this.VisibleFieldCount - 1 do yield this.GetName(i), this.GetValue(i)]
let data =
dict [
for i = 0 to this.VisibleFieldCount - 1 do
yield this.GetName(i), this.GetValue(i)
]

yield FSharp.Data.SqlClient.DynamicRecord(data) |> box |> unbox<'T>
}

Expand Down
Loading

0 comments on commit 9f98846

Please sign in to comment.