diff --git a/.editorconfig b/.editorconfig index 538ba2b..a6e7d26 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,3 +3,7 @@ root = true [*] indent_style = tab indent_size = 2 + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 diff --git a/.github/workflows/documentation-coverage.yaml b/.github/workflows/documentation-coverage.yaml new file mode 100644 index 0000000..b3bac9a --- /dev/null +++ b/.github/workflows/documentation-coverage.yaml @@ -0,0 +1,25 @@ +name: Documentation Coverage + +on: [push, pull_request] + +permissions: + contents: read + +env: + CONSOLE_OUTPUT: XTerm + COVERAGE: PartialSummary + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" + bundler-cache: true + + - name: Validate coverage + timeout-minutes: 5 + run: bundle exec bake decode:index:coverage lib diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml new file mode 100644 index 0000000..f5f553a --- /dev/null +++ b/.github/workflows/documentation.yaml @@ -0,0 +1,58 @@ +name: Documentation + +on: + push: + branches: + - main + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages: +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment: +concurrency: + group: "pages" + cancel-in-progress: true + +env: + CONSOLE_OUTPUT: XTerm + BUNDLE_WITH: maintenance + +jobs: + generate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" + bundler-cache: true + + - name: Installing packages + run: sudo apt-get install wget + + - name: Generate documentation + timeout-minutes: 5 + run: bundle exec bake utopia:project:static --force no + + - name: Upload documentation artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs + + deploy: + runs-on: ubuntu-latest + + environment: + name: github-pages + url: ${{steps.deployment.outputs.page_url}} + + needs: generate + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml deleted file mode 100644 index 61956e9..0000000 --- a/.github/workflows/documentation.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Documentation - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 - env: - BUNDLE_WITH: maintenance - with: - ruby-version: 3.0 - bundler-cache: true - - - name: Installing packages - run: sudo apt-get install wget - - - name: Generate documentation - timeout-minutes: 5 - run: bundle exec bake utopia:project:static - - - name: Deploy documentation - uses: JamesIves/github-pages-deploy-action@4.0.0 - with: - branch: docs - folder: docs diff --git a/.github/workflows/rubocop.yaml b/.github/workflows/rubocop.yaml new file mode 100644 index 0000000..72fcc53 --- /dev/null +++ b/.github/workflows/rubocop.yaml @@ -0,0 +1,24 @@ +name: RuboCop + +on: [push, pull_request] + +permissions: + contents: read + +env: + CONSOLE_OUTPUT: XTerm + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby + bundler-cache: true + + - name: Run RuboCop + timeout-minutes: 10 + run: bundle exec rubocop diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..f3f52c4 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,92 @@ +name: Test Coverage + +on: [push, pull_request] + +permissions: + contents: read + +env: + CONSOLE_OUTPUT: XTerm + COVERAGE: PartialSummary + +jobs: + test: + name: ${{matrix.ruby}} on ${{matrix.os}} + runs-on: ${{matrix.os}}-latest + + strategy: + matrix: + os: + - ubuntu + + ruby: + - "3.3" + + services: + postgres: + image: postgres + ports: + - 5432:5432 + env: + POSTGRES_USER: test + POSTGRES_PASSWORD: test + POSTGRES_DB: test + POSTGRES_HOST_AUTH_METHOD: trust + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 20 + mariadb: + image: mariadb + ports: + - 3306:3306 + env: + MARIADB_USER: test + MARIADB_PASSWORD: test + MARIADB_DATABASE: test + MARIADB_ROOT_PASSWORD: test + options: >- + --health-cmd "healthcheck.sh --connect --innodb_initialized" + --health-interval 10s + --health-timeout 5s + --health-retries 20 + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{matrix.ruby}} + bundler-cache: true + + - name: Installing dependencies (ubuntu) + if: matrix.os == 'ubuntu' + run: | + sudo systemctl stop mysql + sudo apt-get install libmariadb-dev postgresql postgresql-contrib + + - name: Run tests + timeout-minutes: 5 + run: bundle exec bake test + + - uses: actions/upload-artifact@v3 + with: + name: coverage-${{matrix.os}}-${{matrix.ruby}} + path: .covered.db + + validate: + needs: test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" + bundler-cache: true + + - uses: actions/download-artifact@v3 + + - name: Validate coverage + timeout-minutes: 5 + run: bundle exec bake covered:validate --paths */.covered.db \; diff --git a/.github/workflows/test-external.yaml b/.github/workflows/test-external.yaml new file mode 100644 index 0000000..6160be2 --- /dev/null +++ b/.github/workflows/test-external.yaml @@ -0,0 +1,71 @@ +name: Test External + +on: [push, pull_request] + +permissions: + contents: read + +env: + CONSOLE_OUTPUT: XTerm + +jobs: + test: + name: ${{matrix.ruby}} on ${{matrix.os}} + runs-on: ${{matrix.os}}-latest + + strategy: + matrix: + os: + - ubuntu + + ruby: + - "3.1" + - "3.2" + - "3.3" + + services: + postgres: + image: postgres + ports: + - 5432:5432 + env: + POSTGRES_USER: test + POSTGRES_PASSWORD: test + POSTGRES_DB: test + POSTGRES_HOST_AUTH_METHOD: trust + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 20 + mariadb: + image: mariadb + ports: + - 3306:3306 + env: + MARIADB_USER: test + MARIADB_PASSWORD: test + MARIADB_DATABASE: test + MARIADB_ROOT_PASSWORD: test + options: >- + --health-cmd "healthcheck.sh --connect --innodb_initialized" + --health-interval 10s + --health-timeout 5s + --health-retries 20 + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{matrix.ruby}} + bundler-cache: true + + - name: Installing dependencies (ubuntu) + if: matrix.os == 'ubuntu' + run: | + sudo systemctl stop mysql + sudo apt-get install libmariadb-dev postgresql postgresql-contrib + + - name: Run tests + timeout-minutes: 10 + run: bundle exec bake test:external diff --git a/.github/workflows/development.yml b/.github/workflows/test.yaml similarity index 74% rename from .github/workflows/development.yml rename to .github/workflows/test.yaml index 7de4c96..c0e2d47 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/test.yaml @@ -1,7 +1,13 @@ -name: Development +name: Test on: [push, pull_request] +permissions: + contents: read + +env: + CONSOLE_OUTPUT: XTerm + jobs: test: name: ${{matrix.ruby}} on ${{matrix.os}} @@ -14,12 +20,11 @@ jobs: - ubuntu ruby: - - "2.6" - - "2.7" - - "3.0" + - "3.1" + - "3.2" + - "3.3" experimental: [false] - env: [""] include: - os: ubuntu @@ -28,7 +33,6 @@ jobs: - os: ubuntu ruby: jruby experimental: true - env: JRUBY_OPTS="--debug -X+O" - os: ubuntu ruby: head experimental: true @@ -48,24 +52,23 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 20 - mariadb: image: mariadb ports: - 3306:3306 env: - MYSQL_USER: test - MYSQL_PASSWORD: test - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: test + MARIADB_USER: test + MARIADB_PASSWORD: test + MARIADB_DATABASE: test + MARIADB_ROOT_PASSWORD: test options: >- - --health-cmd "mysqladmin ping" + --health-cmd "healthcheck.sh --connect --innodb_initialized" --health-interval 10s --health-timeout 5s --health-retries 20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{matrix.ruby}} @@ -75,8 +78,8 @@ jobs: if: matrix.os == 'ubuntu' run: | sudo systemctl stop mysql - sudo apt-get install postgresql postgresql-contrib libmariadb-dev + sudo apt-get install libmariadb-dev postgresql postgresql-contrib - name: Run tests - timeout-minutes: 5 - run: ${{matrix.env}} bundle exec rspec + timeout-minutes: 10 + run: bundle exec bake test diff --git a/.gitignore b/.gitignore index 3468ed5..09a72e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,5 @@ /.bundle/ -/.yardoc -/_yardoc/ -/coverage/ -/doc/ /pkg/ -/spec/reports/ -/tmp/ - -# rspec failure tracking -.rspec_status -gems.locked +/gems.locked +/.covered.db +/external diff --git a/.rspec b/.rspec deleted file mode 100644 index 0b77ab1..0000000 --- a/.rspec +++ /dev/null @@ -1,3 +0,0 @@ ---format documentation ---warnings ---require spec_helper diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..442c667 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,46 @@ +AllCops: + DisabledByDefault: true + +Layout/IndentationStyle: + Enabled: true + EnforcedStyle: tabs + +Layout/InitialIndentation: + Enabled: true + +Layout/IndentationWidth: + Enabled: true + Width: 1 + +Layout/IndentationConsistency: + Enabled: true + EnforcedStyle: normal + +Layout/EndAlignment: + Enabled: true + EnforcedStyleAlignWith: start_of_line + +Layout/BeginEndAlignment: + Enabled: true + EnforcedStyleAlignWith: start_of_line + +Layout/ElseAlignment: + Enabled: true + +Layout/DefEndAlignment: + Enabled: true + +Layout/CaseIndentation: + Enabled: true + +Layout/CommentIndentation: + Enabled: true + +Layout/EmptyLinesAroundClassBody: + Enabled: true + +Layout/EmptyLinesAroundModuleBody: + Enabled: true + +Style/FrozenStringLiteralComment: + Enabled: true diff --git a/README.md b/README.md deleted file mode 100644 index 248ca25..0000000 --- a/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# DB - -Provides event-driven asynchronous drivers for various database adaptors, including [Postgres](https://github.com/socketry/db-postgres) and [MariaDB/MySQL](https://github.com/socketry/db-mariadb). - -[![Development Status](https://github.com/socketry/db/workflows/Development/badge.svg)](https://github.com/socketry/db/actions?workflow=Development) - -## Features - - - Event driven I/O for streaming queries and results. - - Standard interface for multiple database adapters. - -## Usage - -Please see the [project documentation](https://socketry.github.io/db). - -## Contributing - -We welcome contributions to this project. - -1. Fork it. -2. Create your feature branch (`git checkout -b my-new-feature`). -3. Commit your changes (`git commit -am 'Add some feature'`). -4. Push to the branch (`git push origin my-new-feature`). -5. Create new Pull Request. - -## License - -Copyright, 2020, by [Samuel G. D. Williams](https://www.codeotaku.com). - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/spec/db/benchmark_spec.rb b/benchmark/benchmark.rb similarity index 70% rename from spec/db/benchmark_spec.rb rename to benchmark/benchmark.rb index e49b641..90ab0a5 100644 --- a/spec/db/benchmark_spec.rb +++ b/benchmark/benchmark.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2019, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require 'benchmark/ips' require 'async' @@ -29,7 +12,7 @@ require 'mysql2' require 'pg' -RSpec.describe DB::Client do +describe DB::Client do it "should be fast to insert data" do Benchmark.ips do |x| DB::Adapters.each do |name, klass| diff --git a/benchmark/compare/.bundle/config b/benchmark/compare/.bundle/config new file mode 100644 index 0000000..98f851b --- /dev/null +++ b/benchmark/compare/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_WITH: "maintenance" diff --git a/benchmark/compare/config.ru b/benchmark/compare/config.ru index 56aa2eb..754ec33 100644 --- a/benchmark/compare/config.ru +++ b/benchmark/compare/config.ru @@ -1,3 +1,8 @@ +# frozen_string_literal: true + +require 'active_support' +ActiveSupport::IsolatedExecutionState.isolation_level = :fiber + require 'active_record' ActiveRecord::Base.establish_connection(adapter: "postgresql", database: "test", pool: 64) @@ -53,6 +58,8 @@ class Compare @db.session do |session| session.query("SELECT pg_sleep(1)").call end + + puts @db.instance_variable_get(:@pool).to_s end OK diff --git a/benchmark/compare/gems.rb b/benchmark/compare/gems.rb index 7e05ca1..862d1b3 100644 --- a/benchmark/compare/gems.rb +++ b/benchmark/compare/gems.rb @@ -1,8 +1,13 @@ +# frozen_string_literal: true +# Released under the MIT License. +# Copyright, 2021-2024, by Samuel Williams. + source "https://rubygems.org" gem "falcon" +gem "rack", "~> 2.0" -gem "activerecord" +gem "rails", git: "https://github.com/rails/rails" gem "mysql2" gem "pg" diff --git a/config/sus.rb b/config/sus.rb new file mode 100644 index 0000000..af0ab98 --- /dev/null +++ b/config/sus.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. + +require 'covered/sus' +include Covered::Sus + +Bundler.require(:adapters) + +::CREDENTIALS = { + username: 'test', + password: 'test', + database: 'test', + host: '127.0.0.1' +} + +# Used for PG.connect: +::PG_CREDENTIALS = CREDENTIALS.dup.tap do |credentials| + credentials[:user] = credentials.delete(:username) + credentials[:dbname] = credentials.delete(:database) +end diff --git a/db.gemspec b/db.gemspec index 91d1f85..f496b3e 100644 --- a/db.gemspec +++ b/db.gemspec @@ -1,3 +1,4 @@ +# frozen_string_literal: true require_relative "lib/db/version" @@ -14,14 +15,15 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/socketry/db" - spec.files = Dir.glob('{lib}/**/*', File::FNM_DOTMATCH, base: __dir__) + spec.metadata = { + "documentation_uri" => "https://socketry.github.io/db/", + "funding_uri" => "https://github.com/sponsors/ioquatix", + "source_code_uri" => "https://github.com/socketry/db.git", + } - spec.required_ruby_version = ">= 2.5" + spec.files = Dir.glob(['{lib}/**/*', '*.md'], File::FNM_DOTMATCH, base: __dir__) - spec.add_dependency "async-io" - spec.add_dependency "async-pool" + spec.required_ruby_version = ">= 3.1" - spec.add_development_dependency "bundler" - spec.add_development_dependency "covered" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_dependency "async-pool" end diff --git a/examples/indexes.rb b/examples/indexes.rb index 7a5a8e1..bcf58ca 100755 --- a/examples/indexes.rb +++ b/examples/indexes.rb @@ -1,4 +1,8 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2021-2024, by Samuel Williams. require 'async' require_relative '../lib/db/client' diff --git a/examples/model.rb b/examples/model.rb new file mode 100644 index 0000000..9db48ce --- /dev/null +++ b/examples/model.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2024, by Samuel Williams. + +module LoginSchema + include DB::Schema + + class User + property :name + property :password, BCrypt + end + + has_many :users, User + + def call(username, password) + if user = users.find(username: username) + return user.password == password + end + end +end + +module TodoSchema + include DB::Schema + + class Item + property :description + property :due, Optional[DateTime] + + belongs_to :user, LoginSchema::User + end + + has_many :items, Item +end + +module AppliationSchema + include DB::Schema + + schema :login => LoginSchema + schema :todo => TodoSchema +end + +client = DB::Client.new(DB::Postgres::Adapter.new(database: 'test')) +schema = ApplicationSchema.new(client) + +schema.login.call(username, password) + +pp schema.todo.todos # => [TodoSchema::Todo, ...] diff --git a/gems.rb b/gems.rb index 34b68a1..819670e 100644 --- a/gems.rb +++ b/gems.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. + source "https://rubygems.org" # Specify your gem's dependencies in db.gemspec @@ -20,3 +24,15 @@ gem "mysql2" gem "pg" end + +group :test do + gem "sus" + gem "covered" + gem "decode" + gem "rubocop" + + gem "sus-fixtures-async" + + gem "bake-test" + gem "bake-test-external" +end diff --git a/lib/db.rb b/lib/db.rb index 3ddf306..5cdeaf0 100644 --- a/lib/db.rb +++ b/lib/db.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require_relative 'db/version' require_relative 'db/adapters' diff --git a/lib/db/adapters.rb b/lib/db/adapters.rb index 0a578c8..7303e0e 100644 --- a/lib/db/adapters.rb +++ b/lib/db/adapters.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. module DB # A global map of registered adapters. diff --git a/lib/db/client.rb b/lib/db/client.rb index e876756..8e57e31 100644 --- a/lib/db/client.rb +++ b/lib/db/client.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require 'async/io' require 'async/io/stream' diff --git a/lib/db/context/session.rb b/lib/db/context/session.rb index 6d3e456..686bdab 100644 --- a/lib/db/context/session.rb +++ b/lib/db/context/session.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2021, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require_relative '../query' require_relative '../records' diff --git a/lib/db/context/transaction.rb b/lib/db/context/transaction.rb index 3792499..ff3f200 100644 --- a/lib/db/context/transaction.rb +++ b/lib/db/context/transaction.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require_relative 'session' diff --git a/lib/db/context/transient.rb b/lib/db/context/transient.rb index e84dfde..8e2e75b 100644 --- a/lib/db/context/transient.rb +++ b/lib/db/context/transient.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2021, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. require_relative 'session' diff --git a/lib/db/query.rb b/lib/db/query.rb index c1d2906..ad56aea 100644 --- a/lib/db/query.rb +++ b/lib/db/query.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. module DB # Represents one or more identifiers for databases, tables or columns. diff --git a/lib/db/records.rb b/lib/db/records.rb index a1b9973..4956074 100644 --- a/lib/db/records.rb +++ b/lib/db/records.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2021-2024, by Samuel Williams. module DB # A buffer of records. diff --git a/lib/db/version.rb b/lib/db/version.rb index 64b733a..80f6e31 100644 --- a/lib/db/version.rb +++ b/lib/db/version.rb @@ -1,24 +1,7 @@ # frozen_string_literal: true -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. module DB VERSION = "0.10.3" diff --git a/license.md b/license.md new file mode 100644 index 0000000..2e71de4 --- /dev/null +++ b/license.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright, 2020-2024, by Samuel Williams. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..c0c3cb7 --- /dev/null +++ b/readme.md @@ -0,0 +1,32 @@ +# DB + +Provides event-driven asynchronous drivers for various database adaptors, including [Postgres](https://github.com/socketry/db-postgres) and [MariaDB/MySQL](https://github.com/socketry/db-mariadb). + +[![Development Status](https://github.com/socketry/db/workflows/Test/badge.svg)](https://github.com/socketry/db/actions?workflow=Test) + +## Features + + - Event driven I/O for streaming queries and results. + - Standard interface for multiple database adapters. + +## Usage + +Please see the [project documentation](https://socketry.github.io/db). + +## Contributing + +We welcome contributions to this project. + +1. Fork it. +2. Create your feature branch (`git checkout -b my-new-feature`). +3. Commit your changes (`git commit -am 'Add some feature'`). +4. Push to the branch (`git push origin my-new-feature`). +5. Create new Pull Request. + +### Developer Certificate of Origin + +In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed. + +### Community Guidelines + +This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers. diff --git a/release.cert b/release.cert index f036666..d98e595 100644 --- a/release.cert +++ b/release.cert @@ -1,27 +1,28 @@ -----BEGIN CERTIFICATE----- -MIIEhDCCAuygAwIBAgIBATANBgkqhkiG9w0BAQsFADA3MTUwMwYDVQQDDCxzYW11 -ZWwud2lsbGlhbXMvREM9b3Jpb250cmFuc2Zlci9EQz1jby9EQz1uejAeFw0yMTA4 -MTYwNjMzNDRaFw0yMjA4MTYwNjMzNDRaMDcxNTAzBgNVBAMMLHNhbXVlbC53aWxs -aWFtcy9EQz1vcmlvbnRyYW5zZmVyL0RDPWNvL0RDPW56MIIBojANBgkqhkiG9w0B -AQEFAAOCAY8AMIIBigKCAYEAyXLSS/cw+fXJ5e7hi+U/TeChPWeYdwJojDsFY1xr -xvtqbTTL8gbLHz5LW3QD2nfwCv3qTlw0qI3Ie7a9VMJMbSvgVEGEfQirqIgJXWMj -eNMDgKsMJtC7u/43abRKx7TCURW3iWyR19NRngsJJmaR51yGGGm2Kfsr+JtKKLtL -L188Wm3f13KAx7QJU8qyuBnj1/gWem076hzdA7xi1DbrZrch9GCRz62xymJlrJHn -9iZEZ7AxrS7vokhMlzSr/XMUihx/8aFKtk+tMLClqxZSmBWIErWdicCGTULXCBNb -E/mljo4zEVKhlTWpJklMIhr55ZRrSarKFuW7en0+tpJrfsYiAmXMJNi4XAYJH7uL -rgJuJwSaa/dMz+VmUoo7VKtSfCoOI+6v5/z0sK3oT6sG6ZwyI47DBq2XqNC6tnAj -w+XmCywiTQrFzMMAvcA7rPI4F0nU1rZId51rOvvfxaONp+wgTi4P8owZLw0/j0m4 -8C20DYi6EYx4AHDXiLpElWh3AgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8E -BAMCBLAwHQYDVR0OBBYEFB6ZaeWKxQjGTI+pmz7cKRmMIywwMC4GA1UdEQQnMCWB -I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWB -I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEB -CwUAA4IBgQBVoM+pu3dpdUhZM1w051iw5GfiqclAr1Psypf16Tiod/ho//4oAu6T -9fj3DPX/acWV9P/FScvqo4Qgv6g4VWO5ZU7z2JmPoTXZtYMunRAmQPFL/gSUc6aK -vszMHIyhtyzRc6DnfW2AiVOjMBjaYv8xXZc9bduniRVPrLR4J7ozmGLh4o4uJp7w -x9KCFaR8Lvn/r0oJWJOqb/DMAYI83YeN2Dlt3jpwrsmsONrtC5S3gOUle5afSGos -bYt5ocnEpKSomR9ZtnCGljds/aeO1Xgpn2r9HHcjwnH346iNrnHmMlC7BtHUFPDg -Ts92S47PTOXzwPBDsrFiq3VLbRjHSwf8rpqybQBH9MfzxGGxTaETQYOd6b4e4Ag6 -y92abGna0bmIEb4+Tx9rQ10Uijh1POzvr/VTH4bbIPy9FbKrRsIQ24qDbNJRtOpE -RAOsIl+HOBTb252nx1kIRN5hqQx272AJCbCjKx8egcUQKffFVVCI0nye09v5CK+a -HiLJ8VOFx6w= +MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11 +ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK +CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz +MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd +MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj +bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB +igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2 +9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW +sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE +e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN +XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss +RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn +tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM +zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW +xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O +BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs +aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs +aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE +cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl +xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/ +c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp +8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws +JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP +eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt +Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8 +voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg= -----END CERTIFICATE----- diff --git a/spec/db/client_examples.rb b/spec/db/client_examples.rb deleted file mode 100644 index 07203c3..0000000 --- a/spec/db/client_examples.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -RSpec.shared_examples_for DB::Client do |adapter| - subject{DB::Client.new(adapter)} - - it "can execute multiple queries" do - Sync do - context = subject.context - - query = <<~SQL * 2 - SELECT 42 AS LIFE; - SQL - - context.call(query) do |connection| - 2.times do - result = connection.next_result - expect(result.to_a).to be == [[42]] - end - end - end - end - - it "can generate a query with literal values" do - Sync do - session = subject.session - - session.clause("SELECT").literal(42).clause("AS").identifier(:LIFE).call do |connection| - result = connection.next_result - expect(result.to_a).to be == [[42]] - end - end - end - - it "can generate a query using interpolations" do - Sync do - session = subject.session - - session.query("SELECT %{value} AS %{column}", value: 42, column: :LIFE).call do |connection| - result = connection.next_result - expect(result.to_a).to be == [[42]] - end - end - end - - it "can execute a query in a transaction" do - Sync do - transaction = subject.transaction - - transaction.call("SELECT 42 AS LIFE") do |connection| - result = connection.next_result - expect(result.to_a).to be == [[42]] - end - - transaction.commit - end - end - - context 'with events table' do - before do - Sync do - transaction = subject.transaction - - transaction.call("DROP TABLE IF EXISTS events") - - transaction.call("CREATE TABLE IF NOT EXISTS events (#{transaction.connection.key_column}, created_at TIMESTAMP NOT NULL, description TEXT NULL)") - - transaction.commit - end - end - - it 'can insert rows with timestamps' do - Sync do - session = subject.session - - session.call("INSERT INTO events (created_at, description) VALUES ('2020-05-04 03:02:01', 'Hello World')") - - rows = session.call('SELECT * FROM events') do |connection| - connection.next_result.to_a - end - - expect(rows).to be == [[1, Time.parse("2020-05-04 03:02:01 UTC"), "Hello World"]] - end - end - - it 'can insert null fields' do - Sync do - session = subject.session - - session.call("INSERT INTO events (created_at, description) VALUES ('2020-05-04 03:02:01', NULL)") - - rows = session.call('SELECT * FROM events') do |connection| - connection.next_result.to_a - end - - expect(rows).to be == [[1, Time.parse("2020-05-04 03:02:01 UTC"), nil]] - end - end - end -end diff --git a/spec/db/client_spec.rb b/spec/db/client_spec.rb deleted file mode 100644 index c8b6fbd..0000000 --- a/spec/db/client_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -require 'db/client' -require 'db/adapters' - -require_relative 'client_examples' - -DB::Adapters.each do |name, klass| - RSpec.describe klass do - include_examples DB::Client, klass.new(**CREDENTIALS) - end -end diff --git a/spec/db_spec.rb b/spec/db_spec.rb deleted file mode 100644 index 2e63115..0000000 --- a/spec/db_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -require 'db' - -RSpec.describe DB do - it "has a version number" do - expect(DB::VERSION).not_to be nil - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 6f6a534..0000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -# Copyright, 2020, by Samuel G. D. Williams. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -require 'covered/rspec' -require 'bundler/setup' - -Bundler.require(:adapters) - -CREDENTIALS = { - username: 'test', - password: 'test', - database: 'test', - host: '127.0.0.1' -} - -# Used for PG.connect: -PG_CREDENTIALS = CREDENTIALS.dup -PG_CREDENTIALS[:user] = PG_CREDENTIALS.delete(:username) -PG_CREDENTIALS[:dbname] = PG_CREDENTIALS.delete(:database) - -RSpec.configure do |config| - # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" - - # Disable RSpec exposing methods globally on `Module` and `main` - config.disable_monkey_patching! - - config.expect_with :rspec do |c| - c.syntax = :expect - end -end diff --git a/test/db.rb b/test/db.rb new file mode 100644 index 0000000..8a09e4d --- /dev/null +++ b/test/db.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. + +require 'db' + +describe DB do + it "has a version number" do + expect(DB::VERSION).to be =~ /\d+\.\d+\.\d+/ + end +end diff --git a/test/db/client.rb b/test/db/client.rb new file mode 100644 index 0000000..1685e1a --- /dev/null +++ b/test/db/client.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. + +require 'db/client' +require 'db/adapters' +require 'sus/fixtures/async' + +AClient = Sus::Shared("a client") do |adapter| + include Sus::Fixtures::Async::ReactorContext + + let(:client) {DB::Client.new(adapter)} + + it "can execute multiple queries" do + context = client.context + + query = <<~SQL * 2 + SELECT 42 AS LIFE; + SQL + + context.call(query) do |connection| + 2.times do + result = connection.next_result + expect(result.to_a).to be == [[42]] + end + end + ensure + context.close + end + + it "can generate a query with literal values" do + session = client.session + + session.clause("SELECT").literal(42).clause("AS").identifier(:LIFE).call do |connection| + result = connection.next_result + expect(result.to_a).to be == [[42]] + end + ensure + session.close + end + + it "can generate a query using interpolations" do + session = client.session + + session.query("SELECT %{value} AS %{column}", value: 42, column: :LIFE).call do |connection| + result = connection.next_result + expect(result.to_a).to be == [[42]] + end + ensure + session.close + end + + it "can execute a query in a transaction" do + transaction = client.transaction + + transaction.call("SELECT 42 AS LIFE") do |connection| + result = connection.next_result + expect(result.to_a).to be == [[42]] + end + + transaction.commit + ensure + transaction.close + end + + with 'events table' do + def before + super + + transaction = client.transaction + + transaction.call("DROP TABLE IF EXISTS events") + + transaction.call("CREATE TABLE IF NOT EXISTS events (#{transaction.connection.key_column}, created_at TIMESTAMP NOT NULL, description TEXT NULL)") + + transaction.commit + ensure + transaction.close + end + + it 'can insert rows with timestamps' do + session = client.session + + session.call("INSERT INTO events (created_at, description) VALUES ('2020-05-04 03:02:01', 'Hello World')") + + rows = session.call('SELECT * FROM events') do |connection| + connection.next_result.to_a + end + + expect(rows).to be == [[1, Time.parse("2020-05-04 03:02:01 UTC"), "Hello World"]] + ensure + session.close + end + + it 'can insert null fields' do + session = client.session + + session.call("INSERT INTO events (created_at, description) VALUES ('2020-05-04 03:02:01', NULL)") + + rows = session.call('SELECT * FROM events') do |connection| + connection.next_result.to_a + end + + expect(rows).to be == [[1, Time.parse("2020-05-04 03:02:01 UTC"), nil]] + ensure + session.close + end + end +end + +DB::Adapters.each do |name, klass| + describe klass do + it_behaves_like AClient, klass.new(**CREDENTIALS) + end +end