OSDN Git Service

Regular updates master
authorErik <erikgronwal@users.osdn.me>
Thu, 14 Dec 2023 14:55:05 +0000 (23:55 +0900)
committerErik <erikgronwal@users.osdn.me>
Thu, 14 Dec 2023 14:55:05 +0000 (23:55 +0900)
_data/content.yml
_includes/about-the-site.html
bash.md
pry.md
sequel.md
typescript.md

index cb946f2..ca7df3e 100644 (file)
@@ -12,8 +12,8 @@ sheet:
   suffix: cheatsheet
 
 social_list:
-  default_description: "Ridiculous collection of web development cheatsheets"
-  description: "The ultimate cheatsheet for TITLE."
+  default_description: 'Ridiculous collection of web development cheatsheets'
+  description: 'The ultimate cheatsheet for TITLE.'
   facebook_share: Share on Facebook
   twitter_share: Share on Twitter
 
@@ -33,7 +33,7 @@ search_form:
 
 comments_area:
   suffix: for this cheatsheet.
-  link: "Write yours!"
+  link: 'Write yours!'
 
 not_found:
   title: Not found
@@ -41,10 +41,11 @@ not_found:
   home: Back to home
 
 announcement:
-  id: 2017-10-26-twitter
+  # id: 2017-10-26-twitter
+  id: 2023-12-14
   title: |
-    New: We're on Twitter ♥️
+    We're on Twitter ♥️
   body: |
