Skip to content

Instantly share code, notes, and snippets.

@kanmeiban
Last active January 19, 2018 10:23
Show Gist options
  • Save kanmeiban/7890642 to your computer and use it in GitHub Desktop.
Save kanmeiban/7890642 to your computer and use it in GitHub Desktop.
RUR: A modern Ruby replacement of SQL
# RUR (Relationally Universal Ruby) is a Ruby relational algebra DSL
# that compiles to SQL, allowing you to write complex
# queries without leaving your favorite language. It is going to be a nice
# Ruby-like replacement of SQL in the same manner CoffeeScript is a
# Ruby-like replacement of JavaScript. It will use all the features
# found in a modern RDBMS (views, temp views, constraints, triggers, functions,
# etc) without being tightly coupled to one particular implementation.
#
# Unlike ActiveRecord, which maps tables to classes, RUR maps relations to
# objects.
#
# Like Sequel, RUR uses a global object to interact with the database.
#
# An example of a complex query that would be possible to be written in RUR
# without resorting to SQL in any form, with no SQL leaking in your code:
#
# CREATE OR REPLACE TEMP VIEW profit_by_month AS (
# SELECT to_month(sales_drill.date) AS month,
# SUM("profit in EUR ")::int AS profit
# FROM "tutuf::visual_query"."Sales Drill" AS sales_drill
# GROUP BY month);
#
# CREATE OR REPLACE TEMP VIEW product_types_profit_by_month AS(
# WITH filler AS (
# SELECT DISTINCT generate_series('2013-11-01'::date,
# '2013-12-04'::date,
# '1 month')::timestamp without time zone AS date,
# specific_type AS product_type
# FROM products)
# SELECT COALESCE(to_month(filler.date), to_month(sales_drill.date)) AS period,
# product_type,
# COALESCE( SUM("profit in EUR ")::int, 0) AS profit
# FROM "tutuf::visual_query"."Sales Drill" AS sales_drill
# RIGHT JOIN filler ON to_month(filler.date) = to_month(sales_drill.date)
# AND filler.product_type = sales_drill.type
# WHERE date BETWEEN '2013-11-01' AND '2013-12-04'
# GROUP BY period,
# product_type
# ORDER BY period DESC,
# profit DESC);
#
# SELECT product_type,
# period,
# (100 * product_types_profit_by_month.profit::numeric(10,2) /
# profit_by_month.profit::numeric(10,2))::numeric(10,2) AS "% profit"
# FROM profit_by_month
# JOIN product_types_profit_by_month ON profit_by_month.month =
# product_types_profit_by_month.period ORDER BY "% profit" DESC
#
#
# Some simpler examples to help you get a notion of RUR:
# load relations from the database
tablets = DB['tablets']
brands = DB['brands']
# read metadata about relations that is stored in the database only
tablets.associations
# => [DB['brands']]
# math notation for relational algebra operations
tablet_brands = tablets × brands
tablet_brand_names = tablet_brands[brands.name]
# idiomatic Ruby code for idiomatic operations
users = Table.create(id: serial,
name: string(unique),
admin: boolean(default: false))
users.insert(name: clients.name)
admins = View.create(users[admin: true])
# support for PostgreSQL schemas
ekont.cities.insert( ... )
@kanmeiban
Copy link
Author

FitNesse is the acceptance test wiki (Java)

@kanmeiban
Copy link
Author

Idiomatic ruby:

Version.find_by_name('TODO')
  .fixed_issues
  .map{ |issue| issue.category }
  .uniq

... and ActiveRecord:

 IssueCategory.joins(
      'RIGHT JOIN issues ON issue_categories.id = issues.category_id
       JOIN versions ON issues.fixed_version_id = versions.id')
    .where("versions.name='TODO'")
    .distinct
    .order(:name)

@kanmeiban
Copy link
Author

Dataflow in Ruby – code in terms of a pipeline for data, transforming it and summarizing it into information.
dataflow visualisation
Our job is not to write software. Our job is to turn data into information. That we do that through software is an implementation detail.

@kanmeiban
Copy link
Author

Squeel lets you rewrite...

Article.where ['created_at >= ?', 2.weeks.ago]

...as...

Article.where{created_at >= 2.weeks.ago}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment