Album details
It's time to read album's details from the database.
Start by adjusting the details
in View
module:
View.fs
37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: |
|
Above snippet requires defining one more helper functions in View
:
View.fs
5:
|
|
In the details
function we used list comprehension syntax with an inline list of tuples (["Genre:",album.Genre;...
).
This is just to save us some time from typing the p
element three times for all those properties.
You're welcome to change the implementation so that it doesn't use this shortcut if you like.
The AlbumDetails
database view turns out to be handy now, because we can use all the attributes we need in a single step (no explicit joins required).
To read the album's details in App
module we can do following:
App.fs
30: 31: 32: 33: 34: 35: |
|
App.fs
42:
|
|
A few remarks regarding above snippet:
details
takesid
as parameter and returns WebPartPath.Store.details
of type IntPath guarantees type safetyDb.getAlbumDetails
can returnNone
if no album with given id is found- If an album is found, html WebPart with the
View.details
container is returned - If no album is found,
None
WebPart is returned with help ofnever
.
No pipe operator was used this time, but as an exercise you can think of how you could apply it to the details
WebPart.
Before testing the app, add the "placeholder.gif" image asset.
You can download it from here.
Don't forget to set "Copy To Output Directory", as well as add new file extension to the pathRegex
in App
module.
namespace FSharp
--------------------
namespace Microsoft.FSharp
namespace FSharp.Data
--------------------
namespace Microsoft.FSharp.Data
type LiteralAttribute =
inherit Attribute
new : unit -> LiteralAttribute
Full name: Microsoft.FSharp.Core.LiteralAttribute
--------------------
new : unit -> LiteralAttribute
Full name: SuaveMusicStore.Db.ConnectionString
Full name: SuaveMusicStore.Db.Sql
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>
| MSSQLSERVER = 0
| SQLITE = 1
| POSTGRESQL = 2
| MYSQL = 3
| ORACLE = 4
| MSACCESS = 5
| ODBC = 6
| FIREBIRD = 7
Full name: FSharp.Data.Sql.Common.DatabaseProviderTypes
| ORIGINAL = 0
| TOUPPER = 1
| TOLOWER = 2
Full name: FSharp.Data.Sql.Common.CaseSensitivityChange
Full name: SuaveMusicStore.Db.DbContext
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
Full name: SuaveMusicStore.Db.Album
Full name: SuaveMusicStore.Db.Genre
Full name: SuaveMusicStore.Db.AlbumDetails
Full name: SuaveMusicStore.Db.getContext
<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>
Full name: SuaveMusicStore.Db.getGenres
Full name: Microsoft.FSharp.Collections.list<_>
<summary> The base table genres belonging to schema public</summary>
module Seq
from FSharp.Data.Sql
--------------------
module Seq
from Microsoft.FSharp.Collections
Full name: Microsoft.FSharp.Collections.Seq.toList
Full name: SuaveMusicStore.Db.getAlbumsForGenre
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
<summary> The base table albums belonging to schema public</summary>
Calls Linq.QueryBuilder.Join
<summary> integer</summary>
Calls Linq.QueryBuilder.Where
<summary> character varying(120)</summary>
Calls Linq.QueryBuilder.Select
Full name: SuaveMusicStore.Db.getAlbumDetails
Full name: Microsoft.FSharp.Core.option<_>
<summary> The view albumdetails belonging to schema public</summary>
<summary> integer</summary>
Full name: Microsoft.FSharp.Collections.Seq.tryHead
Full name: SuaveMusicStore.Path.IntPath
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>
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<_>
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
Full name: Microsoft.FSharp.Core.unit
Full name: SuaveMusicStore.Path.withParam
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
Full name: SuaveMusicStore.Path.home
from SuaveMusicStore.Path
Full name: SuaveMusicStore.Path.Store.overview
Full name: SuaveMusicStore.Path.Store.browse
Full name: SuaveMusicStore.Path.Store.details
Full name: SuaveMusicStore.Path.Store.browseKey
from Suave
Full name: SuaveMusicStore.View.em
Full name: Suave.Html.tag
Full name: SuaveMusicStore.View.cssLink
Full name: Suave.Html.link
Full name: SuaveMusicStore.View.h2
Full name: SuaveMusicStore.View.ul
Full name: SuaveMusicStore.View.li
Full name: SuaveMusicStore.View.home
Full name: SuaveMusicStore.View.store
Full name: Suave.Html.p
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<_>
Full name: Microsoft.FSharp.Collections.List.length
from SuaveMusicStore
Full name: Suave.Html.a
Full name: SuaveMusicStore.View.browse
from SuaveMusicStore
Full name: SuaveMusicStore.Db.Album
Full name: SuaveMusicStore.Path.Store.details
<summary> integer</summary>
<summary> character varying(160)</summary>
Full name: SuaveMusicStore.View.details
Full name: SuaveMusicStore.Db.AlbumDetails
<summary> character varying(160)</summary>
Full name: Suave.Html.img
<summary> character varying(1024)</summary>
Full name: Suave.Html.div
<summary> character varying(120)</summary>
<summary> character varying(120)</summary>
<summary> numeric</summary>
System.Decimal.ToString(provider: System.IFormatProvider) : string
System.Decimal.ToString(format: string) : string
System.Decimal.ToString(format: string, provider: System.IFormatProvider) : string
Full name: SuaveMusicStore.View.index
Full name: Suave.Html.html
Full name: Suave.Html.head
Full name: Suave.Html.title
Full name: Suave.Html.body
Full name: Suave.Html.htmlToString
from SuaveMusicStore
from Suave
from Suave
from Suave
from Suave
from Suave
Full name: SuaveMusicStore.App.html
Full name: Suave.Successful.OK
from SuaveMusicStore
Full name: SuaveMusicStore.View.index
Full name: SuaveMusicStore.App.browse
Full name: Suave.Http.request
Full name: SuaveMusicStore.Db.getContext
Full name: SuaveMusicStore.Db.getAlbumsForGenre
Full name: SuaveMusicStore.View.browse
Full name: Suave.RequestErrors.BAD_REQUEST
Full name: SuaveMusicStore.App.overview
Full name: Suave.WebPart.warbler
Full name: SuaveMusicStore.Db.getGenres
Full name: Microsoft.FSharp.Collections.List.map
<summary> character varying(120)</summary>
Full name: SuaveMusicStore.View.store
Full name: SuaveMusicStore.App.details
Full name: SuaveMusicStore.Db.getAlbumDetails
Full name: SuaveMusicStore.View.details
Full name: Suave.WebPart.never
Full name: SuaveMusicStore.App.webPart
Full name: Suave.WebPart.choose
Full name: Suave.Filters.path
Full name: SuaveMusicStore.View.home
Full name: Suave.Filters.pathScan
Full name: Suave.Filters.pathRegex
from Suave
Full name: Suave.Files.browseHome
Full name: Suave.Web.startWebServer
Full name: Suave.Web.defaultConfig
Show code from this section on GitHub