-    Follow [@devhints](https://twitter.com/devhints) on Twitter for daily "today I learned" snippets!
+    Follow [@devhints](https://twitter.com/devhints) on X/Twitter for daily "today I learned" snippets.
 
-    [![](https://img.shields.io/twitter/follow/devhints.svg?style=social&label=@devhints)](https://twitter.com/devhints)
+    Also: I've started a new blog with some insights on web devlopment. Have a look! [**ricostacruz.com/posts**](https://ricostacruz.com/posts?utm_source=devhints)
index de4f487..afdbbb2 100644 (file)
@@ -5,7 +5,7 @@
       Suggestions and corrections? <a href='https://github.com/rstacruz/cheatsheets/issues/907'>Send them in</a>.
       <i class='fleuron'></i>
       I'm <a href="http://ricostacruz.com">Rico Sta. Cruz</a>. 
-      Check out my <a href="http://ricostacruz.com/til">Today I learned blog</a> for more.
+      Check out my <a href="http://ricostacruz.com/posts">Today I learned blog</a> for more.
     </p>
 
     {% if page.url != '/index.html' %}
diff --git a/bash.md b/bash.md
index c079175..b131cf2 100644 (file)
--- a/bash.md
+++ b/bash.md
@@ -14,11 +14,12 @@ keywords:
   - Command substitution
 ---
 
-Getting started
----------------
+## Getting started
+
 {: .-three-column}
 
 ### Introduction
+
 {: .-intro}
 
 This is a quick reference to getting started with Bash scripting.
@@ -44,6 +45,7 @@ echo $name  # see below
 echo "$name"
 echo "${name}!"
 ```
+
 Generally quote your variables unless they contain wildcards to expand or command fragments.
 
 ```bash
@@ -78,6 +80,7 @@ git commit || echo "Commit failed"
 ```
 
 ### Functions
+
 {: id='functions-example'}
 
 ```bash
@@ -91,6 +94,7 @@ echo "You are $(get_name)"
 See: [Functions](#functions)
 
 ### Conditionals
+
 {: id='conditionals-example'}
 
 ```bash
@@ -118,17 +122,17 @@ See: [Unofficial bash strict mode](http://redsymbol.net/articles/unofficial-bash
 echo {A,B}.js
 ```
 
-| Expression | Description         |
-| ---------- | ------------------- |
-| `{A,B}`    | Same as `A B`       |
-| `{A,B}.js` | Same as `A.js B.js` |
-| `{1..5}`   | Same as `1 2 3 4 5` |
+| Expression             | Description           |
+| ---------------------- | --------------------- |
+| `{A,B}`                | Same as `A B`         |
+| `{A,B}.js`             | Same as `A.js B.js`   |
+| `{1..5}`               | Same as `1 2 3 4 5`   |
+| <code>&lcub;{1..3},{7..9}}</code> | Same as `1 2 3 7 8 9` |
 
 See: [Brace expansion](https://web.archive.org/web/20230207192110/https://wiki.bash-hackers.org/syntax/expansion/brace)
 
+## Parameter expansions
 
-Parameter expansions
---------------------
 {: .-three-column}
 
 ### Basics
@@ -247,8 +251,8 @@ echo "${str^^}"  #=> "HELLO WORLD!" (all uppercase)
 
 Omitting the `:` removes the (non)nullity checks, e.g. `${foo-val}` expands to `val` if unset otherwise `$foo`.
 
-Loops
------
+## Loops
+
 {: .-three-column}
 
 ### Basic for loop
@@ -299,8 +303,8 @@ while true; do
 done
 ```
 
-Functions
----------
+## Functions
+
 {: .-three-column}
 
 ### Defining functions
@@ -353,21 +357,21 @@ fi
 
 ### Arguments
 
-| Expression | Description                                      |
-| ---        | ---                                              |
-| `$#`       | Number of arguments                              |
-| `$*`       | All positional arguments  (as a single word)     |
-| `$@`       | All positional arguments (as separate strings)  |
-| `$1`       | First argument                                   |
-| `$_`       | Last argument of the previous command            |
+| Expression | Description                                    |
+| ---------- | ---------------------------------------------- |
+| `$#`       | Number of arguments                            |
+| `$*`       | All positional arguments (as a single word)    |
+| `$@`       | All positional arguments (as separate strings) |
+| `$1`       | First argument                                 |
+| `$_`       | Last argument of the previous command          |
 
 **Note**: `$@` and `$*` must be quoted in order to perform as described.
 Otherwise, they do exactly the same thing (arguments as separate strings).
 
 See [Special parameters](https://web.archive.org/web/20230318164746/https://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).
 
-Conditionals
-------------
+## Conditionals
+
 {: .-three-column}
 
 ### Conditions
@@ -375,7 +379,7 @@ Conditionals
 Note that `[[` is actually a command/program that returns either `0` (true) or `1` (false). Any program that obeys the same logic (like all base utils, such as `grep(1)` or `ping(1)`) can be used as condition, see examples.
 
 | Condition                | Description           |
-| ---                      | ---                   |
+| ------------------------ | --------------------- |
 | `[[ -z STRING ]]`        | Empty string          |
 | `[[ -n STRING ]]`        | Not empty string      |
 | `[[ STRING == STRING ]]` | Equal                 |
@@ -405,7 +409,7 @@ Note that `[[` is actually a command/program that returns either `0` (true) or `
 ### File conditions
 
 | Condition               | Description             |
-| ---                     | ---                     |
+| ----------------------- | ----------------------- |
 | `[[ -e FILE ]]`         | Exists                  |
 | `[[ -r FILE ]]`         | Readable                |
 | `[[ -h FILE ]]`         | Symlink                 |
@@ -461,8 +465,7 @@ if [[ -e "file.txt" ]]; then
 fi
 ```
 
-Arrays
-------
+## Arrays
 
 ### Defining arrays
 
@@ -509,8 +512,8 @@ for i in "${arrayName[@]}"; do
 done
 ```
 
-Dictionaries
-------------
+## Dictionaries
+
 {: .-three-column}
 
 ### Defining
@@ -556,8 +559,7 @@ for key in "${!sounds[@]}"; do
 done
 ```
 
-Options
--------
+## Options
 
 ### Options
 
@@ -581,8 +583,7 @@ shopt -s globstar    # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b
 Set `GLOBIGNORE` as a colon-separated list of patterns to be removed from glob
 matches.
 
-History
--------
+## History
 
 ### Commands
 
@@ -625,9 +626,7 @@ History
 
 `!!` can be replaced with any valid expansion i.e. `!cat`, `!-2`, `!42`, etc.
 
-
-Miscellaneous
--------------
+## Miscellaneous
 
 ### Numeric calculations
 
@@ -640,7 +639,7 @@ $(($RANDOM%200))  # Random number 0..199
 ```
 
 ```bash
-declare -i count  # Declare as type integer 
+declare -i count  # Declare as type integer
 count+=1          # Increment
 ```
 
@@ -732,18 +731,18 @@ printf '%i+%i=%i\n' 1 2 3  4 5 9
 
 ### Transform strings
 
-| Command option     | Description                                         |
-| ------------------ | --------------------------------------------------- |
-| `-c`               | Operations apply to characters not in the given set |
-| `-d`               | Delete characters                                   |
-| `-s`               | Replaces repeated characters with single occurrence |
-| `-t`               | Truncates                                           |
-| `[:upper:]`        | All upper case letters                              |
-| `[:lower:]`        | All lower case letters                              |
-| `[:digit:]`        | All digits                                          |
-| `[:space:]`        | All whitespace                                      |
-| `[:alpha:]`        | All letters                                         |
-| `[:alnum:]`        | All letters and digits                              |
+| Command option | Description                                         |
+| -------------- | --------------------------------------------------- |
+| `-c`           | Operations apply to characters not in the given set |
+| `-d`           | Delete characters                                   |
+| `-s`           | Replaces repeated characters with single occurrence |
+| `-t`           | Truncates                                           |
+| `[:upper:]`    | All upper case letters                              |
+| `[:lower:]`    | All lower case letters                              |
+| `[:digit:]`    | All digits                                          |
+| `[:space:]`    | All whitespace                                      |
+| `[:alpha:]`    | All letters                                         |
+| `[:alnum:]`    | All letters and digits                              |
 
 #### Example
 
@@ -838,10 +837,11 @@ fi
 ```
 
 ## Also see
+
 {: .-one-column}
 
-* [Bash-hackers wiki](https://web.archive.org/web/20230406205817/https://wiki.bash-hackers.org/) _(bash-hackers.org)_
-* [Shell vars](https://web.archive.org/web/20230318164746/https://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
-* [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
-* [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
-* [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
+- [Bash-hackers wiki](https://web.archive.org/web/20230406205817/https://wiki.bash-hackers.org/) _(bash-hackers.org)_
+- [Shell vars](https://web.archive.org/web/20230318164746/https://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
+- [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
+- [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
+- [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
diff --git a/pry.md b/pry.md
index fcb0a3c..8e77b1a 100644 (file)
--- a/pry.md
+++ b/pry.md
@@ -95,7 +95,7 @@ Also consider [pry-rails](https://rubygems.org/gems/pry-rails).
 
     > ls -i      # Instance vars
 
-    > ls -G xx   # Grey by regex
+    > ls -G xx   # Grep by regex
 
 ## Shell integration
 
index c57b600..a15750d 100644 (file)
--- a/sequel.md
+++ b/sequel.md
@@ -5,6 +5,7 @@ layout: 2017/sheet
 ---
 
 ### About
+
 {: .-intro}
 
 Sequel is a database toolkit for Ruby.
@@ -13,382 +14,460 @@ Sequel is a database toolkit for Ruby.
 
 ### Open a database
 
-    require 'rubygems'
-    require 'sequel'
+```
+require 'rubygems'
+require 'sequel'
 
-    DB = Sequel.sqlite('my_blog.db')
-    DB = Sequel.connect('postgres://user:password@localhost/my_db')
-    DB = Sequel.postgres('my_db', :user => 'user', :password => 'password', :host => 'localhost')
-    DB = Sequel.ado('mydb')
+DB = Sequel.sqlite('my_blog.db')
+DB = Sequel.connect('postgres://user:password@localhost/my_db')
+DB = Sequel.postgres('my_db', :user => 'user', :password => 'password', :host => 'localhost')
+DB = Sequel.ado('mydb')
+```
 
 ### Open an SQLite memory database
 
 Without a filename argument, the sqlite adapter will setup a new sqlite database in memory.
 
-    DB = Sequel.sqlite
+```
+DB = Sequel.sqlite
+```
 
 ### Logging SQL statements
 
-    require 'logger'
-    DB = Sequel.sqlite '', :loggers => [Logger.new($stdout)]
-    # or
-    DB.loggers << Logger.new(...)
+```
+require 'logger'
+DB = Sequel.sqlite '', :loggers => [Logger.new($stdout)]
+# or
+DB.loggers << Logger.new(...)
+```
 
 ### Using raw SQL
 
-    DB.run "CREATE TABLE users (name VARCHAR(255) NOT NULL, age INT(3) NOT NULL)"
-    dataset = DB["SELECT age FROM users WHERE name = ?", name]
-    dataset.map(:age)
-    DB.fetch("SELECT name FROM users") do |row|
-      p row[:name]
-    end
+```
+DB.run "CREATE TABLE users (name VARCHAR(255) NOT NULL, age INT(3) NOT NULL)"
+dataset = DB["SELECT age FROM users WHERE name = ?", name]
+dataset.map(:age)
+DB.fetch("SELECT name FROM users") do |row|
+  p row[:name]
+end
+```
 
 ### Create a dataset
 
-    dataset = DB[:items]
-    dataset = DB.from(:items)
+```
+dataset = DB[:items]
+dataset = DB.from(:items)
+```
 
 ### Most dataset methods are chainable
 
-    dataset = DB[:managers].where(:salary => 5000..10000).order(:name, :department)
+```
+dataset = DB[:managers].where(:salary => 5000..10000).order(:name, :department)
+```
 
 ### Insert rows
 
-    dataset.insert(:name => 'Sharon', :grade => 50)
+```
+dataset.insert(:name => 'Sharon', :grade => 50)
+```
 
 ### Retrieve rows
 
-    dataset.each{|r| p r}
-    dataset.all # => [{...}, {...}, ...]
-    dataset.first # => {...}
+```
+dataset.each{|r| p r}
+dataset.all # => [{...}, {...}, ...]
+dataset.first # => {...}
+```
 
 ### Update/Delete rows
 
-    dataset.filter(~:active).delete
-    dataset.filter('price < ?', 100).update(:active => true)
+```
+dataset.filter(~:active).delete
+dataset.filter('price < ?', 100).update(:active => true)
+```
 
 ### Datasets are Enumerable
 
-    dataset.map{|r| r[:name]}
-    dataset.map(:name) # same as above
+```
+dataset.map{|r| r[:name]}
+dataset.map(:name) # same as above
 
-    dataset.inject(0){|sum, r| sum + r[:value]}
-    dataset.sum(:value) # same as above
+dataset.inject(0){|sum, r| sum + r[:value]}
+dataset.sum(:value) # same as above
+```
 
 ### Filtering (see also doc/dataset_filtering.rdoc)
 
 #### Equality
 
-    dataset.filter(:name => 'abc')
-    dataset.filter('name = ?', 'abc')
+```
+dataset.filter(:name => 'abc')
+dataset.filter('name = ?', 'abc')
+```
 
 #### Inequality
 
-    dataset.filter{value > 100}
-    dataset.exclude{value <= 100}
+```
+dataset.filter{value > 100}
+dataset.exclude{value <= 100}
+```
 
 #### Inclusion
 
-    dataset.filter(:value => 50..100)
-    dataset.where{(value >= 50) & (value <= 100)}
+```
+dataset.filter(:value => 50..100)
+dataset.where{(value >= 50) & (value <= 100)}
 
-    dataset.where('value IN ?', [50,75,100])
-    dataset.where(:value=>[50,75,100])
+dataset.where('value IN ?', [50,75,100])
+dataset.where(:value=>[50,75,100])
 
-    dataset.where(:id=>other_dataset.select(:other_id))
+dataset.where(:id=>other_dataset.select(:other_id))
+```
 
 #### Subselects as scalar values
 
-    dataset.where('price > (SELECT avg(price) + 100 FROM table)')
-    dataset.filter{price > dataset.select(avg(price) + 100)}
+```
+dataset.where('price > (SELECT avg(price) + 100 FROM table)')
+dataset.filter{price > dataset.select(avg(price) + 100)}
+```
 
 #### LIKE/Regexp
 
-    DB[:items].filter(:name.like('AL%'))
-    DB[:items].filter(:name => /^AL/)
+```
+DB[:items].filter(:name.like('AL%'))
+DB[:items].filter(:name => /^AL/)
+```
 
 #### AND/OR/NOT
 
-    DB[:items].filter{(x > 5) & (y > 10)}.sql 
-    # SELECT * FROM items WHERE ((x > 5) AND (y > 10))
+```
+DB[:items].filter{(x > 5) & (y > 10)}.sql
+# SELECT * FROM items WHERE ((x > 5) AND (y > 10))
 
-    DB[:items].filter({:x => 1, :y => 2}.sql_or & ~{:z => 3}).sql 
-    # SELECT * FROM items WHERE (((x = 1) OR (y = 2)) AND (z != 3))
+DB[:items].filter({:x => 1, :y => 2}.sql_or & ~{:z => 3}).sql
+# SELECT * FROM items WHERE (((x = 1) OR (y = 2)) AND (z != 3))
+```
 
 #### Mathematical operators
 
-    DB[:items].filter((:x + :y) > :z).sql 
-    # SELECT * FROM items WHERE ((x + y) > z)
+```
+DB[:items].filter((:x + :y) > :z).sql
+# SELECT * FROM items WHERE ((x + y) > z)
 
-    DB[:items].filter{price - 100 < avg(price)}.sql 
-    # SELECT * FROM items WHERE ((price - 100) < avg(price))
+DB[:items].filter{price - 100 < avg(price)}.sql
+# SELECT * FROM items WHERE ((price - 100) < avg(price))
+```
 
 ### Ordering
 
-    dataset.order(:kind)
-    dataset.reverse_order(:kind)
-    dataset.order(:kind.desc, :name)
+```
+dataset.order(:kind)
+dataset.reverse_order(:kind)
+dataset.order(:kind.desc, :name)
+```
 
 ### Limit/Offset
 
-    dataset.limit(30) # LIMIT 30
-    dataset.limit(30, 10) # LIMIT 30 OFFSET 10
+```
+dataset.limit(30) # LIMIT 30
+dataset.limit(30, 10) # LIMIT 30 OFFSET 10
+```
 
 ### Joins
 
-    DB[:items].left_outer_join(:categories, :id => :category_id).sql 
-    # SELECT * FROM items LEFT OUTER JOIN categories ON categories.id = items.category_id
+```
+DB[:items].left_outer_join(:categories, :id => :category_id).sql
+# SELECT * FROM items LEFT OUTER JOIN categories ON categories.id = items.category_id
+
+DB[:items].join(:categories, :id => :category_id).join(:groups, :id => :items__group_id)
+# SELECT * FROM items INNER JOIN categories ON categories.id = items.category_id INNER JOIN groups ON groups.id = items.group_id
+```
 
-    DB[:items].join(:categories, :id => :category_id).join(:groups, :id => :items__group_id) 
-    # SELECT * FROM items INNER JOIN categories ON categories.id = items.category_id INNER JOIN groups ON groups.id = items.group_id
-       
 ### Aggregate functions methods
 
-    dataset.count #=> record count
-    dataset.max(:price)
-    dataset.min(:price)
-    dataset.avg(:price)
-    dataset.sum(:stock)
+```
+dataset.count #=> record count
+dataset.max(:price)
+dataset.min(:price)
+dataset.avg(:price)
+dataset.sum(:stock)
 
-    dataset.group_and_count(:category)
-    dataset.group(:category).select(:category, :AVG.sql_function(:price))
+dataset.group_and_count(:category)
+dataset.group(:category).select(:category, :AVG.sql_function(:price))
+```
 
 ### SQL Functions / Literals
 
-    dataset.update(:updated_at => :NOW.sql_function)
-    dataset.update(:updated_at => 'NOW()'.lit)
+```
+dataset.update(:updated_at => :NOW.sql_function)
+dataset.update(:updated_at => 'NOW()'.lit)
 
-    dataset.update(:updated_at => "DateValue('1/1/2001')".lit)
-    dataset.update(:updated_at => :DateValue.sql_function('1/1/2001'))
+dataset.update(:updated_at => "DateValue('1/1/2001')".lit)
+dataset.update(:updated_at => :DateValue.sql_function('1/1/2001'))
+```
 
 ### Schema Manipulation
 
-    DB.create_table :items do
-      primary_key :id
-      String :name, :unique => true, :null => false
-      TrueClass :active, :default => true
-      foreign_key :category_id, :categories
-      DateTime :created_at
-      
-      index :created_at
-    end
+```
+DB.create_table :items do
+  primary_key :id
+  String :name, :unique => true, :null => false
+  TrueClass :active, :default => true
+  foreign_key :category_id, :categories
+  DateTime :created_at
 
-    DB.drop_table :items
+  index :created_at
+end
 
-    DB.create_table :test do
-      String :zipcode
-      enum :system, :elements => ['mac', 'linux', 'windows']
-    end
+DB.drop_table :items
+
+DB.create_table :test do
+  String :zipcode
+  enum :system, :elements => ['mac', 'linux', 'windows']
+end
+```
 
 ### Aliasing
 
-    DB[:items].select(:name.as(:item_name))
-    DB[:items].select(:name___item_name)
-    DB[:items___items_table].select(:items_table__name___item_name)
-    # SELECT items_table.name AS item_name FROM items AS items_table
+```
+DB[:items].select(:name.as(:item_name))
+DB[:items].select(:name___item_name)
+DB[:items___items_table].select(:items_table__name___item_name)
+# SELECT items_table.name AS item_name FROM items AS items_table
+```
 
 ### Transactions
 
-    DB.transaction do
-      dataset.insert(:first_name => 'Inigo', :last_name => 'Montoya')
-      dataset.insert(:first_name => 'Farm', :last_name => 'Boy')
-    end # Either both are inserted or neither are inserted
+```
+DB.transaction do
+  dataset.insert(:first_name => 'Inigo', :last_name => 'Montoya')
+  dataset.insert(:first_name => 'Farm', :last_name => 'Boy')
+end # Either both are inserted or neither are inserted
+```
 
 Database#transaction is re-entrant:
 
-    DB.transaction do # BEGIN issued only here
-      DB.transaction
-        dataset << {:first_name => 'Inigo', :last_name => 'Montoya'}
-      end
-    end # COMMIT issued only here
+```
+DB.transaction do # BEGIN issued only here
+  DB.transaction
+    dataset << {:first_name => 'Inigo', :last_name => 'Montoya'}
+  end
+end # COMMIT issued only here
+```
 
 Transactions are aborted if an error is raised:
 
-    DB.transaction do
-      raise "some error occurred"
-    end # ROLLBACK issued and the error is re-raised
+```
+DB.transaction do
+  raise "some error occurred"
+end # ROLLBACK issued and the error is re-raised
+```
 
 Transactions can also be aborted by raising Sequel::Rollback:
 
-    DB.transaction do
-      raise(Sequel::Rollback) if something_bad_happened
-    end # ROLLBACK issued and no error raised
+```
+DB.transaction do
+  raise(Sequel::Rollback) if something_bad_happened
+end # ROLLBACK issued and no error raised
+```
 
 Savepoints can be used if the database supports it:
 
-    DB.transaction do
-      dataset << {:first_name => 'Farm', :last_name => 'Boy'} # Inserted
-      DB.transaction(:savepoint=>true) # This savepoint is rolled back
-        dataset << {:first_name => 'Inigo', :last_name => 'Montoya'} # Not inserted
-        raise(Sequel::Rollback) if something_bad_happened
-      end
-      dataset << {:first_name => 'Prince', :last_name => 'Humperdink'} # Inserted
-    end
+```
+DB.transaction do
+  dataset << {:first_name => 'Farm', :last_name => 'Boy'} # Inserted
+  DB.transaction(:savepoint=>true) # This savepoint is rolled back
+    dataset << {:first_name => 'Inigo', :last_name => 'Montoya'} # Not inserted
+    raise(Sequel::Rollback) if something_bad_happened
+  end
+  dataset << {:first_name => 'Prince', :last_name => 'Humperdink'} # Inserted
+end
+```
 
 ### Miscellaneous:
 
-    dataset.sql # "SELECT * FROM items"
-    dataset.delete_sql # "DELETE FROM items"
-    dataset.where(:name => 'sequel').exists # "EXISTS ( SELECT * FROM items WHERE name = 'sequel' )"
-    dataset.columns #=> array of columns in the result set, does a SELECT
-    DB.schema(:items) => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
+```
+dataset.sql # "SELECT * FROM items"
+dataset.delete_sql # "DELETE FROM items"
+dataset.where(:name => 'sequel').exists # "EXISTS ( SELECT * FROM items WHERE name = 'sequel' )"
+dataset.columns #=> array of columns in the result set, does a SELECT
+DB.schema(:items) => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
+```
 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
+---
 
 ### Documents
 
-    http://sequel.rubyforge.org/rdoc/files/doc/association_basics_rdoc.html
-    http://sequel.rubyforge.org/rdoc/classes/Sequel/Schema/Generator.html
-    http://sequel.rubyforge.org/rdoc/files/doc/validations_rdoc.html
-    http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html
+```
+http://sequel.rubyforge.org/rdoc/files/doc/association_basics_rdoc.html
+http://sequel.rubyforge.org/rdoc/classes/Sequel/Schema/Generator.html
+http://sequel.rubyforge.org/rdoc/files/doc/validations_rdoc.html
+http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html
+```
 
 ### Alter table
 
-    database.alter_table :deals do
-      add_column :name, String
-      drop_column :column_name
-      rename_column :from, :to
+```
+database.alter_table :deals do
+  add_column :name, String
+  drop_column :column_name
+  rename_column :from, :to
 
-      add_constraint :valid_name, :name.like('A%')
-      drop_constraint :constraint
+  add_constraint :valid_name, :name.like('A%')
+  drop_constraint :constraint
 
-      add_full_text_index :body
-      add_spacial_index [columns]
+  add_full_text_index :body
+  add_spacial_index [columns]
 
-      add_index :price
-      drop_index :index
+  add_index :price
+  drop_index :index
 
-      add_foreign_key :artist_id, :table
-      add_primary_key :id
-      add_unique_constraint [columns]
-      set_column_allow_null :foo, false
-      set_column_default :title, ''
+  add_foreign_key :artist_id, :table
+  add_primary_key :id
+  add_unique_constraint [columns]
+  set_column_allow_null :foo, false
+  set_column_default :title, ''
 
-      set_column_type :price, 'char(10)'
-    end
+  set_column_type :price, 'char(10)'
+end
+```
 
 ### Model associations
 
-    class Deal < Sequel::Model
+```
+class Deal < Sequel::Model
 
-      # Us (left) <=> Them (right)
-      many_to_many  :images,
-        left_id:    :deal_id,
-        right_id:   :image_id,
-        join_table: :image_links
+  # Us (left) <=> Them (right)
+  many_to_many  :images,
+    left_key:   :deal_id,
+    right_key:  :image_id,
+    join_table: :image_links
 
-      one_to_many   :files,
-        key:        :deal_id,
-        class:      :DataFile,
+  one_to_many   :files,
+    key:        :deal_id,
+    class:      :DataFile,
 
-      many_to_one   :parent, class: self
-      one_to_many   :children, key: :parent_id, class: self
+  many_to_one   :parent, class: self
+  one_to_many   :children, key: :parent_id, class: self
 
-      one_to_many :gold_albums, class: :Album do |ds|
-        ds.filter { copies_sold > 50000 }
-      end
+  one_to_many :gold_albums, class: :Album do |ds|
+    ds.filter { copies_sold > 50000 }
+  end
+```
 
 Provided by many_to_many
 
-    Deal[1].images
-    Deal[1].add_image
-    Deal[1].remove_image
-    Deal[1].remove_all_images
+```
+Deal[1].images
+Deal[1].add_image
+Deal[1].remove_image
+Deal[1].remove_all_images
+```
 
 ### Validations
 
-      def validate
-        super
-        errors.add(:name, 'cannot be empty') if !name || name.empty?
-
-        validates_presence [:title, :site]
-        validates_unique :name
-        validates_format /\Ahttps?:\/\//, :website, :message=>'is not a valid URL'
-        validates_includes %w(a b c), :type
-        validates_integer :rating
-        validates_numeric :number
-        validates_type String, [:title, :description]
-
-        validates_integer :rating  if new?
-
-        # options: :message =>, :allow_nil =>, :allow_blank =>,
-        #          :allow_missing =>,
-
-        validates_exact_length 17, :isbn
-        validates_min_length 3, :name
-        validates_max_length 100, :name
-        validates_length_range 3..100, :name
-        
-        # Setter override
-        def filename=(name)
-          @values[:filename] = name
-        end
-      end
+```
+def validate
+    super
+    errors.add(:name, 'cannot be empty') if !name || name.empty?
+
+    validates_presence [:title, :site]
+    validates_unique :name
+    validates_format /\Ahttps?:\/\//, :website, :message=>'is not a valid URL'
+    validates_includes %w(a b c), :type
+    validates_integer :rating
+    validates_numeric :number
+    validates_type String, [:title, :description]
+
+    validates_integer :rating  if new?
+
+    # options: :message =>, :allow_nil =>, :allow_blank =>,
+    #          :allow_missing =>,
+
+    validates_exact_length 17, :isbn
+    validates_min_length 3, :name
+    validates_max_length 100, :name
+    validates_length_range 3..100, :name
+
+    # Setter override
+    def filename=(name)
+      @values[:filename] = name
     end
+  end
+end
 
-    deal.errors
+deal.errors
+```
 
 ### Model stuff
 
-    deal = Deal[1]
-    deal.changed_columns
-    deal.destroy  # Calls hooks
-    deal.delete   # No hooks
-    deal.exists?
-    deal.new?
-    deal.hash  # Only uniques
-    deal.keys  #=> [:id, :name]
-    deal.modified!
-    deal.modified?
-
-    deal.lock!
+```
+deal = Deal[1]
+deal.changed_columns
+deal.destroy  # Calls hooks
+deal.delete   # No hooks
+deal.exists?
+deal.new?
+deal.hash  # Only uniques
+deal.keys  #=> [:id, :name]
+deal.modified!
+deal.modified?
+
+deal.lock!
+```
 
 ### Callbacks
 
-    before_create
-    after_create
+```
+before_create
+after_create
 
-    before_validation
-    after_validation
-    before_save
-    before_update
-    UPDATE QUERY
-    after_update
-    after_save
+before_validation
+after_validation
+before_save
+before_update
+UPDATE QUERY
+after_update
+after_save
 
-    before_destroy
-    DELETE QUERY
-    after_destroy
+before_destroy
+DELETE QUERY
+after_destroy
+```
 
 ### Schema
 
-    class Deal < Sequel::Model
-      set_schema do
-        primary_key :id
-        primary_key [:id, :title]
-        String :name, primary_key: true
-        
-        String  :title
-        Numeric :price
-        DateTime :expires
-
-        unique :whatever
-        check(:price) { num > 0 }
-
-        foreign_key :artist_id
-        String :artist_name, key: :id
-
-        index :title
-        index [:artist_id, :name]
-        full_text_index :title
-
-        # String, Integer, Fixnum, Bignum, Float, Numeric, BigDecimal,
-        # Date, DateTime, Time, File, TrueClass, FalseClass
-      end
-    end
+```
+class Deal < Sequel::Model
+  set_schema do
+    primary_key :id
+    primary_key [:id, :title]
+    String :name, primary_key: true
+
+    String  :title
+    Numeric :price
+    DateTime :expires
+
+    unique :whatever
+    check(:price) { num > 0 }
+
+    foreign_key :artist_id
+    String :artist_name, key: :id
+
+    index :title
+    index [:artist_id, :name]
+    full_text_index :title
+
+    # String, Integer, Fixnum, Bignum, Float, Numeric, BigDecimal,
+    # Date, DateTime, Time, File, TrueClass, FalseClass
+  end
+end
+```
 
 ### Unrestrict primary key
 
-    Category.create id: 'travel'   # error
-    Category.unrestrict_primary_key
-    Category.create id: 'travel'   # ok
+```
+Category.create id: 'travel'   # error
+Category.unrestrict_primary_key
+Category.create id: 'travel'   # ok
+```
index d9cd501..7a4e6e7 100644 (file)
@@ -244,7 +244,7 @@ type Point = { x: number; y: number };
 type P = keyof Point; // x | y
 ```
 
-## Conditinal Types
+## Conditional Types
 
 ```ts
 // SomeType extends OtherType ? TrueType : FalseType;