Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
telser committed Feb 27, 2024
1 parent 04c97b5 commit c9b0ce0
Show file tree
Hide file tree
Showing 32 changed files with 366 additions and 150 deletions.
5 changes: 4 additions & 1 deletion orville-postgresql/src/Orville/PostgreSQL.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand Down Expand Up @@ -165,6 +165,7 @@ module Orville.PostgreSQL
, SqlMarshaller.marshallReadOnlyField
, SqlMarshaller.marshallPartial
, SqlMarshaller.marshallMaybe
, SqlMarshaller.marshallAlias
, SqlMarshaller.prefixMarshaller
, SqlMarshaller.foldMarshallerFields
, SqlMarshaller.collectFromField
Expand Down Expand Up @@ -205,6 +206,7 @@ module Orville.PostgreSQL
, FieldDefinition.fieldOfType
, FieldDefinition.fieldColumnName
, FieldDefinition.fieldColumnReference
, FieldDefinition.fieldColumnReferenceWithAlias
, FieldDefinition.fieldName
, FieldDefinition.setFieldName
, FieldDefinition.fieldDescription
Expand Down Expand Up @@ -285,6 +287,7 @@ module Orville.PostgreSQL
, Expr.descendingOrder
, Expr.descendingOrderWith
, FieldDefinition.orderByField
, FieldDefinition.orderByFieldWithAlias
, Expr.orderByColumnName
, Expr.andExpr
, Expr.orExpr
Expand Down
12 changes: 6 additions & 6 deletions orville-postgresql/src/Orville/PostgreSQL/AutoMigration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{-# LANGUAGE RankNTypes #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand Down Expand Up @@ -547,7 +547,7 @@ mkAlterTableSteps currentNamespace relationDesc tableDef =
Orville.foldMarshallerFields
(Orville.unannotatedSqlMarshaller $ Orville.tableMarshaller tableDef)
[]
(Orville.collectFromField Orville.IncludeReadOnlyColumns (mkAddAlterColumnActions relationDesc))
(Orville.collectFromField Orville.IncludeReadOnlyColumns (const (mkAddAlterColumnActions relationDesc)))

dropColumnActions =
concatMap
Expand Down Expand Up @@ -690,7 +690,7 @@ mkAddAlterColumnActions relationDesc fieldDef =
|| (Orville.sqlTypeMaximumLength sqlType /= PgCatalog.pgAttributeMaxLength attr)

columnName =
Orville.fieldColumnName fieldDef
Orville.fieldColumnName Nothing fieldDef

dataType =
Orville.sqlTypeExpr sqlType
Expand All @@ -709,7 +709,7 @@ mkAddAlterColumnActions relationDesc fieldDef =

alterNullability = do
guard nullabilityIsChanged
[Expr.alterColumnNullability (Orville.fieldColumnName fieldDef) nullabilityAction]
[Expr.alterColumnNullability columnName nullabilityAction]

maybeExistingDefault =
PgCatalog.lookupAttributeDefault attr relationDesc
Expand Down Expand Up @@ -760,7 +760,7 @@ mkAddAlterColumnActions relationDesc fieldDef =
-- must rely on the database to raise the error because the table
-- does not yet exist for us to discover a conflict with system
-- attributes.
[Expr.addColumn (Orville.fieldColumnDefinition fieldDef)]
[Expr.addColumn (Orville.fieldColumnDefinition Nothing fieldDef)]

{- |
Builds 'Expr.AlterTableAction' expressions for the given attribute to make
Expand Down Expand Up @@ -1192,7 +1192,7 @@ currentNamespaceQuery =
-- put it in quotes it tries to treat it as a regular column name,
-- which then can't be found as a column in the query.
(RawSql.unsafeSqlExpression "current_schema")
(Orville.fieldColumnName PgCatalog.namespaceNameField)
(Orville.fieldColumnName Nothing PgCatalog.namespaceNameField)
]
)
Nothing
Expand Down
45 changes: 44 additions & 1 deletion orville-postgresql/src/Orville/PostgreSQL/Execution/Select.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ module Orville.PostgreSQL.Execution.Select
, selectToQueryExpr
, selectTable
, selectMarshalledColumns
, selectTableWithAlias
, selectMarshalledColumnsWithAlias
, rawSelectQueryExpr
)
where
Expand All @@ -31,7 +33,7 @@ import qualified Orville.PostgreSQL.Execution.Execute as Execute
import qualified Orville.PostgreSQL.Execution.QueryType as QueryType
import qualified Orville.PostgreSQL.Execution.SelectOptions as SelectOptions
import qualified Orville.PostgreSQL.Expr as Expr
import Orville.PostgreSQL.Marshall.SqlMarshaller (AnnotatedSqlMarshaller, marshallerDerivedColumns, unannotatedSqlMarshaller)
import Orville.PostgreSQL.Marshall.SqlMarshaller (AnnotatedSqlMarshaller, marshallerDerivedColumns, unannotatedSqlMarshaller, marshallAlias)
import qualified Orville.PostgreSQL.Monad as Monad
import Orville.PostgreSQL.Schema (TableDefinition, tableMarshaller, tableName)

