Docker

We already have the database running in Docker, why don't we do the same with the web app?

Let's briefly go through the overall architecture of Suave Music Store running on Docker (the database part is already configured):

  • We'll use two separate docker images:
    • First image for the database,
    • Second image for the actual F# app,
  • The db image will be build on top of the official postgres image,
  • The db image, upon build initialization, will create our suavemusicstore database from script,
  • The app image will extend the official fsharp image,
  • The app image will copy compiled binaries to the image,
  • The app image will depend on the db container, that's why we'll provide a link between those.

That's the big picture, let's now go straight to essential configuration:

Database connection string

To run on docker, we'll have to provide a proper connection string. Up until now, function getContext in Db module utilized the same connection string that was used for type provider.

But as we'll run the app container in isolation, we have to specify a proper connection string:

Db.fs

  29: 
  30: 
  31: 
  32: 
  33: 
let DockerConnectionString = "Server=suavemusicstore_db;" + "Database=suavemusicstore;" + "User Id=suave;" + "Password=1234;"

Db.fs

  35: 
let getContext() = Sql.GetDataContext(DockerConnectionString)

Server suavemusicstore_db is the docker link name that we'll apply when firing up containers. Docker networking infrastructure takes care of matching the link name with destination host, which will be run in a separate container.

In real world (yeah, I knew I'd use this phrase one day) we'd probably move the connection strings to some kind of configuration file.

Server http binding

At the moment when starting web server (last line of App module), the defaultConfig is used, which in turn uses HTTP binding to 127.0.0.1 (localhost) IP address. From this Stack Overflow answer we can read that "binding inside container to localhost usually prevent from accepting connections". Solution here is to accept requests from all IPs instead. This can be done by providing 0.0.0.0 address:

App.fs

 322: 
 323: 
 324: 
let cfg = { defaultConfig with bindings = [ HttpBinding.createSimple HTTP "0.0.0.0" 8083 ] }

App.fs

 326: 
startWebServer cfg webPart

The snippets above copies all fields from the defaultConfig and overrides the binding to 0.0.0.0:8083.

Server image

Database Docker image is already in place, under postgres directory.

For the Web image, let's create new Dockerfile in project's root directory. It will make use of the official fsharp image:

FROM fsharp:4.0

COPY ./bin/Debug/net461 /app

EXPOSE 8083

WORKDIR /app

CMD ["mono", "SuaveMusicStore.exe"]

It will use the COPY instruction as well, but this time we'll copy the whole directory with compiled binaries. Because we're going to bind to port 8083, we need to declare that in the Dockerfile with the EXPOSE instruction. CMD stands for command that is executed when we spin up a container from this image, and the preceding WORKDIR instruction simply states what the working directory should be when running all subsequent RUN all CMD instructions.

I chose to copy compiled binaries to the image instead of compiling the app inside docker. If desired however, one should be able to do the opposite and compile sources within the F# image itself.

Building the image

To build the docker image, we can invoke following commands:

> .\build.cmd
> docker build -t theimowski/suavemusicstore_app:0.1 .

Above snippet:

  • runs our build.cmd script (build.sh for Mac and Linux) to compile the application
  • builds app (server) image with a proper tag from current directory (.)

Note: make sure you have compiled the app before building the image.

After running the commands and typing docker images, you should spot the newly built image next to previous one:

REPOSITORY                       TAG     IMAGE ID            CREATED             SIZE
theimowski/suavemusicstore_app   0.1     2fc4970e9b34        50 seconds ago      633.2 MB
theimowski/suavemusicstore_db    0.1     143b21b4a88c        2 days ago          264.6 MB

Spinning up web container

Now that we have the second image in place, it's finally time to run a container. To do so, we can invoke following command:

> docker run -p 8083:8083 -d --name suavemusicstore_app `
  --link suavemusicstore_db:suavemusicstore_db theimowski/suavemusicstore_app:0.1

The command above consists of a few arguments:

  • -p 8083:8083 instructs to expose the 8083 port from the container to the docker host,
  • -d stands for detached (background) mode,
  • --name assigns a friendly name to the running container,
  • --link suavemusicstore_db:suavemusicstore_db lets the app container communicate with the db container using the name of db container. Note the alias for the link (suavemusicstore_db) must be the same as in the Db module for the getContext function,
  • last argument is the tag of the image.

If everything went fine, we should now be able to see two running containers with the docker ps command:

CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                    NAMES
3eb8ba5ec672        theimowski/suavemusicstore_app:0.1   "mono SuaveMusicStore"   43 seconds ago      Up 43 seconds       0.0.0.0:8083->8083/tcp   suavemusicstore_app
28abd8d491d8        theimowski/suavemusicstore_db:0.1    "/docker-entrypoint.s"   53 seconds ago      Up 52 seconds       5432/tcp                 suavemusicstore_db

To try out the application, open up your browser and navigate to the endpoint on docker host:

  • When running Docker Toolbox on Win / Mac, check out docker-machine ip <docker VM name> for docker host IP, and the endpoint should be something like http://192.168.99.100:8083/
  • When running Docker natively on Linux, the endpoint should be just http://localhost:8083/

Phew! We did it, Suave Music Store is now running fully on Docker - How cool is that?

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
namespace FSharp.Data.Sql
Multiple items
type LiteralAttribute =
inherit Attribute
new : unit -> LiteralAttribute

Full name: Microsoft.FSharp.Core.LiteralAttribute

--------------------
new : unit -> LiteralAttribute
val TPConnectionString : string

Full name: SuaveMusicStore.Db.TPConnectionString
type Sql = SqlDataProvider<...>

Full name: SuaveMusicStore.Db.Sql
type SqlDataProvider

Full name: FSharp.Data.Sql.SqlDataProvider


<summary>Typed representation of a database</summary>
<param name='ConnectionString'>The connection string for the SQL database</param>
<param name='ConnectionStringName'>The connection string name to select from a configuration file</param>
<param name='DatabaseVendor'> The target database vendor</param>
<param name='IndividualsAmount'>The amount of sample entities to project into the type system for each SQL entity type. Default 1000.</param>
<param name='UseOptionTypes'>If true, F# option types will be used in place of nullable database columns. If false, you will always receive the default value of the column's type even if it is null in the database.</param>
<param name='ResolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types.</param>
<param name='Owner'>The owner of the schema for this provider to resolve (Oracle Only)</param>
<param name='CaseSensitivityChange'>Should we do ToUpper or ToLower when generating table names?</param>
<param name='TableNames'>Comma separated table names list to limit a number of tables in big instances. The names can have '%' sign to handle it as in the 'LIKE' query (Oracle and MSSQL Only)</param>
<param name='OdbcQuote'>Odbc quote characters: Quote characters for the table and column names: `alias`, [alias]</param>
<param name='SQLiteLibrary'>Use System.Data.SQLite or Mono.Data.SQLite or select automatically (SQLite only)</param>
namespace FSharp.Data.Sql.Common
type DatabaseProviderTypes =
| MSSQLSERVER = 0
| SQLITE = 1
| POSTGRESQL = 2
| MYSQL = 3
| ORACLE = 4
| MSACCESS = 5
| ODBC = 6
| FIREBIRD = 7

Full name: FSharp.Data.Sql.Common.DatabaseProviderTypes
Common.DatabaseProviderTypes.POSTGRESQL: Common.DatabaseProviderTypes = 2
type CaseSensitivityChange =
| ORIGINAL = 0
| TOUPPER = 1
| TOLOWER = 2

Full name: FSharp.Data.Sql.Common.CaseSensitivityChange
Common.CaseSensitivityChange.ORIGINAL: Common.CaseSensitivityChange = 0
type DbContext = SqlDataProvider<...>.dataContext

Full name: SuaveMusicStore.Db.DbContext
type dataContext =
member ClearUpdates : unit -> List<SqlEntity>
member CreateConnection : unit -> IDbConnection
member GetUpdates : unit -> List<SqlEntity>
member Public : publicSchema
member SubmitUpdates : unit -> Unit
member SubmitUpdatesAsync : unit -> Async<Unit>
nested type public.albumdetails.Individuals
nested type public.albumdetailsEntity
nested type public.albums.Individuals
nested type public.albumsEntity
...

Full name: FSharp.Data.Sql.SqlDataProvider,DatabaseVendor="2",ConnectionString="Server=192.168.99.100;Database=suavemusicstore;User Id=suave;Password=1234;",CaseSensitivityChange="0".dataContext
type Album = SqlDataProvider<...>.dataContext.public.albumsEntity

Full name: SuaveMusicStore.Db.Album
type Genre = SqlDataProvider<...>.dataContext.public.genresEntity

Full name: SuaveMusicStore.Db.Genre
type AlbumDetails = SqlDataProvider<...>.dataContext.public.albumdetailsEntity

Full name: SuaveMusicStore.Db.AlbumDetails
type Artist = SqlDataProvider<...>.dataContext.public.artistsEntity

Full name: SuaveMusicStore.Db.Artist
type User = SqlDataProvider<...>.dataContext.public.usersEntity

Full name: SuaveMusicStore.Db.User
type CartDetails = SqlDataProvider<...>.dataContext.public.cartdetailsEntity

Full name: SuaveMusicStore.Db.CartDetails
type Cart = SqlDataProvider<...>.dataContext.public.cartsEntity

Full name: SuaveMusicStore.Db.Cart
type BestSeller = SqlDataProvider<...>.dataContext.public.bestsellersEntity

Full name: SuaveMusicStore.Db.BestSeller
val DockerConnectionString : string

Full name: SuaveMusicStore.Db.DockerConnectionString
val getContext : unit -> SqlDataProvider<...>.dataContext

Full name: SuaveMusicStore.Db.getContext
SqlDataProvider<...>.GetDataContext() : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider using the static parameters</summary>

SqlDataProvider<...>.GetDataContext(transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider</summary>
<param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>

SqlDataProvider<...>.GetDataContext(connectionString: string) : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider</summary>
<param name='connectionString'>The database connection string</param>

SqlDataProvider<...>.GetDataContext(connectionString: string, transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider</summary>
<param name='connectionString'>The database connection string</param>
<param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>

SqlDataProvider<...>.GetDataContext(connectionString: string, resolutionPath: string) : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider</summary>
<param name='connectionString'>The database connection string</param>
<param name='resolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types</param>

SqlDataProvider<...>.GetDataContext(connectionString: string, resolutionPath: string, transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


<summary>Returns an instance of the SQL Provider</summary>
<param name='connectionString'>The database connection string</param>
<param name='resolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types</param>
<param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>
val getGenres : ctx:DbContext -> Genre list

Full name: SuaveMusicStore.Db.getGenres
val ctx : DbContext
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
property SqlDataProvider<...>.dataContext.Public: SqlDataProvider<...>.dataContext.publicSchema
property SqlDataProvider<...>.dataContext.publicSchema.Genres: SqlDataProvider<...>.dataContext.publicSchema.public.genres


<summary> The base table genres belonging to schema public</summary>
Multiple items
module Seq

from FSharp.Data.Sql

--------------------
module Seq

from Microsoft.FSharp.Collections
val toList : source:seq<'T> -> 'T list

Full name: Microsoft.FSharp.Collections.Seq.toList
val getAlbumsForGenre : genreName:string -> ctx:DbContext -> Album list

Full name: SuaveMusicStore.Db.getAlbumsForGenre
val genreName : string
val query : Linq.QueryBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
val album : SqlDataProvider<...>.dataContext.public.albumsEntity
property SqlDataProvider<...>.dataContext.publicSchema.Albums: SqlDataProvider<...>.dataContext.publicSchema.public.albums


<summary> The base table albums belonging to schema public</summary>
custom operation: join var in collection on (outerKey = innerKey). Note that parentheses are required after 'on'

Calls Linq.QueryBuilder.Join
val genre : SqlDataProvider<...>.dataContext.public.genresEntity
property SqlDataProvider<...>.dataContext.public.genresEntity.Genreid: int


<summary> integer</summary>
custom operation: where (bool)

Calls Linq.QueryBuilder.Where
property SqlDataProvider<...>.dataContext.public.genresEntity.Name: string


<summary> character varying(120)</summary>
custom operation: select ('Result)

Calls Linq.QueryBuilder.Select
val getAlbumDetails : id:int -> ctx:DbContext -> AlbumDetails option

Full name: SuaveMusicStore.Db.getAlbumDetails
val id : int
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val album : SqlDataProvider<...>.dataContext.public.albumdetailsEntity
property SqlDataProvider<...>.dataContext.publicSchema.Albumdetails: SqlDataProvider<...>.dataContext.publicSchema.public.albumdetails


<summary> The view albumdetails belonging to schema public</summary>
property SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumid: int


<summary> integer</summary>
val tryHead : source:seq<'T> -> 'T option

Full name: Microsoft.FSharp.Collections.Seq.tryHead
val getAlbumsDetails : ctx:DbContext -> AlbumDetails list

Full name: SuaveMusicStore.Db.getAlbumsDetails
Multiple items
module List

from FSharp.Data.Sql

--------------------
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val sortBy : projection:('T -> 'Key) -> list:'T list -> 'T list (requires comparison)

Full name: Microsoft.FSharp.Collections.List.sortBy
val a : SqlDataProvider<...>.dataContext.public.albumdetailsEntity
property SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Artist: string


<summary> character varying(120)</summary>
val getAlbum : id:int -> ctx:DbContext -> Album option

Full name: SuaveMusicStore.Db.getAlbum
property SqlDataProvider<...>.dataContext.public.albumsEntity.Albumid: int


<summary> integer</summary>
val getBestSellers : ctx:DbContext -> BestSeller list

Full name: SuaveMusicStore.Db.getBestSellers
property SqlDataProvider<...>.dataContext.publicSchema.Bestsellers: SqlDataProvider<...>.dataContext.publicSchema.public.bestsellers


<summary> The view bestsellers belonging to schema public</summary>
val deleteAlbum : album:Album -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.deleteAlbum
val album : Album
member Common.SqlEntity.Delete : unit -> unit
SqlDataProvider<...>.dataContext.SubmitUpdates() : Unit


<summary>Save changes to data-source. May throws errors: To deal with non-saved items use GetUpdates() and ClearUpdates().</summary>
val getArtists : ctx:DbContext -> Artist list

Full name: SuaveMusicStore.Db.getArtists
property SqlDataProvider<...>.dataContext.publicSchema.Artists: SqlDataProvider<...>.dataContext.publicSchema.public.artists


<summary> The base table artists belonging to schema public</summary>
val createAlbum : artistId:int * genreId:int * price:decimal * title:string -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.createAlbum
val artistId : int
val genreId : int
val price : decimal
val title : string
SqlDataProvider<...>.dataContext.publicSchema.public.albums.Create() : SqlDataProvider<...>.dataContext.public.albumsEntity
SqlDataProvider<...>.dataContext.publicSchema.public.albums.Create(data: System.Collections.Generic.IEnumerable<string * obj>) : SqlDataProvider<...>.dataContext.public.albumsEntity


<summary>Item array of database columns:
artistid,genreid,price,title</summary>

SqlDataProvider<...>.dataContext.publicSchema.public.albums.Create(artistid: int, genreid: int, price: decimal, title: string) : SqlDataProvider<...>.dataContext.public.albumsEntity
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val updateAlbum : album:Album -> artistId:int * genreId:int * price:decimal * title:string -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.updateAlbum
property SqlDataProvider<...>.dataContext.public.albumsEntity.Artistid: int


<summary> integer</summary>
property SqlDataProvider<...>.dataContext.public.albumsEntity.Genreid: int


<summary> integer</summary>
property SqlDataProvider<...>.dataContext.public.albumsEntity.Price: decimal


<summary> numeric</summary>
property SqlDataProvider<...>.dataContext.public.albumsEntity.Title: string


<summary> character varying(160)</summary>
val validateUser : username:string * password:string -> ctx:DbContext -> User option

Full name: SuaveMusicStore.Db.validateUser
val username : string
val password : string
val user : SqlDataProvider<...>.dataContext.public.usersEntity
property SqlDataProvider<...>.dataContext.publicSchema.Users: SqlDataProvider<...>.dataContext.publicSchema.public.users


<summary> The base table users belonging to schema public</summary>
property SqlDataProvider<...>.dataContext.public.usersEntity.Username: string


<summary> character varying(200)</summary>
property SqlDataProvider<...>.dataContext.public.usersEntity.Password: string


<summary> character varying(200)</summary>
val getCart : cartId:string -> albumId:int -> ctx:DbContext -> Cart option

Full name: SuaveMusicStore.Db.getCart
val cartId : string
val albumId : int
val cart : SqlDataProvider<...>.dataContext.public.cartsEntity
property SqlDataProvider<...>.dataContext.publicSchema.Carts: SqlDataProvider<...>.dataContext.publicSchema.public.carts


<summary> The base table carts belonging to schema public</summary>
property SqlDataProvider<...>.dataContext.public.cartsEntity.Cartid: string


<summary> character varying(50)</summary>
property SqlDataProvider<...>.dataContext.public.cartsEntity.Albumid: int


<summary> integer</summary>
val addToCart : cartId:string -> albumId:int -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.addToCart
union case Option.Some: Value: 'T -> Option<'T>
val cart : Cart
property SqlDataProvider<...>.dataContext.public.cartsEntity.Count: int


<summary> integer</summary>
union case Option.None: Option<'T>
SqlDataProvider<...>.dataContext.publicSchema.public.carts.Create() : SqlDataProvider<...>.dataContext.public.cartsEntity
SqlDataProvider<...>.dataContext.publicSchema.public.carts.Create(data: System.Collections.Generic.IEnumerable<string * obj>) : SqlDataProvider<...>.dataContext.public.cartsEntity


<summary>Item array of database columns:
albumid,cartid,count,datecreated</summary>

SqlDataProvider<...>.dataContext.publicSchema.public.carts.Create(albumid: int, cartid: string, count: int, datecreated: System.DateTime) : SqlDataProvider<...>.dataContext.public.cartsEntity
namespace System
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

--------------------
System.DateTime()
(+0 other overloads)
System.DateTime(ticks: int64) : unit
(+0 other overloads)
System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
(+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit
(+0 other overloads)
property System.DateTime.UtcNow: System.DateTime
val getCartsDetails : cartId:string -> ctx:DbContext -> CartDetails list

Full name: SuaveMusicStore.Db.getCartsDetails
val cart : SqlDataProvider<...>.dataContext.public.cartdetailsEntity
property SqlDataProvider<...>.dataContext.publicSchema.Cartdetails: SqlDataProvider<...>.dataContext.publicSchema.public.cartdetails


<summary> The view cartdetails belonging to schema public</summary>
property SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Cartid: string


<summary> character varying(50)</summary>
val removeFromCart : cart:Cart -> albumId:'a -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.removeFromCart
val albumId : 'a
val getCarts : cartId:string -> ctx:DbContext -> Cart list

Full name: SuaveMusicStore.Db.getCarts
val upgradeCarts : cartId:string * username:string -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.upgradeCarts
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val existing : Cart
val getUser : username:string -> ctx:DbContext -> User option

Full name: SuaveMusicStore.Db.getUser
val newUser : username:string * password:string * email:string -> ctx:DbContext -> SqlDataProvider<...>.dataContext.public.usersEntity

Full name: SuaveMusicStore.Db.newUser
val email : string
SqlDataProvider<...>.dataContext.publicSchema.public.users.Create() : SqlDataProvider<...>.dataContext.public.usersEntity
SqlDataProvider<...>.dataContext.publicSchema.public.users.Create(data: System.Collections.Generic.IEnumerable<string * obj>) : SqlDataProvider<...>.dataContext.public.usersEntity


<summary>Item array of database columns:
email,password,role,username</summary>

SqlDataProvider<...>.dataContext.publicSchema.public.users.Create(email: string, password: string, role: string, username: string) : SqlDataProvider<...>.dataContext.public.usersEntity
val placeOrder : username:string -> ctx:DbContext -> Unit

Full name: SuaveMusicStore.Db.placeOrder
val carts : CartDetails list
val total : decimal
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val c : CartDetails
Multiple items
val decimal : value:'T -> decimal (requires member op_Explicit)

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

--------------------
type decimal = System.Decimal

Full name: Microsoft.FSharp.Core.decimal

--------------------
type decimal<'Measure> = decimal

Full name: Microsoft.FSharp.Core.decimal<_>
property SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Count: int


<summary> integer</summary>
property SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Price: decimal


<summary> numeric</summary>
val order : SqlDataProvider<...>.dataContext.public.ordersEntity
property SqlDataProvider<...>.dataContext.publicSchema.Orders: SqlDataProvider<...>.dataContext.publicSchema.public.orders


<summary> The base table orders belonging to schema public</summary>
SqlDataProvider<...>.dataContext.publicSchema.public.orders.Create() : SqlDataProvider<...>.dataContext.public.ordersEntity
SqlDataProvider<...>.dataContext.publicSchema.public.orders.Create(data: System.Collections.Generic.IEnumerable<string * obj>) : SqlDataProvider<...>.dataContext.public.ordersEntity


<summary>Item array of database columns:
orderdate,total</summary>

SqlDataProvider<...>.dataContext.publicSchema.public.orders.Create(orderdate: System.DateTime, total: decimal) : SqlDataProvider<...>.dataContext.public.ordersEntity
property SqlDataProvider<...>.dataContext.public.ordersEntity.Username: string


<summary> character varying(256)</summary>
val cart : CartDetails
val orderDetails : SqlDataProvider<...>.dataContext.public.orderdetailsEntity
property SqlDataProvider<...>.dataContext.publicSchema.Orderdetails: SqlDataProvider<...>.dataContext.publicSchema.public.orderdetails


<summary> The base table orderdetails belonging to schema public</summary>
SqlDataProvider<...>.dataContext.publicSchema.public.orderdetails.Create() : SqlDataProvider<...>.dataContext.public.orderdetailsEntity
SqlDataProvider<...>.dataContext.publicSchema.public.orderdetails.Create(data: System.Collections.Generic.IEnumerable<string * obj>) : SqlDataProvider<...>.dataContext.public.orderdetailsEntity


<summary>Item array of database columns:
albumid,orderid,quantity,unitprice</summary>

SqlDataProvider<...>.dataContext.publicSchema.public.orderdetails.Create(albumid: int, orderid: int, quantity: int, unitprice: decimal) : SqlDataProvider<...>.dataContext.public.orderdetailsEntity
property SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Albumid: int


<summary> integer</summary>
property SqlDataProvider<...>.dataContext.public.ordersEntity.Orderid: int


<summary> integer</summary>
module Option

from Microsoft.FSharp.Core
val iter : action:('T -> unit) -> option:'T option -> unit

Full name: Microsoft.FSharp.Core.Option.iter
type IntPath = PrintfFormat<(int -> string),unit,string,string,int>

Full name: SuaveMusicStore.Path.IntPath
Multiple items
type PrintfFormat<'Printer,'State,'Residue,'Result> =
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>
member Value : string

Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_>

--------------------
type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> =
inherit PrintfFormat<'Printer,'State,'Residue,'Result>
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>

Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_,_>

--------------------
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>

--------------------
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>
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<_>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val withParam : key:string * value:string -> path:string -> string

Full name: SuaveMusicStore.Path.withParam
val key : string
val value : string
val path : string
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val home : string

Full name: SuaveMusicStore.Path.home
val overview : string

Full name: SuaveMusicStore.Path.Store.overview
val browse : string

Full name: SuaveMusicStore.Path.Store.browse
val details : IntPath

Full name: SuaveMusicStore.Path.Store.details
val browseKey : string

Full name: SuaveMusicStore.Path.Store.browseKey
val manage : string

Full name: SuaveMusicStore.Path.Admin.manage
val createAlbum : string

Full name: SuaveMusicStore.Path.Admin.createAlbum
val editAlbum : IntPath

Full name: SuaveMusicStore.Path.Admin.editAlbum
val deleteAlbum : IntPath

Full name: SuaveMusicStore.Path.Admin.deleteAlbum
val logon : string

Full name: SuaveMusicStore.Path.Account.logon
val logoff : string

Full name: SuaveMusicStore.Path.Account.logoff
val register : string

Full name: SuaveMusicStore.Path.Account.register
module Cart

from SuaveMusicStore.Path
val overview : string

Full name: SuaveMusicStore.Path.Cart.overview
val addAlbum : IntPath

Full name: SuaveMusicStore.Path.Cart.addAlbum
val removeAlbum : IntPath

Full name: SuaveMusicStore.Path.Cart.removeAlbum
val checkout : string

Full name: SuaveMusicStore.Path.Cart.checkout
namespace Suave
module Form

from Suave
type Album =
{ArtistId: decimal;
GenreId: decimal;
Title: string;
Price: decimal;
ArtUrl: string;}

Full name: SuaveMusicStore.Form.Album
Album.ArtistId: decimal
Album.GenreId: decimal
Album.Title: string
Album.Price: decimal
Album.ArtUrl: string
val album : Form<Album>

Full name: SuaveMusicStore.Form.album
Multiple items
union case Form.Form: FormProp<'a> list * ServerSideValidation<'a> list -> Form<'a>

--------------------
type Form<'a> = | Form of FormProp<'a> list * ServerSideValidation<'a> list

Full name: Suave.Form.Form<_>
union case FormProp.TextProp: Property<'a,string> -> FormProp<'a>
val f : Album
val maxLength : max:int -> Validation<string>

Full name: Suave.Form.maxLength
union case FormProp.DecimalProp: Property<'a,decimal> -> FormProp<'a>
val min : min:decimal -> Validation<decimal>

Full name: Suave.Form.min
val max : max:decimal -> Validation<decimal>

Full name: Suave.Form.max
val step : step:System.Decimal -> Validation<decimal>

Full name: Suave.Form.step
type Logon =
{Username: string;
Password: Password;}

Full name: SuaveMusicStore.Form.Logon
Logon.Username: string
Multiple items
Logon.Password: Password

--------------------
type Password = | Password of string

Full name: Suave.Form.Password
val logon : Form<Logon>

Full name: SuaveMusicStore.Form.logon
type Register =
{Username: string;
Email: string;
Password: Password;
ConfirmPassword: Password;}

Full name: SuaveMusicStore.Form.Register
Register.Username: string
Register.Email: string
Multiple items
Register.Password: Password

--------------------
type Password = | Password of string

Full name: Suave.Form.Password
Register.ConfirmPassword: Password
Multiple items
union case Password.Password: string -> Password

--------------------
type Password = | Password of string

Full name: Suave.Form.Password
val pattern : Validation<Password>

Full name: SuaveMusicStore.Form.pattern
val passwordRegex : pattern:string -> Validation<Password>

Full name: Suave.Form.passwordRegex
val passwordsMatch : (Register -> bool) * string

Full name: SuaveMusicStore.Form.passwordsMatch
val f : Register
Register.Password: Password
val register : Form<Register>

Full name: SuaveMusicStore.Form.register
union case FormProp.PasswordProp: Property<'a,Password> -> FormProp<'a>
type Checkout =
{FirstName: string;
LastName: string;
Address: string;
PromoCode: string option;}

Full name: SuaveMusicStore.Form.Checkout
Checkout.FirstName: string
Checkout.LastName: string
Checkout.Address: string
Checkout.PromoCode: string option
Multiple items
val option : value:string -> txt:string -> selected:bool -> Suave.Html.Node

Full name: Suave.Form.option

--------------------
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val checkout : Form<Checkout>

Full name: SuaveMusicStore.Form.checkout
module Html

from Suave
val em : s:string -> Node

Full name: SuaveMusicStore.View.em
val s : string
val tag : tag:string -> attr:Attribute list -> contents:Node list -> Node

Full name: Suave.Html.tag
union case Node.Text: string -> Node
val cssLink : href:string -> Node

Full name: SuaveMusicStore.View.cssLink
val href : string
val link : attr:Attribute list -> Node

Full name: Suave.Html.link
val h2 : s:string -> Node

Full name: SuaveMusicStore.View.h2
val ul : nodes:Node list -> Node

Full name: SuaveMusicStore.View.ul
val nodes : Node list
val ulAttr : attr:Attribute list -> nodes:Node list -> Node

Full name: SuaveMusicStore.View.ulAttr
val attr : Attribute list
val li : (Node list -> Node)

Full name: SuaveMusicStore.View.li
val table : x:Node list -> Node

Full name: SuaveMusicStore.View.table
val x : Node list
val th : x:Node list -> Node

Full name: SuaveMusicStore.View.th
val tr : x:Node list -> Node

Full name: SuaveMusicStore.View.tr
val td : x:Node list -> Node

Full name: SuaveMusicStore.View.td
val strong : s:string -> Node

Full name: SuaveMusicStore.View.strong
val text : s:string -> Node list

Full name: Suave.Html.text
val form : x:Node list -> Node

Full name: SuaveMusicStore.View.form
val formInput : (('a -> Quotations.Expr<'b>) -> Attribute list -> Form<'a> -> Node)

Full name: SuaveMusicStore.View.formInput
val input : quotF:('a -> Quotations.Expr<'b>) -> attrs:Attribute list -> form:Form<'a> -> Node

Full name: Suave.Form.input
val submitInput : value:string -> Node

Full name: SuaveMusicStore.View.submitInput
val input : attr:Attribute list -> Node

Full name: Suave.Html.input
type Field<'a> =
{Label: string;
Html: Form<'a> -> Node;}

Full name: SuaveMusicStore.View.Field<_>
Field.Label: string
Multiple items
Field.Html: Form<'a> -> Node

--------------------
type HtmlAttribute = string * string

Full name: Suave.Form.HtmlAttribute
Multiple items
union case Form.Form: FormProp<'a> list * ServerSideValidation<'a> list -> Form<'a>

--------------------
module Form

from SuaveMusicStore

--------------------
type Form<'a> = | Form of FormProp<'a> list * ServerSideValidation<'a> list

Full name: Suave.Form.Form<_>
type Node =
| Element of Element * Node list
| VoidElement of Element
| Text of string
| Raw of string
| WhiteSpace of string

Full name: Suave.Html.Node
type Fieldset<'a> =
{Legend: string;
Fields: Field<'a> list;}

Full name: SuaveMusicStore.View.Fieldset<_>
Fieldset.Legend: string
Fieldset.Fields: Field<'a> list
type FormLayout<'a> =
{Fieldsets: Fieldset<'a> list;
SubmitText: string;
Form: Form<'a>;}

Full name: SuaveMusicStore.View.FormLayout<_>
FormLayout.Fieldsets: Fieldset<'a> list
FormLayout.SubmitText: string
Multiple items
FormLayout.Form: Form<'a>

--------------------
module Form

from SuaveMusicStore

--------------------
type Form<'a> = | Form of FormProp<'a> list * ServerSideValidation<'a> list

Full name: Suave.Form.Form<_>
val renderForm : layout:FormLayout<'a> -> Node

Full name: SuaveMusicStore.View.renderForm
val layout : FormLayout<'a>
val set : Fieldset<'a>
val field : Field<'a>
val div : (Attribute list -> Node list -> Node)

Full name: Suave.Html.div
Field.Html: Form<'a> -> Node
FormLayout.Form: Form<'a>
val home : bestSellers:Db.BestSeller list -> Node list

Full name: SuaveMusicStore.View.home
val bestSellers : Db.BestSeller list
module Db

from SuaveMusicStore
type BestSeller = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.bestsellersEntity

Full name: SuaveMusicStore.Db.BestSeller
val img : attr:Attribute list -> Node

Full name: Suave.Html.img
val album : Db.BestSeller
val a : href:string -> attr:Attribute list -> (Node list -> Node)

Full name: Suave.Html.a
module Path

from SuaveMusicStore
module Store

from SuaveMusicStore.Path
val details : Path.IntPath

Full name: SuaveMusicStore.Path.Store.details
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.bestsellersEntity.Albumid: int


<summary> integer</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.bestsellersEntity.Albumarturl: string


<summary> character varying(1024)</summary>
val span : (Attribute list -> Node list -> Node)

Full name: Suave.Html.span
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.bestsellersEntity.Title: string


<summary> character varying(160)</summary>
val store : genres:string list -> Node list

Full name: SuaveMusicStore.View.store
val genres : string list
val p : (Attribute list -> Node list -> Node)

Full name: Suave.Html.p
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val length : list:'T list -> int

Full name: Microsoft.FSharp.Collections.List.length
val genre : string
val url : string
val browse : genre:string -> albums:Db.Album list -> Node list

Full name: SuaveMusicStore.View.browse
val albums : Db.Album list
type Album = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity

Full name: SuaveMusicStore.Db.Album
val album : Db.Album
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Albumid: int


<summary> integer</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Albumarturl: string


<summary> character varying(1024)</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Title: string


<summary> character varying(160)</summary>
val details : album:Db.AlbumDetails -> Node list

Full name: SuaveMusicStore.View.details
val album : Db.AlbumDetails
type AlbumDetails = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity

Full name: SuaveMusicStore.Db.AlbumDetails
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Title: string


<summary> character varying(160)</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumarturl: string


<summary> character varying(1024)</summary>
val caption : string
val t : string
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Genre: string


<summary> character varying(120)</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Artist: string


<summary> character varying(120)</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Price: decimal


<summary> numeric</summary>
System.Decimal.ToString() : string
System.Decimal.ToString(provider: System.IFormatProvider) : string
System.Decimal.ToString(format: string) : string
System.Decimal.ToString(format: string, provider: System.IFormatProvider) : string
val addAlbum : Path.IntPath

Full name: SuaveMusicStore.Path.Cart.addAlbum
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumid: int


<summary> integer</summary>
val truncate : k:int -> s:string -> string

Full name: SuaveMusicStore.View.truncate
val k : int
property System.String.Length: int
System.String.Substring(startIndex: int) : string
System.String.Substring(startIndex: int, length: int) : string
val manage : albums:Db.AlbumDetails list -> Node list

Full name: SuaveMusicStore.View.manage
val albums : Db.AlbumDetails list
module Admin

from SuaveMusicStore.Path
val editAlbum : Path.IntPath

Full name: SuaveMusicStore.Path.Admin.editAlbum
val deleteAlbum : Path.IntPath

Full name: SuaveMusicStore.Path.Admin.deleteAlbum
val deleteAlbum : albumTitle:string -> Node list

Full name: SuaveMusicStore.View.deleteAlbum
val albumTitle : string
val br : attr:Attribute list -> Node

Full name: Suave.Html.br
val createAlbum : genres:(decimal * string) list -> artists:(decimal * string) list -> Node list

Full name: SuaveMusicStore.View.createAlbum
val genres : (decimal * string) list
val artists : (decimal * string) list
val album : Form<Form.Album>

Full name: SuaveMusicStore.Form.album
type HtmlAttribute = string * string

Full name: Suave.Form.HtmlAttribute
val selectInput : quotF:('a -> Quotations.Expr<'b>) -> options:('b * string) list -> selected:'b option -> form:Form<'a> -> Node (requires equality)

Full name: Suave.Form.selectInput
val f : Form.Album
Form.Album.GenreId: decimal
Form.Album.ArtistId: decimal
Form.Album.Title: string
Form.Album.Price: decimal
Form.Album.ArtUrl: string
val editAlbum : album:Db.Album -> genres:(decimal * string) list -> artists:(decimal * string) list -> Node list

Full name: SuaveMusicStore.View.editAlbum
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Genreid: int


<summary> integer</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Artistid: int


<summary> integer</summary>
val formatDec : d:System.Decimal -> string

Full name: Suave.Form.formatDec
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Price: decimal


<summary> numeric</summary>
val logon : msg:string -> Node list

Full name: SuaveMusicStore.View.logon
val msg : string
module Account

from SuaveMusicStore.Path
val logon : Form<Form.Logon>

Full name: SuaveMusicStore.Form.logon
val f : Form.Logon
Form.Logon.Username: string
Form.Logon.Password: Password
val notFound : Node list

Full name: SuaveMusicStore.View.notFound
val partNav : cartItems:int -> Node

Full name: SuaveMusicStore.View.partNav
val cartItems : int
val partUser : user:string option -> Node

Full name: SuaveMusicStore.View.partUser
val user : string option
Multiple items
val option : value:string -> txt:string -> selected:bool -> Node

Full name: Suave.Form.option

--------------------
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val user : string
val partGenres : genres:Db.Genre list -> Node

Full name: SuaveMusicStore.View.partGenres
val genres : Db.Genre list
type Genre = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.genresEntity

Full name: SuaveMusicStore.Db.Genre
val genre : Db.Genre
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.genresEntity.Name: string


<summary> character varying(120)</summary>
val emptyCart : Node list

Full name: SuaveMusicStore.View.emptyCart
val nonEmptyCart : carts:Db.CartDetails list -> Node list

Full name: SuaveMusicStore.View.nonEmptyCart
val carts : Db.CartDetails list
type CartDetails = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.cartdetailsEntity

Full name: SuaveMusicStore.Db.CartDetails
val h : string
val cart : Db.CartDetails
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Albumid: int


<summary> integer</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Albumtitle: string


<summary> character varying(160)</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Price: decimal


<summary> numeric</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.cartdetailsEntity.Count: int


<summary> integer</summary>
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
val c : Db.CartDetails
val d : string
val script : (Attribute list -> Node list -> Node)

Full name: Suave.Html.script
val cart : _arg1:Db.CartDetails list -> Node list

Full name: SuaveMusicStore.View.cart
Multiple items
val list : Db.CartDetails list

--------------------
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val register : msg:string -> Node list

Full name: SuaveMusicStore.View.register
val register : Form<Form.Register>

Full name: SuaveMusicStore.Form.register
val f : Form.Register
Form.Register.Username: string
Form.Register.Email: string
Form.Register.Password: Password
Form.Register.ConfirmPassword: Password
val checkout : Node list

Full name: SuaveMusicStore.View.checkout
val checkout : Form<Form.Checkout>

Full name: SuaveMusicStore.Form.checkout
val f : Form.Checkout
Form.Checkout.FirstName: string
Form.Checkout.LastName: string
Form.Checkout.Address: string
Form.Checkout.PromoCode: string option
val checkoutComplete : Node list

Full name: SuaveMusicStore.View.checkoutComplete
val index : partNav:Node -> partUser:Node -> partGenres:Node -> container:Node list -> string

Full name: SuaveMusicStore.View.index
val partNav : Node
val partUser : Node
val partGenres : Node
val container : Node list
val html : (Attribute list -> Node list -> Node)

Full name: Suave.Html.html
val head : (Attribute list -> Node list -> Node)

Full name: Suave.Html.head
val title : attr:Attribute list -> s:string -> Node

Full name: Suave.Html.title
val body : (Attribute list -> Node list -> Node)

Full name: Suave.Html.body
val htmlToString : node:Node -> string

Full name: Suave.Html.htmlToString
module App

from SuaveMusicStore
module Authentication

from Suave
module Cookie

from Suave
module Filters

from Suave
module Model

from Suave
module Binding

from Suave.Model
module Operators

from Suave
module RequestErrors

from Suave
module State

from Suave
module CookieStateStore

from Suave.State
module Successful

from Suave
module Web

from Suave
type UserLoggedOnSession =
{Username: string;
Role: string;}

Full name: SuaveMusicStore.App.UserLoggedOnSession
UserLoggedOnSession.Username: string
Multiple items
val string : value:'T -> string

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

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

Full name: Microsoft.FSharp.Core.string
UserLoggedOnSession.Role: string
Multiple items
union case CookieLife.Session: CookieLife

--------------------
type Session =
| NoSession
| CartIdOnly of string
| UserLoggedOn of UserLoggedOnSession

Full name: SuaveMusicStore.App.Session
union case Session.NoSession: Session
union case Session.CartIdOnly: string -> Session
union case Session.UserLoggedOn: UserLoggedOnSession -> Session
val session : f:(Session -> HttpContext -> Async<'a option>) -> (HttpContext -> Async<'a option>)

Full name: SuaveMusicStore.App.session
val f : (Session -> HttpContext -> Async<'a option>)
val statefulForSession : WebPart

Full name: Suave.State.CookieStateStore.statefulForSession
val context : apply:(HttpContext -> HttpContext -> 'a) -> context:HttpContext -> 'a

Full name: Suave.Http.context
val x : HttpContext
Multiple items
module HttpContext

from Suave.State.CookieStateStore

--------------------
module HttpContext

from Suave.Authentication

--------------------
module HttpContext

from Suave.Http

--------------------
type HttpContext =
{request: HttpRequest;
runtime: HttpRuntime;
connection: Connection;
userState: Map<string,obj>;
response: HttpResult;}
member clientIp : trustProxy:bool -> sources:string list -> IPAddress
member clientPort : trustProxy:bool -> sources:string list -> Port
member clientProto : trustProxy:bool -> sources:string list -> string
member clientIpTrustProxy : IPAddress
member clientPortTrustProxy : Port
member clientProtoTrustProxy : string
member isLocal : bool
static member clientIp_ : Property<HttpContext,IPAddress>
static member clientPort_ : Property<HttpContext,Port>
static member clientProto_ : Property<HttpContext,string>
static member connection_ : Property<HttpContext,Connection>
static member isLocal_ : Property<HttpContext,bool>
static member request_ : Property<HttpContext,HttpRequest>
static member response_ : Property<HttpContext,HttpResult>
static member runtime_ : Property<HttpContext,HttpRuntime>
static member userState_ : Property<HttpContext,Map<string,obj>>

Full name: Suave.Http.HttpContext
val state : ctx:HttpContext -> State.StateStore option

Full name: Suave.State.CookieStateStore.HttpContext.state
val state : State.StateStore
abstract member State.StateStore.get : string -> 'T option
val role : string
val html : container:Html.Node list -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.html
val container : Html.Node list
val ctx : FSharp.Data.Sql.SqlDataProvider<...>.dataContext
val getContext : unit -> FSharp.Data.Sql.SqlDataProvider<...>.dataContext

Full name: SuaveMusicStore.Db.getContext
val result : (int -> string option -> HttpContext -> Async<HttpContext option>)
val OK : body:string -> WebPart

Full name: Suave.Successful.OK
module View

from SuaveMusicStore
val index : partNav:Html.Node -> partUser:Html.Node -> partGenres:Html.Node -> container:Html.Node list -> string

Full name: SuaveMusicStore.View.index
val partNav : cartItems:int -> Html.Node

Full name: SuaveMusicStore.View.partNav
val partUser : user:string option -> Html.Node

Full name: SuaveMusicStore.View.partUser
val partGenres : genres:Db.Genre list -> Html.Node

Full name: SuaveMusicStore.View.partGenres
val getGenres : ctx:Db.DbContext -> Db.Genre list

Full name: SuaveMusicStore.Db.getGenres
module Writers

from Suave
val setMimeType : mimeType:string -> WebPart

Full name: Suave.Writers.setMimeType
val items : int
val getCartsDetails : cartId:string -> ctx:Db.DbContext -> Db.CartDetails list

Full name: SuaveMusicStore.Db.getCartsDetails
val home : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.home
val warbler : f:('t -> 't -> 'u) -> 't -> 'u

Full name: Suave.WebPart.warbler
val bestsellers : Db.BestSeller list
val getBestSellers : ctx:Db.DbContext -> Db.BestSeller list

Full name: SuaveMusicStore.Db.getBestSellers
val home : bestSellers:Db.BestSeller list -> Html.Node list

Full name: SuaveMusicStore.View.home
val browse : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.browse
val request : apply:(HttpRequest -> HttpContext -> 'a) -> context:HttpContext -> 'a

Full name: Suave.Http.request
val r : HttpRequest
member HttpRequest.queryParam : key:string -> Choice<string,string>
union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
val getAlbumsForGenre : genreName:string -> ctx:Db.DbContext -> Db.Album list

Full name: SuaveMusicStore.Db.getAlbumsForGenre
val browse : genre:string -> albums:Db.Album list -> Html.Node list

Full name: SuaveMusicStore.View.browse
union case Choice.Choice2Of2: 'T2 -> Choice<'T1,'T2>
val BAD_REQUEST : body:string -> WebPart

Full name: Suave.RequestErrors.BAD_REQUEST
val overview : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.overview
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val g : Db.Genre
val store : genres:string list -> Html.Node list

Full name: SuaveMusicStore.View.store
val details : id:int -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.details
val getAlbumDetails : id:int -> ctx:Db.DbContext -> Db.AlbumDetails option

Full name: SuaveMusicStore.Db.getAlbumDetails
val details : album:Db.AlbumDetails -> Html.Node list

Full name: SuaveMusicStore.View.details
val never : WebPart<'a>

Full name: Suave.WebPart.never
val manage : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.manage
val getAlbumsDetails : ctx:Db.DbContext -> Db.AlbumDetails list

Full name: SuaveMusicStore.Db.getAlbumsDetails
val manage : albums:Db.AlbumDetails list -> Html.Node list

Full name: SuaveMusicStore.View.manage
val bindToForm : form:Form<'a> -> handler:('a -> HttpContext -> Async<HttpContext option>) -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.bindToForm
val form : Form<'a>
val handler : ('a -> HttpContext -> Async<HttpContext option>)
val bindReq : f:(HttpRequest -> Choice<'b,'c>) -> fCont:('b -> HttpContext -> 'd) -> fErr:('c -> HttpContext -> 'd) -> (HttpContext -> 'd)

Full name: Suave.Model.Binding.bindReq
val bindForm : form:Form<'a> -> req:HttpRequest -> Choice<'a,string>

Full name: Suave.Form.bindForm
val createAlbum : WebPart<HttpContext>

Full name: SuaveMusicStore.App.createAlbum
val choose : options:WebPart<'a> list -> WebPart<'a>

Full name: Suave.WebPart.choose
val GET : WebPart

Full name: Suave.Filters.GET
Multiple items
val decimal : value:'T -> decimal (requires member op_Explicit)

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

--------------------
type decimal = Decimal

Full name: Microsoft.FSharp.Core.decimal

--------------------
type decimal<'Measure> = decimal

Full name: Microsoft.FSharp.Core.decimal<_>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.genresEntity.Genreid: int


<summary> integer</summary>
val getArtists : ctx:Db.DbContext -> Db.Artist list

Full name: SuaveMusicStore.Db.getArtists
val g : Db.Artist
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.artistsEntity.Artistid: int


<summary> integer</summary>
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.artistsEntity.Name: string


<summary> character varying(120)</summary>
val createAlbum : genres:(decimal * string) list -> artists:(decimal * string) list -> Html.Node list

Full name: SuaveMusicStore.View.createAlbum
val POST : WebPart

Full name: Suave.Filters.POST
Multiple items
union case Form.Form: FormProp<'a> list * ServerSideValidation<'a> list -> Form<'a>

--------------------
module Form

from Suave

--------------------
module Form

from SuaveMusicStore

--------------------
type Form<'a> = | Form of FormProp<'a> list * ServerSideValidation<'a> list

Full name: Suave.Form.Form<_>
val form : Form.Album
val createAlbum : artistId:int * genreId:int * price:decimal * title:string -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.createAlbum
module Redirection

from Suave
val FOUND : location:string -> WebPart

Full name: Suave.Redirection.FOUND
val editAlbum : id:int -> WebPart<HttpContext>

Full name: SuaveMusicStore.App.editAlbum
val getAlbum : id:int -> ctx:Db.DbContext -> Db.Album option

Full name: SuaveMusicStore.Db.getAlbum
val editAlbum : album:Db.Album -> genres:(decimal * string) list -> artists:(decimal * string) list -> Html.Node list

Full name: SuaveMusicStore.View.editAlbum
val updateAlbum : album:Db.Album -> artistId:int * genreId:int * price:decimal * title:string -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.updateAlbum
val deleteAlbum : id:int -> WebPart<HttpContext>

Full name: SuaveMusicStore.App.deleteAlbum
val deleteAlbum : albumTitle:string -> Html.Node list

Full name: SuaveMusicStore.View.deleteAlbum
val deleteAlbum : album:Db.Album -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.deleteAlbum
val passHash : pass:string -> string

Full name: SuaveMusicStore.App.passHash
val pass : string
val sha : Security.Cryptography.SHA256
namespace System.Security
namespace System.Security.Cryptography
type SHA256 =
inherit HashAlgorithm
static member Create : unit -> SHA256 + 1 overload

Full name: System.Security.Cryptography.SHA256
Security.Cryptography.SHA256.Create() : Security.Cryptography.SHA256
Security.Cryptography.SHA256.Create(hashName: string) : Security.Cryptography.SHA256
namespace System.Text
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...

Full name: System.Text.Encoding
property Text.Encoding.UTF8: Text.Encoding
Text.Encoding.GetBytes(s: string) : byte []
Text.Encoding.GetBytes(chars: char []) : byte []
Text.Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Text.Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Text.Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Text.Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte []) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(inputStream: IO.Stream) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte [], offset: int, count: int) : byte []
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...

Full name: System.Array
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val b : byte
Byte.ToString() : string
Byte.ToString(provider: IFormatProvider) : string
Byte.ToString(format: string) : string
Byte.ToString(format: string, provider: IFormatProvider) : string
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val concat : sep:string -> strings:seq<string> -> string

Full name: Microsoft.FSharp.Core.String.concat
val sessionStore : setF:(State.StateStore -> HttpContext -> Async<HttpContext option>) -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.sessionStore
val setF : (State.StateStore -> HttpContext -> Async<HttpContext option>)
val returnPathOrHome : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.returnPathOrHome
val x : HttpRequest
val authenticateUser : user:Db.User -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.authenticateUser
val user : Db.User
type User = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.usersEntity

Full name: SuaveMusicStore.Db.User
val authenticated : relativeExpiry:CookieLife -> secure:bool -> WebPart

Full name: Suave.Authentication.authenticated
type CookieLife =
| Session
| MaxAge of duration: TimeSpan

Full name: Suave.Cookie.CookieLife
union case CookieLife.Session: CookieLife
val upgradeCarts : cartId:string * username:string -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.upgradeCarts
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.usersEntity.Username: string


<summary> character varying(200)</summary>
val store : State.StateStore
abstract member State.StateStore.set : string -> 'T -> WebPart
val succeed : WebPart<'a>

Full name: Suave.WebPart.succeed
property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.usersEntity.Role: string


<summary> character varying(50)</summary>
val logon : WebPart<HttpContext>

Full name: SuaveMusicStore.App.logon
val logon : msg:string -> Html.Node list

Full name: SuaveMusicStore.View.logon
val form : Form.Logon
val validateUser : username:string * password:string -> ctx:Db.DbContext -> Db.User option

Full name: SuaveMusicStore.Db.validateUser
val register : WebPart<HttpContext>

Full name: SuaveMusicStore.App.register
val register : msg:string -> Html.Node list

Full name: SuaveMusicStore.View.register
val form : Form.Register
val getUser : username:string -> ctx:Db.DbContext -> Db.User option

Full name: SuaveMusicStore.Db.getUser
val existing : Db.User
val user : FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.usersEntity
val newUser : username:string * password:string * email:string -> ctx:Db.DbContext -> FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.usersEntity

Full name: SuaveMusicStore.Db.newUser
val reset : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.reset
val unsetPair : httpCookieName:string -> WebPart

Full name: Suave.Cookie.unsetPair
val SessionAuthCookie : string

Full name: Suave.Authentication.SessionAuthCookie
val StateCookie : string

Full name: Suave.State.CookieStateStore.StateCookie
val redirectWithReturnPath : redirection:string -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.redirectWithReturnPath
val redirection : string
HttpRequest.url: Uri
property Uri.AbsolutePath: string
val loggedOn : f_success:WebPart -> WebPart

Full name: SuaveMusicStore.App.loggedOn
val f_success : WebPart
val authenticate : relativeExpiry:CookieLife -> secure:bool -> missingCookie:(unit -> Choice<byte [],WebPart>) -> decryptionFailure:(Utils.Crypto.SecretboxDecryptionError -> Choice<byte [],WebPart>) -> fSuccess:WebPart -> WebPart

Full name: Suave.Authentication.authenticate
val admin : f_success:(HttpContext -> Async<HttpContext option>) -> WebPart

Full name: SuaveMusicStore.App.admin
val f_success : (HttpContext -> Async<HttpContext option>)
val FORBIDDEN : body:string -> WebPart

Full name: Suave.RequestErrors.FORBIDDEN
val UNAUTHORIZED : body:string -> WebPart

Full name: Suave.RequestErrors.UNAUTHORIZED
val cart : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.cart
val emptyCart : Html.Node list

Full name: SuaveMusicStore.View.emptyCart
val cart : _arg1:Db.CartDetails list -> Html.Node list

Full name: SuaveMusicStore.View.cart
val addToCart : albumId:int -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.addToCart
Multiple items
type Guid =
struct
new : b:byte[] -> Guid + 4 overloads
member CompareTo : value:obj -> int + 1 overload
member Equals : o:obj -> bool + 1 overload
member GetHashCode : unit -> int
member ToByteArray : unit -> byte[]
member ToString : unit -> string + 2 overloads
static val Empty : Guid
static member NewGuid : unit -> Guid
static member Parse : input:string -> Guid
static member ParseExact : input:string * format:string -> Guid
...
end

Full name: System.Guid

--------------------
Guid()
Guid(b: byte []) : unit
Guid(g: string) : unit
Guid(a: int, b: int16, c: int16, d: byte []) : unit
Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
Guid.NewGuid() : Guid
val addToCart : cartId:string -> albumId:int -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.addToCart
val removeFromCart : albumId:int -> (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.removeFromCart
val getCart : cartId:string -> albumId:int -> ctx:Db.DbContext -> Db.Cart option

Full name: SuaveMusicStore.Db.getCart
val cart : Db.Cart
val removeFromCart : cart:Db.Cart -> albumId:'a -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.removeFromCart
Multiple items
module Html

from Suave

--------------------
type HtmlAttribute = string * string

Full name: Suave.Form.HtmlAttribute
val htmlToString : node:Html.Node -> string

Full name: Suave.Html.htmlToString
val checkout : (HttpContext -> Async<HttpContext option>)

Full name: SuaveMusicStore.App.checkout
val checkout : Html.Node list

Full name: SuaveMusicStore.View.checkout
val placeOrder : username:string -> ctx:Db.DbContext -> Unit

Full name: SuaveMusicStore.Db.placeOrder
val checkoutComplete : Html.Node list

Full name: SuaveMusicStore.View.checkoutComplete
val webPart : WebPart<HttpContext>

Full name: SuaveMusicStore.App.webPart
val path : pathAfterDomain:string -> WebPart

Full name: Suave.Filters.path
val pathScan : pf:PrintfFormat<'a,'b,'c,'d,'t> -> h:('t -> WebPart) -> WebPart

Full name: Suave.Filters.pathScan
val removeAlbum : Path.IntPath

Full name: SuaveMusicStore.Path.Cart.removeAlbum
val pathRegex : pathAfterDomainRegex:string -> WebPart

Full name: Suave.Filters.pathRegex
module Files

from Suave
val browseHome : WebPart

Full name: Suave.Files.browseHome
val notFound : Html.Node list

Full name: SuaveMusicStore.View.notFound
val cfg : SuaveConfig

Full name: SuaveMusicStore.App.cfg
val defaultConfig : SuaveConfig

Full name: Suave.Web.defaultConfig
Multiple items
module HttpBinding

from Suave.Http

--------------------
type HttpBinding =
{scheme: Protocol;
socketBinding: SocketBinding;}
override ToString : unit -> string
member uri : path:string -> query:string -> Uri
static member scheme_ : Property<HttpBinding,Protocol>
static member socketBinding_ : Property<HttpBinding,SocketBinding>

Full name: Suave.Http.HttpBinding
val createSimple : scheme:Protocol -> ip:string -> port:int -> HttpBinding

Full name: Suave.Http.HttpBinding.createSimple
union case Protocol.HTTP: Protocol
val startWebServer : config:SuaveConfig -> webpart:WebPart -> unit

Full name: Suave.Web.startWebServer

Show code from this section on GitHub

results matching ""

    No results matching ""