1 people like it.

One script to create MS-SQL-database and host OWIN Web-server with SignalR-clients

One script to create MS-SQL-database and host OWIN Web-server with SignalR-clients

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
160: 
161: 
162: 
163: 
164: 
165: 
166: 
167: 
168: 
169: 
170: 
171: 
172: 
173: 
174: 
175: 
176: 
177: 
178: 
179: 
180: 
181: 
182: 
183: 
184: 
185: 
186: 
187: 
188: 
189: 
190: 
191: 
192: 
193: 
194: 
195: 
196: 
197: 
198: 
199: 
200: 
201: 
202: 
203: 
204: 
205: 
206: 
207: 
208: 
209: 
210: 
211: 
212: 
213: 
214: 
215: 
216: 
217: 
218: 
219: 
220: 
221: 
222: 
223: 
224: 
225: 
226: 
227: 
228: 
229: 
230: 
231: 
232: 
233: 
234: 
235: 
236: 
237: 
238: 
239: 
240: 
241: 
242: 
243: 
244: 
245: 
246: 
247: 
248: 
249: 
250: 
251: 
252: 
253: 
254: 
255: 
256: 
257: 
258: 
259: 
260: 
261: 
262: 
263: 
264: 
265: 
266: 
267: 
268: 
269: 
270: 
271: 
272: 
273: 
274: 
275: 
276: 
277: 
278: 
279: 
280: 
281: 
282: 
283: 
284: 
285: 
286: 
287: 
288: 
289: 
290: 
291: 
#if INTERACTIVE
open System
open System.IO

Console.WriteLine "Downloading components, etc. Will take a while."
// Run as admin, developer command prompt or F# Interactive. e.g. "fsi myfile.fsx"

[<Literal>]
let connectionString = "Data Source=localhost; Initial Catalog=myDatabase; Integrated Security=True;"
let serverDir =  __SOURCE_DIRECTORY__ + @"/frontend"
 
// --- Package Restore ------------------------------------
Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
if not <| File.Exists "paket.exe" then
    let url = "https://github.com/fsprojects/Paket/releases/download/1.18.0/paket.exe"
    use wc = new Net.WebClient ()
    let tmp = Path.GetTempFileName () 
    wc.DownloadFile (url, tmp); 
    File.Move (tmp,Path.GetFileName url)
 
#r "paket.exe"
 
Paket.Dependencies.Install """
source https://nuget.org/api/v2
nuget FAKE
nuget FSharp.Formatting
nuget FSharp.Data
nuget FSharp.Data.SqlClient
nuget Microsoft.AspNet.SignalR.Core
nuget Microsoft.AspNet.WebApi.OwinSelfHost
nuget Microsoft.Owin.Cors
nuget Microsoft.Owin.StaticFiles
nuget Rx-Main
nuget SQLProvider
nuget SourceLink.Fake
""";; // Rx-Main and SourceLink are for future use only...

// --- Drop and Create a Database ------------------------------------

#I @"./packages/FAKE/tools"
#r @"./packages/FAKE/tools/FakeLib.dll"
#r @"./packages/FAKE/tools/Fake.SQL.dll"

open Fake
open Fake.SQL

let SqlServerConnection = connectionString |> getServerInfo
SqlServerConnection |> SqlServer.DropDb |> ignore
SqlServerConnection |> SqlServer.CreateDb |> ignore

// Wouldn't need this if you have the DB already or install it from Fake scripts
// like this: SqlServer.runScript SqlServerConnection "createtables.sql"

#r @"./packages/FSharp.Data.SqlClient/lib/net40/FSharp.Data.SqlClient.dll"
open FSharp.Data

// Create Tables
[<Literal>]
let personTable="""
CREATE TABLE dbo.Person(
	Id int NOT NULL IDENTITY (1, 1) PRIMARY KEY,
	FirstName nvarchar(255) NOT NULL,
	LastName nvarchar(255) NOT NULL
	)  ON [PRIMARY]
"""

[<Literal>]
let orderTable="""
CREATE TABLE dbo.[Order](
	Id int NOT NULL IDENTITY (1, 1) PRIMARY KEY,
	PersonId int NOT NULL,
	Amount decimal(18, 0) NOT NULL,
	OrderDate smalldatetime NOT NULL
	)  ON [PRIMARY]
"""
async {
   use cmd1 = new SqlCommandProvider<personTable, connectionString>()
   let! p = cmd1.AsyncExecute()
   use cmd2 = new SqlCommandProvider<orderTable, connectionString>()
   let! o = cmd2.AsyncExecute()
   return p+o
} |> Async.RunSynchronously;;

// Insert Demo Data
[<Literal>]
let demoData="INSERT INTO [dbo].[Person] ([FirstName],[LastName]) VALUES (@firstName, @lastName)"

async {
   use cmd3 = new SqlCommandProvider<demoData, connectionString>()
   let! i1 = cmd3.AsyncExecute(firstName = "John", lastName = "Doe")
   let! i2 = cmd3.AsyncExecute(firstName = "Tuomas", lastName = "Hietanen")
   return i1+i2
} |> Async.RunSynchronously

// --- Create a HTML-Page ------------------------------------

// Could also load from separate files :-)
let page = """
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta charset="UTF-8" />
    <title>My Site</title>
	<!--script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js"></script-->
	<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.js"></script>
	<!--script src="http://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.2.0.min.js"></script-->
	<script src="http://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.2.0.js"></script>
    <script type="text/javascript" src="/signalr/hubs"></script>
    <script type="text/javascript">
		var personList = {};
        $(document).ready(function () {

            //SignalR Hub:
            var signalHub;
            $.connection.hub.url = "/signalr";
            signalHub = $.connection.SignalHub; //Hub class
            if (!signalHub) console.log("hub not found");

            signalHub.client.listPersons = function (data) {
				data.forEach(function(itm) {
					 $('#peopleSelect')
						 .append($("<option></option>")
						 .attr("value",itm.Item1)
						 .text(itm.Item2)); 
					personList[itm.Item1] = itm.Item2;
				});
			};

            signalHub.client.acceptedOrder = function (data) {
                alert(data);
			};

            signalHub.client.NotifyAll = function (id, myDay) {
                alert("Hi all! New order for person " + personList[id] + " added to the system at " + myDay + ". ");
			};
			
            $.connection.hub.logging = true;
            $.connection.hub.start().
                done(function () {
					
                    $("#btn1").click(function () {
						var person = $('#peopleSelect').val();
						var ms = new Date();
                        signalHub.server.createOrder(person, ms);
                        return false;
                    });
                });
        });
    </script>
    <style>
        .bgFrame {
            background-color: #ffffff;
            border: thin solid #000000;
            padding: 30px;
            margin: 30px;
            width: 600px;
            height: 200px;
            vertical-align: middle;
            text-align: center;
        }
    </style>
</head>

<body style="background-color: #cc99ff">
    <div class="bgFrame">
        <h2>Create orders for persons:</h2><br />
        <form method="post" action="index.html">
            <select id="peopleSelect"></select><br />
            <input type="button" id="btn1" value="Place new order!" />
        </form>
    </div>
</body>
</html>
"""

if not <| Directory.Exists serverDir then
    Directory.CreateDirectory serverDir |> ignore

let filename = serverDir + @"/index.html"
if not <| File.Exists filename then
    File.WriteAllText (filename, page)

// --- Load the References ------------------------------------

// Yes you can run this OWIN server also from Mono! Mono needs #I:s...

#r @"./packages/FSharp.Data/lib/net40/FSharp.Data.dll"
#r @"./packages/SQLProvider/lib/net40/FSharp.Data.SqlProvider.dll"

// OWIN and SignalR-packages:
#I @"./packages/Microsoft.AspNet.SignalR.Core/lib/net45"
#r @"./packages/Microsoft.AspNet.SignalR.Core/lib/net45/Microsoft.AspNet.SignalR.Core.dll"
#I @"./packages/Microsoft.Owin/lib/net45" 
#r @"./packages/Microsoft.Owin/lib/net45/Microsoft.Owin.dll"
#I @"./packages/Microsoft.Owin.Security/lib/net45"
#r @"./packages/Microsoft.Owin.Security/lib/net45/Microsoft.Owin.Security.dll"
#I @"./packages/Microsoft.Owin.Hosting/lib/net45"
#r @"./packages/Microsoft.Owin.Hosting/lib/net45/Microsoft.Owin.Hosting.dll"
#I @"./packages/Microsoft.Owin.Host.HttpListener/lib/net45"
#r @"./packages/Microsoft.Owin.Host.HttpListener/lib/net45/Microsoft.Owin.Host.HttpListener.dll"
#I @"./packages/Microsoft.Owin.StaticFiles/lib/net45"
#r @"./packages/Microsoft.Owin.StaticFiles/lib/net45/Microsoft.Owin.StaticFiles.dll"
#I @"./packages/Microsoft.Owin.FileSystems/lib/net45"
#r @"./packages/Microsoft.Owin.FileSystems/lib/net45/Microsoft.Owin.FileSystems.dll"
#I @"./packages/Newtonsoft.Json/lib/net45"
#r @"./packages/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
#I @"./packages/Owin/lib/net40"
#r @"./packages/Owin/lib/net40/Owin.dll"

#else
// Use paket to manage project references. 
module myServer
#endif
// --- SQL-Server Connection ------------------------------------

open FSharp.Data
open FSharp.Data.Sql

type SqlConnection = 
    SqlDataProvider< // Supports SQL-Server, Oracle, MySql, Odbc, etc. 
        ConnectionString = connectionString,
        DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER,
        IndividualsAmount = 1000,
        UseOptionTypes = true>

// --- Communication to Clients ------------------------------------

open System
open System.Linq
open Microsoft.AspNet.SignalR
open Microsoft.AspNet.SignalR.Hubs 
open System.Threading.Tasks

type MessageToClient =  // Server can push data to single or all clients
    abstract ListPersons : seq<int * string> -> Task
    abstract AcceptedOrder : string -> Task
    abstract NotifyAll : int * DateTime -> Task

[<HubName("SignalHub")>]
type SignalHub() as this = 
    inherit Hub<MessageToClient>()

    override __.OnConnected() =
        base.OnConnected() |> ignore
        let context = SqlConnection.GetDataContext()
        let items =
            query {
                for c in context.``[dbo].[Person]`` do
                // where (c.Id < 100000)
                select (c.Id, c.FirstName + " " + c.LastName) 
            } |> Seq.toArray
        // printfn "Client connected: %s" this.Context.ConnectionId
        this.Clients.Caller.ListPersons items
       
    member __.CreateOrder (personId:int) (time:DateTime) = 
        let context = SqlConnection.GetDataContext()
        let itm = context.``[dbo].[Order]``.Create(
                    1.0m,
                    PersonId = personId,
                    OrderDate = time
        ) // or could also use SqlCommandProvider...
        context.SubmitUpdates()
        this.Clients.Caller.AcceptedOrder "Thanks for the order!" |> ignore
        this.Clients.All.NotifyAll (personId, time)

let hubConfig = HubConfiguration(EnableDetailedErrors = true, EnableJavaScriptProxies = true)

type MyWebStartup() =
    member x.Configuration(ap:Owin.IAppBuilder) =
        //OWIN Component registrations here...

        //SignalR:
        let app = Owin.OwinExtensions.MapSignalR(ap, hubConfig)

        //Static files server (Note: default FileSystem is current directory!)
        let fileServerOptions = Microsoft.Owin.StaticFiles.FileServerOptions()
        fileServerOptions.DefaultFilesOptions.DefaultFileNames.Add "index.html"
        fileServerOptions.FileSystem <- Microsoft.Owin.FileSystems.PhysicalFileSystem <| serverDir
        Owin.FileServerExtensions.UseFileServer(app, fileServerOptions) |> ignore
        ()

[<assembly: Microsoft.Owin.OwinStartup(typeof<MyWebStartup>)>]
do()

let url = "http://localhost:7000"
let server = Microsoft.Owin.Hosting.WebApp.Start<MyWebStartup> url
Console.WriteLine ("Server started at: " + url)
Console.WriteLine "Press Enter to stop & quit."
Console.ReadLine()
server.Dispose()
Multiple items
union case CodeLanguage.FSharp: CodeLanguage

--------------------
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Data
type SqlConnection = obj

Full name: Script.SqlConnection
val connectionString : string

Full name: Script.connectionString
Multiple items
union case ServiceInstallStart.System: ServiceInstallStart

--------------------
namespace System
namespace System.Linq
namespace Microsoft
namespace System.Threading
namespace System.Threading.Tasks
type MessageToClient =
  interface
    abstract member AcceptedOrder : string -> Task
    abstract member ListPersons : seq<int * string> -> Task
    abstract member NotifyAll : int * DateTime -> Task
  end

Full name: Script.MessageToClient
abstract member MessageToClient.ListPersons : seq<int * string> -> Task

Full name: Script.MessageToClient.ListPersons
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
Multiple items
type Task =
  new : action:Action -> Task + 7 overloads
  member AsyncState : obj
  member ContinueWith : continuationAction:Action<Task> -> Task + 9 overloads
  member CreationOptions : TaskCreationOptions
  member Dispose : unit -> unit
  member Exception : AggregateException
  member Id : int
  member IsCanceled : bool
  member IsCompleted : bool
  member IsFaulted : bool
  ...

Full name: System.Threading.Tasks.Task

--------------------
type Task<'TResult> =
  inherit Task
  new : function:Func<'TResult> -> Task<'TResult> + 7 overloads
  member ContinueWith : continuationAction:Action<Task<'TResult>> -> Task + 9 overloads
  member Result : 'TResult with get, set
  static member Factory : TaskFactory<'TResult>

Full name: System.Threading.Tasks.Task<_>

--------------------
Task(action: Action) : unit
Task(action: Action, cancellationToken: Threading.CancellationToken) : unit
Task(action: Action, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj) : unit
Task(action: Action, cancellationToken: Threading.CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: Threading.CancellationToken) : unit
Task(action: Action<obj>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: Threading.CancellationToken, creationOptions: TaskCreationOptions) : unit

--------------------
Task(function: Func<'TResult>) : unit
Task(function: Func<'TResult>, cancellationToken: Threading.CancellationToken) : unit
Task(function: Func<'TResult>, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj) : unit
Task(function: Func<'TResult>, cancellationToken: Threading.CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: Threading.CancellationToken) : unit
Task(function: Func<obj,'TResult>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: Threading.CancellationToken, creationOptions: TaskCreationOptions) : unit
abstract member MessageToClient.AcceptedOrder : string -> Task

Full name: Script.MessageToClient.AcceptedOrder
abstract member MessageToClient.NotifyAll : int * DateTime -> Task

Full name: Script.MessageToClient.NotifyAll
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
Multiple items
type SignalHub =
  inherit obj
  new : unit -> SignalHub
  member CreateOrder : personId:int -> time:DateTime -> 'a
  override OnConnected : unit -> 'a

Full name: Script.SignalHub

--------------------
new : unit -> SignalHub
val this : SignalHub
override SignalHub.OnConnected : unit -> 'a

Full name: Script.SignalHub.OnConnected
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val query : Linq.QueryBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
module Seq

from Microsoft.FSharp.Collections
val toArray : source:seq<'T> -> 'T []

Full name: Microsoft.FSharp.Collections.Seq.toArray
member SignalHub.CreateOrder : personId:int -> time:DateTime -> 'a

Full name: Script.SignalHub.CreateOrder
val hubConfig : obj

Full name: Script.hubConfig
Multiple items
type MyWebStartup =
  new : unit -> MyWebStartup
  member Configuration : ap:'a -> unit

Full name: Script.MyWebStartup

--------------------
new : unit -> MyWebStartup
val x : MyWebStartup
Multiple items
member MyWebStartup.Configuration : ap:'a -> unit

Full name: Script.MyWebStartup.Configuration

--------------------
namespace System.Configuration
val ap : 'a
val app : obj
val fileServerOptions : obj
module FileSystem

from Fake
val serverDir : string

Full name: Script.serverDir
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val url : string

Full name: Script.url
val server : obj

Full name: Script.server
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
Console.WriteLine() : unit
   (+0 other overloads)
Console.WriteLine(value: string) : unit
   (+0 other overloads)
Console.WriteLine(value: obj) : unit
   (+0 other overloads)
Console.WriteLine(value: uint64) : unit
   (+0 other overloads)
Console.WriteLine(value: int64) : unit
   (+0 other overloads)
Console.WriteLine(value: uint32) : unit
   (+0 other overloads)
Console.WriteLine(value: int) : unit
   (+0 other overloads)
Console.WriteLine(value: float32) : unit
   (+0 other overloads)
Console.WriteLine(value: float) : unit
   (+0 other overloads)
Console.WriteLine(value: decimal) : unit
   (+0 other overloads)
Console.ReadLine() : string

More information

Link:http://fssnip.net/rv
Posted:9 years ago
Author:Tuomas Hietanen
Tags: owin , website , signalr , sql