/FsSql.Tests/NorthwindTests.fs

http://github.com/mausch/FsSql · F# · 88 lines · 77 code · 11 blank · 0 comment · 9 complexity · 2ab542a9b8ebe0d98fdc68e6a6b1bc9e MD5 · raw file

  1. module FsSql.Tests.NorthwindTests
  2. open System
  3. open System.Collections.Generic
  4. open System.Data
  5. open Microsoft.FSharp.Reflection
  6. #if __MonoSQL__
  7. open Mono.Data.Sqlite
  8. type SQLiteConnection = SqliteConnection
  9. type SQLiteException = SqliteException
  10. #else
  11. open System.Data.SQLite
  12. #endif
  13. let createConnection() =
  14. let conn = new SQLiteConnection("Data Source=test.db;Version=3;New=True;")
  15. conn.Open()
  16. conn :> IDbConnection
  17. let createSchema types =
  18. let exec a = Sql.execNonQuery (Sql.withNewConnection createConnection) a [] |> ignore
  19. let sqlType t =
  20. match t with
  21. | x when x = typeof<int> -> "int"
  22. | x when x = typeof<string> -> "varchar"
  23. | x when x = typeof<bool> -> "int"
  24. | x when x = typeof<DateTime> -> "datetime"
  25. | x -> failwithf "Don't know how to express type %A in database" x
  26. let escape s =
  27. let keywords = HashSet<_>(["order"], StringComparer.InvariantCultureIgnoreCase)
  28. if keywords.Contains s
  29. then sprintf "\"%s\"" s // sqlite-specific quote
  30. else s
  31. let createTable (escape: string -> string) (sqlType: Type -> string) (t: Type) =
  32. let fields = FSharpType.GetRecordFields t |> Seq.filter (fun p -> p.Name <> "id")
  33. let table = escape t.Name
  34. let drop = sprintf "drop table if exists %s" table
  35. let fields =
  36. let fieldType (t: Type) =
  37. let nullable = t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<option<_>>
  38. let sqlType =
  39. let t =
  40. if nullable
  41. then t.GetGenericArguments().[0]
  42. else t
  43. sqlType t
  44. let nullable = if nullable then "" else "not"
  45. sprintf "%s %s null" sqlType nullable
  46. fields |> Seq.map (fun f -> sprintf "%s %s" (escape f.Name) (fieldType f.PropertyType))
  47. let fields = String.Join(",", Seq.toArray fields)
  48. let create = sprintf "create table %s (id int primary key, %s)" table fields
  49. printfn "%s" create
  50. exec drop
  51. exec create
  52. ()
  53. types |> Seq.iter (createTable escape sqlType)
  54. type Employee = {
  55. id: int
  56. LastName: string
  57. FirstName: string
  58. ReportsTo: int option
  59. }
  60. type Order = {
  61. id: int
  62. customer: int
  63. employee: int
  64. date: DateTime
  65. }
  66. type Product = {
  67. id: int
  68. ProductName: string
  69. }
  70. type OrderDetail = {
  71. id: int
  72. order: int
  73. product: int
  74. }
  75. let ``something``() =
  76. createSchema [typeof<Employee>; typeof<Order>; typeof<Product>; typeof<OrderDetail>]
  77. ()