@@ -1,11 +1,204 @@
1## RELEASE NOTES
1## RELEASE NOTES
3−### Version 0.3.0.0 - June 23, 2018
3+### Version 0.3 - June 23, 2018
5−**Changes**
5+Version 0.3 of Squeal adds views as well as composite and enumerated types to Squeal.
6+To support these features, a new kind `SchemumType` was added.
15+As a consequence, you will have to update your schema definitions like so:
21+ '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
22+ '[ "id" ::: 'Def :=> 'NotNull 'PGint4
23+ , "name" ::: 'NoDef :=> 'NotNull 'PGtext
29+ '[ "users" ::: 'Table (
30+ '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
31+ '[ "id" ::: 'Def :=> 'NotNull 'PGint4
32+ , "name" ::: 'NoDef :=> 'NotNull 'PGtext
6−- **Views** - Create, drop and query views
39+You can now create, drop, and query views.
7−- **Enums, Composites** - Create, drop and marshal enumerated and composite types
40+
8−- **Bugfixes**
41+```Haskell
44+ ('[] :: TableConstraints) :=>
45+ '[ "a" ::: 'NoDef :=> 'Null 'PGint4
46+ , "b" ::: 'NoDef :=> 'Null 'PGint4
47+ , "c" ::: 'NoDef :=> 'Null 'PGint4
50+ '[ "b" ::: 'Null 'PGint4
51+ , "c" ::: 'Null 'PGint4
57+ definition :: Definition '["abc" ::: 'Table ABC ] '["abc" ::: 'Table ABC, "bc" ::: 'View BC]
58+ definition = createView #bc (select (#b :* #c :* Nil) (from (table #abc)))
59+in printSQL definition
61+CREATE VIEW "bc" AS SELECT "b" AS "b", "c" AS "c" FROM "abc" AS "abc";
65+ definition :: Definition '["abc" ::: 'Table ABC, "bc" ::: 'View BC] '["abc" ::: 'Table ABC]
66+ definition = dropView #bc
67+in printSQL definition
73+ query :: Query '["abc" ::: 'Table ABC, "bc" ::: 'View BC] '[] BC
74+ query = selectStar (from (view #bc))
77+SELECT * FROM "bc" AS "bc"
82+PostgreSQL has a powerful type system. It even allows for user defined types.
83+For instance, you can define enumerated types which are data types that comprise
84+a static, ordered set of values. They are equivalent to Haskell algebraic data
85+types whose constructors are nullary. An example of an enum type might be the days of the week,
86+or a set of status values for a piece of data.
88+Enumerated types are created using the `createTypeEnum` command, for example:
93+ definition :: Definition '[] '["mood" ::: 'Typedef ('PGenum '["sad", "ok", "happy"])]
94+ definition = createTypeEnum #mood (label @"sad" :* label @"ok" :* label @"happy" :* Nil)
96+>>> printSQL definition
97+CREATE TYPE "mood" AS ENUM ('sad', 'ok', 'happy');
100+Enumerated types can also be generated from a Haskell algbraic data type with nullary constructors, for example:
103+>>> data Schwarma = Beef | Lamb | Chicken deriving GHC.Generic
104+>>> instance SOP.Generic Schwarma
105+>>> instance SOP.HasDatatypeInfo Schwarma
107+>>> :kind! EnumFrom Schwarma
108+EnumFrom Schwarma :: PGType
109+= 'PGenum '["Beef", "Lamb", "Chicken"]
113+ definition :: Definition '[] '["schwarma" ::: 'Typedef (EnumFrom Schwarma)]
114+ definition = createTypeEnumFrom @Schwarma #schwarma
116+>>> printSQL definition
117+CREATE TYPE "schwarma" AS ENUM ('Beef', 'Lamb', 'Chicken');
120+You can express values of an enum type using `label`, which is an overloaded method
121+of the `IsPGlabel` typeclass.
126+ expression :: Expression sch rels grp params ('NotNull (EnumFrom Schwarma))
127+ expression = label @"Chicken"
128+in printSQL expression
135+In addition to enum types, you can define composite types.
136+A composite type represents the structure of a row or record;
137+it is essentially just a list of field names and their data types.
140+`createTypeComposite` creates a composite type. The composite type is
141+specified by a list of attribute names and data types.
146+ definition :: Definition '[] '["complex" ::: 'Typedef ('PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8])]
147+ definition = createTypeComposite #complex (float8 `As` #real :* float8 `As` #imaginary :* Nil)
149+>>> printSQL definition
150+CREATE TYPE "complex" AS ("real" float8, "imaginary" float8);
153+Composite types are almost equivalent to Haskell record types.
154+However, because of the potential presence of @NULL@
155+all the record fields must be `Maybe`s of basic types.
156+Composite types can be generated from a Haskell record type, for example:
159+>>> data Complex = Complex {real :: Maybe Double, imaginary :: Maybe Double} deriving GHC.Generic
160+>>> instance SOP.Generic Complex
161+>>> instance SOP.HasDatatypeInfo Complex
163+>>> :kind! CompositeFrom Complex
164+CompositeFrom Complex :: PGType
165+= 'PGcomposite '['("real", 'PGfloat8), '("imaginary", 'PGfloat8)]
169+ definition :: Definition '[] '["complex" ::: 'Typedef (CompositeFrom Complex)]
170+ definition = createTypeCompositeFrom @Complex #complex
171+in printSQL definition
173+CREATE TYPE "complex" AS ("real" float8, "imaginary" float8);
176+A row constructor is an expression that builds a row value
177+(also called a composite value) using values for its member fields.
182+ i :: Expression '[] '[] 'Ungrouped '[] ('NotNull (CompositeFrom Complex))
183+ i = row (0 `As` #real :* 1 `As` #imaginary :* Nil)
189+You can also use `(&)` to apply a field label to a composite value.
194+ expr :: Expression '[] '[] 'Ungrouped '[] ('Null 'PGfloat8)
195+ expr = i & #imaginary
198+(ROW(0, 1)).imaginary
201+Both composite and enum types can be automatically encoded from and decoded to their equivalent Haskell types.
10### Version 0.2.1 - April 7, 2018
203### Version 0.2.1 - April 7, 2018