• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
SQL Provider

SQL Provider



Slides from the talk at Skillsmatter on my F# erasing SQL provider

Slides from the talk at Skillsmatter on my F# erasing SQL provider




Total Views
Views on SlideShare
Embed Views



2 Embeds 22

https://twitter.com 17
http://lanyrd.com 5



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    SQL Provider SQL Provider Presentation Transcript

    • SQL Type Provider Ross McKinlay, January 2014 @pezi_pink www.pinksquirrellabs.com github.com/pezipink/sqlprovider
    • But….. We already have a SQL type provider!!!
    • • Only supports SQL Server • Supports any number of database vendors • Uses SQLMetal.exe to generate code • No code generation step • Is not really an erasing type provider, doesn’t scale • Fully erasing type provider, can scale to massive schemas • Is closed source • Completely open source! • Has very limited extensibility points • Pluggable back end, and open source. Go WILD! • Supports a limited set of LINQ functions (currently) • Constraint navigation and querying, “dot individuals” • Supports almost all LINQ functions • Limited schema exploration mechanics
    • SqlProvider Features • Instant access to a variety of database vendors with no code generation step • Lazily evaluated metadata enabling scaling to large schemas • LINQ queries, presently with the following supported keywords : – select, select many(for), join, distinct, where, take (top), exactlyOne (single), sortBy, sortByDescending, thenBy, thenByDescending • “Dot Individuals” allowing you to directly view the rows of the database as static types via intelliense • Schema navigation – you can directly enumerate over the constraints of an entity – no need to understand the relational design of the database up front to perform joins • Custom operators suc as in In |=| and Like =% • F# Option types can be used for nullable columns • Stored procedures (well, sort of, support for this isn’t great yet!) • Currently support for MS SQL Server SQLite, Postgresql • Debugging hooks
    • Compile Time Schema Metadata Provided Types Execution Time ISqlProvider Quotations Type Provider LINQ SQL Entity DataContext
    • Entity Attributes (Columns) Schema Metadata Provided Types Employee Id, Name, etc Company Id, Address, etc Erased Type SqlEntity KeyValue Pairs Order Id, Amount, etc
    • Entity Relationships (Constraints) Schema Metadata Provided Types Employee { FK Company –> Employee } Company { FK Company –> Employee } { FK Company -> Order } Constraint information Static DataContext Order {FK Company -> Order }
    • Am I a compiler? Yes. Pretty much. RUNTIME Project Results LINQ AST Execute Query SQL AST Generate SQL SQL Query Type Optimise ISqlProvider LINQ Expression
    • LINQ Expression Trees!
    • Nested Active Patterns! | MethodCall(None, (MethodWithName "Join"), [createRelated Convert(MethodCall(_, (MethodWithName "_CreateEntities"), [String destEntity] )) OptionalQuote (Lambda([ParamName sourceAlias],SqlColumnGet(sourceTi,sourceKey,_))) OptionalQuote (Lambda([ParamName destAlias],SqlColumnGet(destTi,destKey,_))) OptionalQuote (Lambda(projectionParams,_))]) -> | OptionalOuterJoin(outerJoin, MethodCall(None,(MethodWithName "_CreateRelated"), [param; _; String PE; String PK; String FE; String FK; String IE; RelDirection dir;])) -> | MethodCall(Some(ParamName name | PropertyGet(_,PropName name)), (MethodWithName "GetColumn"),[String key]) ->
    • Projection Analysis and transformation steps are applied to the LINQ projection expression; 1) To extract fields that have been explicitly been selected so they can be used to construct a sensible query where possible 2) Entity access nodes are replaced with calls to GetSubEntity() which performs the magic allowing it to seem as if using an ORM, when in reality each row’s data is stored in one master SqlEntity SqlEntity A SqlEntity C GetSubEntity(a) DataRow (SqlEntity) SqlEntity B GetSubEntity(b) GetSubEntity(c) a.Name b.Addr1 b.Addr2 a.Title c.Id c.Amount a.Phone b.Addr2
    • Extensibility via ADO.NET All you need to do is implement most of this interface! WHAT COULD BE SIMPLER!  type internal ISqlProvider = abstract CreateConnection : string -> IDbConnection abstract CreateCommand : IDbConnection * string -> IDbCommand abstract CreateCommandParameter : string * obj * SqlDbType option -> IDataParameter abstract CreateTypeMappings : IDbConnection -> Unit abstract ClrToEnum : (string -> SqlDbType option) with get abstract SqlToEnum : (string -> SqlDbType option) with get abstract SqlToClr : (string -> Type option) with get abstract GetTables : IDbConnection -> Table list abstract GetColumns : IDbConnection * Table -> Column list abstract GetPrimaryKey : Table -> string option abstract GetRelationships : IDbConnection * Table -> (Relationship list * Relationship list) abstract GetSprocs : IDbConnection -> Sproc list abstract GenerateQueryText : SqlQuery * string * Table * Dictionary<string,ResizeArray<string>> -> string * ResizeArray<IDataParameter> ^ Of course, this last one is the kicker… but thankfully you can largely just copy and paste from an existing provider 
    • Questions ¿