SlideShare a Scribd company logo
SCRAP YOUR
QUERY
BOILERPLATE
WITH SPECQL
2.9.2017 ClojuTRE Tatu Tarvainen (@tatut)
WHAT IS SPECQL?
› The combination of clojure.spec, PostgreSQL and the power of
macros
clojure.spec PostgreSQL
λ
SOME BACKGROUND
› Yesql/Jeesql/Hugsql are all fine and specql does not try to ”solve”
SQL so that you don’t have to use it anymore
› When you have multiple slightly different queries, there’s
duplication or fetching too much
› Adding dynamic WHERE clauses leads to ugly NULL checking of
bound parameters
EXAMPLE
› SELECT it.foo, it.bar, it.baz
› FROM interesting_table it
› WHERE it.archived = FALSE
› AND it.organization = :user_org_id
› AND it.category IN (:categories)
EXAMPLE
› SELECT it.foo, it.bar, it.baz
› FROM interesting_table it
› WHERE it.archived = FALSE
› AND it.organization = :user_org_id
› AND it.category IN (:categories)
How to make
variants without
duplication or
selecting too much?
EXAMPLE
› SELECT it.foo, it.bar, it.baz
› FROM interesting_table it
› WHERE it.archived = FALSE
› AND it.organization = :user_org_id
› AND it.category IN (:categories)
How to
add/remove
clauses
dynamically?
EXAMPLE
› SELECT it.foo, it.bar, it.baz,
› o.name AS organization_name
› FROM interesting_table it
› JOIN organization o ON it.organization_id = o.id
› WHERE it.archived = FALSE
› AND it.organization = :user_org_id
› AND it.category IN (:categories)
EXAMPLE
› SELECT it.foo, it.bar, it.baz,
› o.name AS organization_name
› FROM interesting_table it
› JOIN organization o ON it.organization_id = o.id
› WHERE it.archived = FALSE
› AND it.organization = :user_org_id
› AND it.category IN (:categories)
How to cleanly add
these without code
duplication?
THE SPECQL WAY: DEFINE
› (define-tables db
› [”interesting_table” ::it/interesting
› {::it/organization (rel/has-one
› ::it/organization_id
› ::org/organization
› ::org/id)}])
THE SPECQL WAY: DEFINE
› (define-tables db
› [”interesting_table” ::it/interesting
› {::it/organization (rel/has-one
› ::it/organization_id
› ::org/organization
› ::org/id)}])
The main macro
for defining things
THE SPECQL WAY: DEFINE
› (define-tables db
› [”interesting_table” ::it/interesting
› {::it/organization (rel/has-one
› ::it/organization_id
› ::org/organization
› ::org/id)}])
The name of the
table in the
database
THE SPECQL WAY: DEFINE
› (define-tables db
› [”interesting_table” ::it/interesting
› {::it/organization (rel/has-one
› ::it/organization_id
› ::org/organization
› ::org/id)}])
The namespaced
keyword for the
table
THE SPECQL WAY: DEFINE
› (define-tables db
› [”interesting_table” ::it/interesting
› {::it/organization (rel/has-one
› ::it/organization_id
› ::org/organization
› ::org/id)}])
Additional
definitions for
columns
THE SPECQL WAY: FETCH
› (defn fetch-interesting [db org-id categories]
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
THE SPECQL WAY: FETCH
› (defn fetch-interesting [db org-id categories]
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
The table to fetch
from
THE SPECQL WAY: FETCH
› (defn fetch-interesting [db org-id categories]
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
Set of columns to
retrieve
THE SPECQL WAY: FETCH
› (defn fetch-interesting [db org-id categories]
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
The WHERE
clause map
THE SPECQL WAY: RESULT
› (fetch-interesting db 1 #{”stuff” ”things”})
› ;; => ({::it/foo 1
› ::it/bar ”example”
› ::it/baz true} …)
›
THE SPECQL WAY: JOIN
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz
› [::it/organization #{::org/id ::org/name}]}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
THE SPECQL WAY: JOIN
› (fetch db ::it/interesting
› #{::it/foo ::it/bar ::it/baz
› [::it/organization #{::org/id ::org/name}]}
› {::it/archived false
› ::it/organization_id org-id
› ::it/category (op/in categories)}))
Nested column definition
for a JOINed tables
THE SPECQL WAY: JOIN
› ;; => ({::it/foo 1
› ::it/bar ”example”
› ::it/baz true
› ::it/organization {::org/id 1
› ::org/name ”Acme Inc”}
› …)
THE SPECQL WAY: JOIN
› ;; => ({::it/foo 1
› ::it/bar ”example”
› ::it/baz true
› ::it/organization {::org/id 1
› ::org/name ”Acme Inc”}
› …)
Joined entity is
available in a nested
map
SPECQL BENEFITS
› Clojure data!
› The column set is just data and can be easily manipulated
• Even given as parameters from the frontend
› Where clauses can be easily added and are (mostly) just data as well
› Every table and column has a single ns keyword definition
• No more ”order” vs ”order-id” vs ”ord” differences in returned query
results
• Namespaced keys are the way of the future
SPECQL BENEFITS
› Clojure data!
› The column set is just data and can be easily manipulated
• Even given as parameters from the frontend
› Where clauses can be easily added and are (mostly) just data as well
› Every table and column has a single ns keyword definition
• No more ”order” vs ”order-id” vs ”ord” differences in returned query
results
• Namespaced keys are the way of the future HERE TO STAY
SPECQL BENEFITS
› Works with ClojureScript
• The spec generation part, put your specs in .cljc files and enjoy the same
specs and have your db definitions drive your frontend as well
› Works well with ”typed document storage” pattern
• A column can be a user defined type or array
› Provides generic upsert!
• No need to branch code, let the db handle it
› Works with database VIEWs
STATUS
› The github project page (https://github.com/tatut/specql) still says
EXPERIMENTAL
• Current 0.7 alpha stage, should be ready this year
• We are already using it in production in Harja
› No concrete promises before the experimental flag is gone, but the
API should only grow
• The test suite is comprehensive and should not break
STATUS
› 0.7 is coming and adds support for stored procedures
• Macro for defining a stored procedure as a function
• Better JOIN handling
• Currently fetching multiple ”has many” collections at once doesn’t work properly
› How to help
• Please try it out if you are using PostgreSQL
• Report rough edges, I try to provide good error messages
› EXAMPLE
THANK YOU
github.com/tatut/specql twitter.com/tatut

More Related Content

What's hot

Introduction to database
Introduction to databaseIntroduction to database
Introduction to database
oly07104
 
Introduction to database
Introduction to databaseIntroduction to database
Introduction to database
Kazi Uddin Oly
 
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
Marco Gralike
 
Enterprise Search Solution: Apache SOLR. What's available and why it's so cool
Enterprise Search Solution: Apache SOLR. What's available and why it's so coolEnterprise Search Solution: Apache SOLR. What's available and why it's so cool
Enterprise Search Solution: Apache SOLR. What's available and why it's so cool
Ecommerce Solution Provider SysIQ
 
Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)
Wongnai
 
PostgreSQL (2) by Aswin
PostgreSQL (2) by AswinPostgreSQL (2) by Aswin
PostgreSQL (2) by Aswin
Agate Studio
 
การใช้ภาษา SQL
การใช้ภาษา SQLการใช้ภาษา SQL
การใช้ภาษา SQL
Kornnicha Wonglai
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered table
Mahabubur Rahaman
 
Victoria wordpress
Victoria wordpressVictoria wordpress
Victoria wordpress
Flynn O'Connor
 
Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2
Marco Gralike
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access
Rebecca Grenier
 
UKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the DatabaseUKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the Database
Marco Gralike
 
Introduction to Solr
Introduction to SolrIntroduction to Solr
Introduction to Solr
Jayesh Bhoyar
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
Simon Willison
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
Mysql query optimization
Mysql query optimizationMysql query optimization
Mysql query optimization
Baohua Cai
 
Mentor Your Indexes
Mentor Your IndexesMentor Your Indexes
Mentor Your Indexes
Karwin Software Solutions LLC
 
Apache Solr + ajax solr
Apache Solr + ajax solrApache Solr + ajax solr
Apache Solr + ajax solr
Net7
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
Valentine Dianov
 
Advanced Django ORM techniques
Advanced Django ORM techniquesAdvanced Django ORM techniques
Advanced Django ORM techniques
Daniel Roseman
 

What's hot (20)

Introduction to database
Introduction to databaseIntroduction to database
Introduction to database
 
Introduction to database
Introduction to databaseIntroduction to database
Introduction to database
 
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
Oracle Developer Day, 20 October 2009, Oracle De Meern, Holland: Oracle Datab...
 
Enterprise Search Solution: Apache SOLR. What's available and why it's so cool
Enterprise Search Solution: Apache SOLR. What's available and why it's so coolEnterprise Search Solution: Apache SOLR. What's available and why it's so cool
Enterprise Search Solution: Apache SOLR. What's available and why it's so cool
 
Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)
 
PostgreSQL (2) by Aswin
PostgreSQL (2) by AswinPostgreSQL (2) by Aswin
PostgreSQL (2) by Aswin
 
การใช้ภาษา SQL
การใช้ภาษา SQLการใช้ภาษา SQL
การใช้ภาษา SQL
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered table
 
Victoria wordpress
Victoria wordpressVictoria wordpress
Victoria wordpress
 
Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access
 
UKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the DatabaseUKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the Database
 
Introduction to Solr
Introduction to SolrIntroduction to Solr
Introduction to Solr
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
 
Mysql query optimization
Mysql query optimizationMysql query optimization
Mysql query optimization
 
Mentor Your Indexes
Mentor Your IndexesMentor Your Indexes
Mentor Your Indexes
 
Apache Solr + ajax solr
Apache Solr + ajax solrApache Solr + ajax solr
Apache Solr + ajax solr
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
 
Advanced Django ORM techniques
Advanced Django ORM techniquesAdvanced Django ORM techniques
Advanced Django ORM techniques
 

Similar to Scrap your query boilerplate with specql

Introduction to Elasticsearch
Introduction to ElasticsearchIntroduction to Elasticsearch
Introduction to Elasticsearch
Sperasoft
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao Introduction
Booch Lin
 
PostgreSQL
PostgreSQLPostgreSQL
PostgreSQL
Reuven Lerner
 
An Introduction to Elastic Search.
An Introduction to Elastic Search.An Introduction to Elastic Search.
An Introduction to Elastic Search.
Jurriaan Persyn
 
PostgreSQL - It's kind've a nifty database
PostgreSQL - It's kind've a nifty databasePostgreSQL - It's kind've a nifty database
PostgreSQL - It's kind've a nifty database
Barry Jones
 
Oracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAsOracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAs
Alex Zaballa
 
Oracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c  - New Features for Developers and DBAsOracle Database 12c  - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAs
Alex Zaballa
 
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
Uri Cohen
 
Go database/sql
Go database/sqlGo database/sql
Go database/sql
Artem Kovardin
 
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
Alex Zaballa
 
IR SQLite Session #1
IR SQLite Session #1IR SQLite Session #1
IR SQLite Session #1
InfoRepos Technologies
 
Postgresql
PostgresqlPostgresql
TSQL in SQL Server 2012
TSQL in SQL Server 2012TSQL in SQL Server 2012
TSQL in SQL Server 2012
Eduardo Castro
 
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to SphinxMYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
Pythian
 
Making Django and NoSQL Play Nice
Making Django and NoSQL Play NiceMaking Django and NoSQL Play Nice
Making Django and NoSQL Play Nice
Alex Gaynor
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
 
10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL
Satoshi Nagayasu
 
Apache TAJO
Apache TAJOApache TAJO
Apache TAJO
Asis Mohanty
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
ddiers
 
Relational Database Language.pptx
Relational Database Language.pptxRelational Database Language.pptx
Relational Database Language.pptx
Sheethal Aji Mani
 

Similar to Scrap your query boilerplate with specql (20)

Introduction to Elasticsearch
Introduction to ElasticsearchIntroduction to Elasticsearch
Introduction to Elasticsearch
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao Introduction
 
PostgreSQL
PostgreSQLPostgreSQL
PostgreSQL
 
An Introduction to Elastic Search.
An Introduction to Elastic Search.An Introduction to Elastic Search.
An Introduction to Elastic Search.
 
PostgreSQL - It's kind've a nifty database
PostgreSQL - It's kind've a nifty databasePostgreSQL - It's kind've a nifty database
PostgreSQL - It's kind've a nifty database
 
Oracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAsOracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAs
 
Oracle Database 12c - New Features for Developers and DBAs
Oracle Database 12c  - New Features for Developers and DBAsOracle Database 12c  - New Features for Developers and DBAs
Oracle Database 12c - New Features for Developers and DBAs
 
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
To scale or not to scale: Key/Value, Document, SQL, JPA – What’s right for my...
 
Go database/sql
Go database/sqlGo database/sql
Go database/sql
 
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
 
IR SQLite Session #1
IR SQLite Session #1IR SQLite Session #1
IR SQLite Session #1
 
Postgresql
PostgresqlPostgresql
Postgresql
 
TSQL in SQL Server 2012
TSQL in SQL Server 2012TSQL in SQL Server 2012
TSQL in SQL Server 2012
 
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to SphinxMYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
 
Making Django and NoSQL Play Nice
Making Django and NoSQL Play NiceMaking Django and NoSQL Play Nice
Making Django and NoSQL Play Nice
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
 
10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL
 
Apache TAJO
Apache TAJOApache TAJO
Apache TAJO
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
 
Relational Database Language.pptx
Relational Database Language.pptxRelational Database Language.pptx
Relational Database Language.pptx
 

Recently uploaded

ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
Drona Infotech
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
GohKiangHock
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
Patrick Weigel
 

Recently uploaded (20)

ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
 

Scrap your query boilerplate with specql

  • 1. SCRAP YOUR QUERY BOILERPLATE WITH SPECQL 2.9.2017 ClojuTRE Tatu Tarvainen (@tatut)
  • 2. WHAT IS SPECQL? › The combination of clojure.spec, PostgreSQL and the power of macros clojure.spec PostgreSQL λ
  • 3. SOME BACKGROUND › Yesql/Jeesql/Hugsql are all fine and specql does not try to ”solve” SQL so that you don’t have to use it anymore › When you have multiple slightly different queries, there’s duplication or fetching too much › Adding dynamic WHERE clauses leads to ugly NULL checking of bound parameters
  • 4. EXAMPLE › SELECT it.foo, it.bar, it.baz › FROM interesting_table it › WHERE it.archived = FALSE › AND it.organization = :user_org_id › AND it.category IN (:categories)
  • 5. EXAMPLE › SELECT it.foo, it.bar, it.baz › FROM interesting_table it › WHERE it.archived = FALSE › AND it.organization = :user_org_id › AND it.category IN (:categories) How to make variants without duplication or selecting too much?
  • 6. EXAMPLE › SELECT it.foo, it.bar, it.baz › FROM interesting_table it › WHERE it.archived = FALSE › AND it.organization = :user_org_id › AND it.category IN (:categories) How to add/remove clauses dynamically?
  • 7. EXAMPLE › SELECT it.foo, it.bar, it.baz, › o.name AS organization_name › FROM interesting_table it › JOIN organization o ON it.organization_id = o.id › WHERE it.archived = FALSE › AND it.organization = :user_org_id › AND it.category IN (:categories)
  • 8. EXAMPLE › SELECT it.foo, it.bar, it.baz, › o.name AS organization_name › FROM interesting_table it › JOIN organization o ON it.organization_id = o.id › WHERE it.archived = FALSE › AND it.organization = :user_org_id › AND it.category IN (:categories) How to cleanly add these without code duplication?
  • 9. THE SPECQL WAY: DEFINE › (define-tables db › [”interesting_table” ::it/interesting › {::it/organization (rel/has-one › ::it/organization_id › ::org/organization › ::org/id)}])
  • 10. THE SPECQL WAY: DEFINE › (define-tables db › [”interesting_table” ::it/interesting › {::it/organization (rel/has-one › ::it/organization_id › ::org/organization › ::org/id)}]) The main macro for defining things
  • 11. THE SPECQL WAY: DEFINE › (define-tables db › [”interesting_table” ::it/interesting › {::it/organization (rel/has-one › ::it/organization_id › ::org/organization › ::org/id)}]) The name of the table in the database
  • 12. THE SPECQL WAY: DEFINE › (define-tables db › [”interesting_table” ::it/interesting › {::it/organization (rel/has-one › ::it/organization_id › ::org/organization › ::org/id)}]) The namespaced keyword for the table
  • 13. THE SPECQL WAY: DEFINE › (define-tables db › [”interesting_table” ::it/interesting › {::it/organization (rel/has-one › ::it/organization_id › ::org/organization › ::org/id)}]) Additional definitions for columns
  • 14. THE SPECQL WAY: FETCH › (defn fetch-interesting [db org-id categories] › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)}))
  • 15. THE SPECQL WAY: FETCH › (defn fetch-interesting [db org-id categories] › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)})) The table to fetch from
  • 16. THE SPECQL WAY: FETCH › (defn fetch-interesting [db org-id categories] › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)})) Set of columns to retrieve
  • 17. THE SPECQL WAY: FETCH › (defn fetch-interesting [db org-id categories] › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)})) The WHERE clause map
  • 18. THE SPECQL WAY: RESULT › (fetch-interesting db 1 #{”stuff” ”things”}) › ;; => ({::it/foo 1 › ::it/bar ”example” › ::it/baz true} …) ›
  • 19. THE SPECQL WAY: JOIN › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz › [::it/organization #{::org/id ::org/name}]} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)}))
  • 20. THE SPECQL WAY: JOIN › (fetch db ::it/interesting › #{::it/foo ::it/bar ::it/baz › [::it/organization #{::org/id ::org/name}]} › {::it/archived false › ::it/organization_id org-id › ::it/category (op/in categories)})) Nested column definition for a JOINed tables
  • 21. THE SPECQL WAY: JOIN › ;; => ({::it/foo 1 › ::it/bar ”example” › ::it/baz true › ::it/organization {::org/id 1 › ::org/name ”Acme Inc”} › …)
  • 22. THE SPECQL WAY: JOIN › ;; => ({::it/foo 1 › ::it/bar ”example” › ::it/baz true › ::it/organization {::org/id 1 › ::org/name ”Acme Inc”} › …) Joined entity is available in a nested map
  • 23. SPECQL BENEFITS › Clojure data! › The column set is just data and can be easily manipulated • Even given as parameters from the frontend › Where clauses can be easily added and are (mostly) just data as well › Every table and column has a single ns keyword definition • No more ”order” vs ”order-id” vs ”ord” differences in returned query results • Namespaced keys are the way of the future
  • 24. SPECQL BENEFITS › Clojure data! › The column set is just data and can be easily manipulated • Even given as parameters from the frontend › Where clauses can be easily added and are (mostly) just data as well › Every table and column has a single ns keyword definition • No more ”order” vs ”order-id” vs ”ord” differences in returned query results • Namespaced keys are the way of the future HERE TO STAY
  • 25. SPECQL BENEFITS › Works with ClojureScript • The spec generation part, put your specs in .cljc files and enjoy the same specs and have your db definitions drive your frontend as well › Works well with ”typed document storage” pattern • A column can be a user defined type or array › Provides generic upsert! • No need to branch code, let the db handle it › Works with database VIEWs
  • 26. STATUS › The github project page (https://github.com/tatut/specql) still says EXPERIMENTAL • Current 0.7 alpha stage, should be ready this year • We are already using it in production in Harja › No concrete promises before the experimental flag is gone, but the API should only grow • The test suite is comprehensive and should not break
  • 27. STATUS › 0.7 is coming and adds support for stored procedures • Macro for defining a stored procedure as a function • Better JOIN handling • Currently fetching multiple ”has many” collections at once doesn’t work properly › How to help • Please try it out if you are using PostgreSQL • Report rough edges, I try to provide good error messages

Editor's Notes

  1. Specql is a new library for using PostgreSQL from a Clojure application. It introspects your database at compile time (with the help of some macro magic) and provides clojure.spec specs for your tables and their columns. In addition to creating specs, Specql also retains runtime information so that it can provide generic query and update operations. More on those later.
  2. We have found that slightly different queries are painful to maintain. Hand written SQL also suffers from the problem of having different keys for different table columns. One query might use :order and another might use :orderid. There is no single truth of what a keyword means.
  3. Let's compare by an example. Consider some table called interesting_table that we want to query from.
  4. How can we easily vary the set of columns we fetch without having multiple almost identical queries or fetching everything and selecting the wanted keys on the caller.
  5. These two problems, in our experience, lead to making similar queries or make the queries you write awkwardly complicated. And we haven’t even talked about JOINs yet. What if I have two similar queries, but the other one needs to join a table?
  6. Adding columns from a JOINed table further changes how our SQL query looks. Making it difficult to even see that they are conceptually the same.
  7. First we define our tables so specql can generate the specs and record information about it.
  8. First we define our tables so specql can generate the specs and record information about it.
  9. First we define our tables so specql can generate the specs and record information about it.
  10. The spec for the table (a keys spec) is generated for the keyword specified here. All column specs will be generated in the same namespace.
  11. The column options can be used to do transformations for the columns (like converting an enum to keywords on the fly). In this example we are defining a JOIN specification. The organization virtual column is a one to one JOIN to the organization table.
  12. Specql provides a function called fetch that can be used to make queries against any previously defined table.
  13. The table is simply the keyword we registered the table under in a previous call to define-tables
  14. The columns is just a Clojure set of the namespaced keywords of the table columns
  15. The where map is interesting. The keys are columns of the table being queried the values can either be values (which are simple equality checks) or operators. The basic SQL operators are provided (equality, less than, greater than, in, like) and there is a protocol for you to define more. Multiple maps of where clauses can be combined with op/and and op/or operators.
  16. Finally the result is a sequence of maps which contain the namespaced keys.
  17. How do we add the JOIN?
  18. We simply add a vector to the column set. The first element is the join definition we defined in define-tables and the second element is a set of columns to retrieve from the join table.
  19. We simply add a vector to the column set. The first element is the join definition we defined in define-tables and the second element is a set of columns to retrieve from the join table.
  20. We simply add a vector to the column set. The first element is the join definition we defined in define-tables and the second element is a set of columns to retrieve from the join table.
  21. ClojureScript: speql understands some of the constraints on fields: NOT NULL and string lengths. PostgreSQL columns can be arbitrarily complex objects. You can have an array of a user defined type as a column and specql will work great with that. Upsert: Upsert, which came in pg 9.5, is fully supported. Upsert takes the db, the table keyword, a record map to insert and a where clause for the update Optionally the unique column set to upsert on can also be specified, and defaults to the primary key Views: you can write your complicated queries as views that and spec those like any table.
  22. Although it is a very young library, we are already using it in production in Harja, which is a large public sector application for road infastructure maintenance. We started adding specql to our new features and it has been helpful.