serviette (empty) → 0.1.0.0
raw patch · 7 files changed
+313/−0 lines, 7 filesdep +aesondep +basedep +bytestringbinary-added
Dependencies added: aeson, base, bytestring, generic-deriving, protolude, text
Files
- .DS_Store binary
- ._.DS_Store binary
- LICENSE +30/−0
- README.md +27/−0
- serviette.cabal +35/−0
- src/ApiDataTypes.hs +144/−0
- src/Serviette.hs +77/−0
+ .DS_Store view
binary file changed (absent → 6148 bytes)
+ ._.DS_Store view
binary file changed (absent → 120 bytes)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,27 @@+# SERVIETTE - SQL JSON API + Library for generating SQL queries from JSON. + Send the json in the expected format and receive raw sql string.+### Why ?+- Why not ?++### Expected JSON format+````+{+ "format":1,+ "action":"SELECT",+ "selectName": "users",+ "joinTables":[+ {"tablename":"addresses","field":"userid","operator":"=","withTable":"users", "withField":"id"},+ {"tablename":"posts","field":"userid","operator":"=","withTable":"users", "withField":"id"}+ ],+ "whereCondition":[+ {"whereTableName":"users","whereField":"id", "whereOperator":">", "whereFieldValue": 1}+ ]+}+````++If `format` is set to 1 you will get raw sql string back, something like this:+`````++`````+
+ serviette.cabal view
@@ -0,0 +1,35 @@+name: serviette+version: 0.1.0.0+synopsis: JSON to Sql raw string or db result in json format+description: Use json to query the database and receive results+homepage: https://github.com/v0d1ch/serviette#readme+license: BSD3+license-file: LICENSE+author: Sasa Bogicevic +maintainer: brutallesale@gmail.com+copyright: 2017 Sasa Bogicevic+category: Web+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Serviette+ , ApiDataTypes+ build-depends: base >= 4.7 && < 5+ , aeson+ , bytestring >= 0.9 && < 0.11+ , text >= 0.11 && < 2.0+ , generic-deriving+ , protolude++++ default-language: Haskell2010++++source-repository head+ type: git+ location: https://github.com/v0d1ch/serviette
+ src/ApiDataTypes.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++-- | This provides types that represent sql query structure+module ApiDataTypes where++import Control.Applicative+import Control.Monad+import Data.Aeson+import Data.Aeson.Types+import Data.Text as T+import Generics.Deriving++-- | Type declaration++-- | Represents db table name+data TableName = TableName Text+ deriving (Show, Generic)++-- | Represents db table column name+data ColumnName = ColumnName Text+ deriving (Show, Generic)++-- | Represents operator (=, >, <, like, not like etc.)+data Operator = Operator Text+ deriving(Show, Generic)++-- | Represents the main action for the sql query (SELECT,INSERT, UPDATE, DELETE)+data Action = Action Text+ deriving (Show, Generic)+-- | Represents return format (for now this is only raw sql string)+data Format = Format+ { getFormat :: Int+ } deriving (Show, Eq)++-- | Represents Date field value+type DateVal = Text++-- | Represents field value which can be integer, string or date+data FieldValue = IntField Int | TextField Text | DateField DateVal deriving (Show, Generic)++-- | Represents join table for the sql query+data JoinTable = JoinTable+ { tablename :: TableName+ , field :: ColumnName+ , operator :: Operator+ , withTable :: TableName+ , withField :: ColumnName+ , whereConditionJoin :: Text+ } deriving (Show, Generic)++-- | Represents main where condition+data WhereCondition = WhereCondition+ { whereTableName :: TableName+ , whereField :: ColumnName+ , whereOperator :: Operator+ , whereFieldValue :: FieldValue+ } deriving (Show, Generic)++-- | Represents intermediate type for receiving json+data SqlQuery = SqlQuery+ { format :: Int+ , action :: Action+ , selectName :: TableName+ , joinTables :: [JoinTable]+ , whereCondition :: [WhereCondition]+ } deriving (Show, Generic)++-- | Represents type that is the result of the json "computation"+data SqlResultQuery = SqlResultQuery+ { getAction :: Action+ , getSelectTable :: TableName+ , getJoins :: [JoinTable]+ , getWhereCondition :: [WhereCondition]+ } deriving (Show, Generic)+++-- | Instances++-- | Json instance for TableName+instance FromJSON TableName++-- | Json instance for TableName+instance ToJSON TableName++-- | aeson instance for Action+instance FromJSON Action++-- | aeson instance for Action+instance ToJSON Action++-- | aeson instance for Operator+instance FromJSON Operator++-- | aeson instance for Operator+instance ToJSON Operator++-- | aeson instance for JoinTable+instance FromJSON JoinTable++-- | aeson instance for JoinTable+instance ToJSON JoinTable++-- | aeson instance for ColumnName+instance FromJSON ColumnName++-- | aeson instance for ColumnName+instance ToJSON ColumnName++-- | aeson instance for SqlQuery+instance FromJSON SqlQuery++-- | aeson instance for SqlQuery+instance ToJSON SqlQuery++-- | aeson instance for SqlResultQuery+instance FromJSON SqlResultQuery++-- | aeson instance for SqlResultQuery+instance ToJSON SqlResultQuery++-- | aeson instance for FieldValue+instance FromJSON FieldValue++-- | aeson instance for FieldValue+instance ToJSON FieldValue++-- | aeson instance for WhereCondition+instance ToJSON WhereCondition++-- | aeson instance for WhereCondition+instance FromJSON WhereCondition where+ parseJSON (Object v)+ = WhereCondition+ <$> v .: "whereTableName"+ <*> v .: "whereField"+ <*> v .: "whereOperator"+ <*> ( IntField <$> (v .: "whereFieldValue")+ <|> TextField <$> (v .: "whereFieldValue")+ <|> DateField <$> (v .: "whereFieldValue")++ )+ parseJSON _ = mzero
+ src/Serviette.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE OverloadedStrings #-}+-- | Define functions needed for Json to Text manipulation+-- current version supports only raw sql string result+-- next version will implement database query result in the json format+-- as well as errors in the json structure if any++module Serviette (SqlQuery, SqlResultQuery, rawSqlStr) where++import ApiDataTypes+import Data.Text hiding (concat, map)+++-- | Various Getters++-- | Extracts the action and appends space+extractAction :: Action -> Text+extractAction (Action t) = append t " "++-- | Extracts table name to Text+extractTableName :: TableName -> Text+extractTableName (TableName t) = t++-- | Extracts table column name to Text+extractColumnName :: ColumnName -> Text+extractColumnName (ColumnName t) = t++-- | Extracts Operator to Text+extractOperator :: Operator -> Text+extractOperator (Operator t) = t++-- | Fetches the Action from SqlQuery+getActionArg :: SqlQuery -> Action+getActionArg q = action q++-- | Gets the main table that Action is performed on+getSelectTableArg :: SqlQuery -> TableName+getSelectTableArg q = selectName q++-- | Retrieves the join list from the SqlQuery+getJoinTableArg :: SqlQuery -> [JoinTable]+getJoinTableArg q = joinTables q++-- | Gets the where condition list+getWhereConditionArg :: SqlQuery -> [WhereCondition]+getWhereConditionArg q = whereCondition q++-- | Retrieves the result Format+getFormatArg :: SqlQuery -> Int+getFormatArg q = getFormat $ Format $ format q++-- | Formats the join table list+formatJoinStr :: JoinTable -> Text+formatJoinStr j = Prelude.foldl append "" (" join " : [(extractTableName $ tablename j) , " on " , (extractColumnName $ field j) , " " ,(extractOperator $ operator j) , " " , (extractTableName $ withTable j) , "." , (extractColumnName $ withField j), " " ])++-- | Fetches field value depending on field type+formatFieldValue :: FieldValue -> String+formatFieldValue a =+ case a of+ IntField x -> show x+ TextField x -> show x+ DateField x -> show x++-- | Formats WhereCondition to Text+formatWhereConditionStr :: WhereCondition -> Text+formatWhereConditionStr j = Prelude.foldl append " " (" where " : [ (extractTableName $ whereTableName j), "." , (extractColumnName $ whereField j) , " " ,(extractOperator $ whereOperator j) , " " , (pack $ formatFieldValue $ whereFieldValue j)])+++-- | Creates final SqlResultQuery type+formatToSqlResultQueryType sql = SqlResultQuery (getActionArg sql) (getSelectTableArg sql) (getJoinTableArg sql) (getWhereConditionArg sql)++-- | Returns raw sql query string+rawSqlStr :: SqlQuery -> Text+rawSqlStr s =+ Prelude.foldl append "" [(extractAction $ getAction sql) ,(extractTableName $ getSelectTable sql) , joins , whereConditions ]+ where joins = Prelude.foldl append "" $ fmap formatJoinStr $ getJoins sql+ whereConditions = Prelude.foldl append "" $ fmap formatWhereConditionStr $ getWhereCondition sql+ sql = formatToSqlResultQueryType s