Expand Down Expand Up @@ -121,6 +123,47 @@ selectMarshalledColumns marshaller qualifiedTableName selectOptions =
(Expr.referencesTable qualifiedTableName)
selectOptions

{- |
Builds a 'Select' that will select all the columns described in the
'TableDefinition'. This is the safest way to build a 'Select', because table
name and columns are all read from the 'TableDefinition'. If the table is
being managed with Orville auto-migrations, this will match the schema in the
database.
@since 1.1.0.0
-}
selectTableWithAlias ::
Expr.Alias ->
TableDefinition key writeEntity readEntity ->
SelectOptions.SelectOptions ->
Select readEntity
selectTableWithAlias alias tableDef =
selectMarshalledColumnsWithAlias alias (tableMarshaller tableDef) (tableName tableDef)

{- |
Builds a 'Select' that will select the columns described by the marshaller from the specified
table with the given alias. It is up to the caller to ensure that the columns in the marshaller
make sense for the table.
This function is useful for querying a subset of table columns using a custom
marshaller.
@since 1.1.0.0
-}
selectMarshalledColumnsWithAlias ::
Expr.Alias ->
AnnotatedSqlMarshaller writeEntity readEntity ->
Expr.Qualified Expr.TableName ->
SelectOptions.SelectOptions ->
Select readEntity
selectMarshalledColumnsWithAlias alias marshaller qualifiedTableName selectOptions =
rawSelectQueryExpr marshaller $
SelectOptions.selectOptionsQueryExpr
(Expr.selectDerivedColumns (marshallerDerivedColumns . marshallAlias alias $ unannotatedSqlMarshaller marshaller))
(Expr.referencesTableWithAlias alias qualifiedTableName)
selectOptions


{- |
Builds a 'Select' that will execute the specified query and use the given
'Orville.PostgreSQL.SqlMarshaller' to decode it. It is up to the caller to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand Down Expand Up @@ -66,7 +66,7 @@ selectInt64Value caller valueExpression = do
Expr.queryExpr
(Expr.selectClause (Expr.selectExpr Nothing))
( Expr.selectDerivedColumns
[Expr.deriveColumnAs valueExpression (Expr.columnName "result")]
[Expr.deriveColumnAs valueExpression (Expr.aliasQualifyColumn Nothing (Expr.columnName "result"))]
)
Nothing

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -21,7 +21,7 @@ where
import qualified Data.Maybe as Maybe

import Orville.PostgreSQL.Expr.DataType (DataType)
import Orville.PostgreSQL.Expr.Name (ColumnName)
import Orville.PostgreSQL.Expr.Name (ColumnName, Qualified)
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

Expand Down Expand Up @@ -49,7 +49,7 @@ newtype ColumnDefinition
-}
columnDefinition ::
-- | The name the resulting column should have.
ColumnName ->
Qualified ColumnName ->
-- | The SQL type of the column.
DataType ->
-- | The constraint on the column, if any.
Expand Down
6 changes: 3 additions & 3 deletions orville-postgresql/src/Orville/PostgreSQL/Expr/Count.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -13,7 +13,7 @@ module Orville.PostgreSQL.Expr.Count
)
where

import Orville.PostgreSQL.Expr.Name (ColumnName, FunctionName, functionName)
import Orville.PostgreSQL.Expr.Name (ColumnName, FunctionName, Qualified, functionName)
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression, columnReference, functionCall)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

Expand Down Expand Up @@ -44,6 +44,6 @@ count1 =
@since 1.0.0.0
-}
countColumn :: ColumnName -> ValueExpression
countColumn :: Qualified ColumnName -> ValueExpression
countColumn =
count . columnReference
6 changes: 3 additions & 3 deletions orville-postgresql/src/Orville/PostgreSQL/Expr/GroupBy.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -18,7 +18,7 @@ where

import Data.List.NonEmpty (NonEmpty)

import Orville.PostgreSQL.Expr.Name (ColumnName)
import Orville.PostgreSQL.Expr.Name (ColumnName, Qualified)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

{- |
Expand Down Expand Up @@ -83,6 +83,6 @@ appendGroupByExpr (GroupByExpr a) (GroupByExpr b) =
@since 1.0.0.0
-}
groupByColumnsExpr :: NonEmpty ColumnName -> GroupByExpr
groupByColumnsExpr :: NonEmpty (Qualified ColumnName) -> GroupByExpr
groupByColumnsExpr =
GroupByExpr . RawSql.intercalate RawSql.commaSpace
4 changes: 2 additions & 2 deletions orville-postgresql/src/Orville/PostgreSQL/Expr/Insert.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand Down Expand Up @@ -95,7 +95,7 @@ parens and commas are used to separate.
@since 1.0.0.0
-}
insertColumnList :: [ColumnName] -> InsertColumnList
insertColumnList :: [Qualified ColumnName] -> InsertColumnList
insertColumnList columnNames =
InsertColumnList $
RawSql.leftParen
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -12,16 +12,32 @@ module Orville.PostgreSQL.Expr.Internal.Name.Qualified
, qualifyTable
, qualifySequence
, qualifyColumn
, Alias
, aliasQualifyColumn
, alias
)
where

import Orville.PostgreSQL.Expr.Internal.Name.ColumnName (ColumnName)
import Orville.PostgreSQL.Expr.Internal.Name.Identifier (IdentifierExpression (toIdentifier))
import Orville.PostgreSQL.Expr.Internal.Name.Identifier (IdentifierExpression (toIdentifier), Identifier, identifier)
import Orville.PostgreSQL.Expr.Internal.Name.SchemaName (SchemaName)
import Orville.PostgreSQL.Expr.Internal.Name.SequenceName (SequenceName)
import Orville.PostgreSQL.Expr.Internal.Name.TableName (TableName)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

newtype Alias
= Alias Identifier
deriving
( -- | @since 1.1.0.0
RawSql.SqlExpression
, -- | @since 1.1.0.0
IdentifierExpression
)

alias :: String -> Alias
alias =
Alias . identifier

{- |
Type to represent a qualified SQL name. E.G.
Expand Down Expand Up @@ -82,6 +98,14 @@ qualifyColumn mbSchemaName tableName unqualifiedName =
. RawSql.unsafeFromRawSql
$ RawSql.toRawSql (toIdentifier tableName) <> RawSql.dot <> RawSql.toRawSql (toIdentifier unqualifiedName)

aliasQualifyColumn :: Maybe Alias -> ColumnName -> Qualified ColumnName
aliasQualifyColumn mbAliasName unqualifiedName =
Qualified $ case mbAliasName of
Nothing ->
RawSql.toRawSql $ toIdentifier unqualifiedName
Just aliasName ->
RawSql.toRawSql (toIdentifier aliasName) <> RawSql.dot <> RawSql.toRawSql (toIdentifier unqualifiedName)

-- Note: Not everything actually makes sense to be qualified by _only_ a schema name, such as
-- columns, as in 'qualifyColumn'. But this does give us a nice uniform way to provide the
-- functionality in those more type restricted scenarios.
Expand Down
10 changes: 5 additions & 5 deletions orville-postgresql/src/Orville/PostgreSQL/Expr/OrderBy.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -25,7 +25,7 @@ where

import qualified Data.List.NonEmpty as NEL

import Orville.PostgreSQL.Expr.Name (ColumnName)
import Orville.PostgreSQL.Expr.Name (ColumnName, Qualified)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql

{- |
Expand Down Expand Up @@ -83,11 +83,11 @@ appendOrderByExpr (OrderByExpr a) (OrderByExpr b) =
@since 1.0.0.0
-}
orderByColumnsExpr :: NEL.NonEmpty (ColumnName, OrderByDirection) -> OrderByExpr
orderByColumnsExpr :: NEL.NonEmpty (Qualified ColumnName, OrderByDirection) -> OrderByExpr
orderByColumnsExpr =
OrderByExpr . RawSql.intercalate RawSql.commaSpace . fmap columnOrdering
where
columnOrdering :: (ColumnName, OrderByDirection) -> RawSql.RawSql
columnOrdering :: (Qualified ColumnName, OrderByDirection) -> RawSql.RawSql
columnOrdering (columnName, orderByDirection) =
RawSql.toRawSql columnName <> RawSql.space <> RawSql.toRawSql orderByDirection

Expand All @@ -96,7 +96,7 @@ orderByColumnsExpr =
@since 1.0.0.0
-}
orderByColumnName :: ColumnName -> OrderByDirection -> OrderByExpr
orderByColumnName :: Qualified ColumnName -> OrderByDirection -> OrderByExpr
orderByColumnName =
curry (orderByColumnsExpr . pure)

Expand Down
8 changes: 4 additions & 4 deletions orville-postgresql/src/Orville/PostgreSQL/Expr/Query.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{- |
Copyright : Flipstone Technology Partners 2023
Copyright : Flipstone Technology Partners 2023-2024
License : MIT
Stability : Stable
Expand All @@ -26,7 +26,7 @@ import Data.Maybe (catMaybes, fromMaybe)

import Orville.PostgreSQL.Expr.GroupBy (GroupByClause)
import Orville.PostgreSQL.Expr.LimitExpr (LimitExpr)
import Orville.PostgreSQL.Expr.Name (ColumnName)
import Orville.PostgreSQL.Expr.Name (ColumnName, Qualified)
import Orville.PostgreSQL.Expr.OffsetExpr (OffsetExpr)
import Orville.PostgreSQL.Expr.OrderBy (OrderByClause)
import Orville.PostgreSQL.Expr.Select (SelectClause)
Expand Down Expand Up @@ -110,7 +110,7 @@ selectStar =
@since 1.0.0.0
-}
selectColumns :: [ColumnName] -> SelectList
selectColumns :: [Qualified ColumnName] -> SelectList
selectColumns =
selectDerivedColumns . map (deriveColumn . columnReference)

Expand Down Expand Up @@ -156,7 +156,7 @@ deriveColumn =
@since 1.0.0.0
-}
deriveColumnAs :: ValueExpression -> ColumnName -> DerivedColumn
deriveColumnAs :: ValueExpression -> Qualified ColumnName -> DerivedColumn --TODO This should not be allowed to take a qualified column name, it isn't valid sql to have the qualifier
deriveColumnAs valueExpr asColumn =
DerivedColumn
( RawSql.toRawSql valueExpr
Expand Down
Loading

0 comments on commit c9b0ce0

Please sign in to comment.