Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a new pull request by comparing changes across two branches #531

Merged
merged 17 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e0d77a9
Document ActionText::RichText methods [ci-skip]
p8 Apr 15, 2023
2f9b553
Fix monospace formatting [ci-skip]
jonathanhefner Apr 16, 2023
27d507f
Fix marshalling_format_version config name [ci-skip]
jonathanhefner Apr 16, 2023
d618a45
Replace backticks with RDoc markup [ci-skip]
jonathanhefner Apr 16, 2023
0b5505e
Fix typos for AS::Notifications::Fanout::Handle [ci-skip]
jonathanhefner Apr 16, 2023
4dcf592
Fix regression in test name filters with specs
ghiculescu Apr 14, 2023
950ffb9
Docs: fix misspel on association_basics.md [ci-skip] (#47958)
hachi8833 Apr 17, 2023
bd8aeea
Merge pull request #47953 from p8/actiontext/document-rich-text-methods
p8 Apr 17, 2023
5ed3f60
Introduce adapter for Trilogy, a MySQL-compatible DB client
adrianna-chang-shopify Mar 20, 2023
a2a6331
Add ActiveSupport::MessagePack
jonathanhefner Mar 22, 2023
112c3cd
Merge pull request #47770 from jonathanhefner/message_pack
jonathanhefner Apr 17, 2023
f7a4022
Merge pull request #47880 from adrianna-chang-shopify/ac-trilogy-adapter
eileencodes Apr 17, 2023
539144d
Merge pull request #47942 from ghiculescu/declarative-specs
jonathanhefner Apr 17, 2023
f831111
Active Record: assign connection pool before checking version
byroot Apr 18, 2023
7239ec1
Merge pull request #47972 from Shopify/ar-get-version-schema-cache
byroot Apr 18, 2023
43f03ea
Use Trilogy#discard! when discard! called on TrilogyAdapter
adrianna-chang-shopify Apr 18, 2023
732a474
Merge pull request #47974 from adrianna-chang-shopify/ac-trilogy-discard
byroot Apr 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ gem "listen", "~> 3.3", require: false
gem "libxml-ruby", platforms: :ruby
gem "connection_pool", require: false
gem "rexml", require: false
gem "msgpack", ">= 1.7.0", require: false

# for railties
gem "bootsnap", ">= 1.4.4", require: false
Expand Down Expand Up @@ -149,6 +150,7 @@ platforms :ruby, :windows do
group :db do
gem "pg", "~> 1.3"
gem "mysql2", "~> 0.5"
gem "trilogy", "~> 2.4"
end
end

Expand Down
5 changes: 4 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ GEM
mixlib-shellout (3.2.7)
chef-utils
mono_logger (1.1.1)
msgpack (1.6.0)
msgpack (1.7.0)
multi_json (1.15.0)
multipart-post (2.2.3)
mustermann (3.0.0)
Expand Down Expand Up @@ -507,6 +507,7 @@ GEM
timeout (0.3.2)
tomlrb (2.0.3)
trailblazer-option (0.1.2)
trilogy (2.4.0)
turbo-rails (1.3.2)
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
Expand Down Expand Up @@ -580,6 +581,7 @@ DEPENDENCIES
minitest-bisect
minitest-ci
minitest-retry
msgpack (>= 1.7.0)
mysql2 (~> 0.5)
nokogiri (>= 1.8.1, != 1.11.0)
pg (~> 1.3)
Expand Down Expand Up @@ -617,6 +619,7 @@ DEPENDENCIES
sucker_punch
tailwindcss-rails
terser (>= 1.1.4)
trilogy (~> 2.4)
turbo-rails
tzinfo-data
w3c_validators (~> 1.3.6)
Expand Down
12 changes: 6 additions & 6 deletions actionpack/lib/action_controller/metal/live.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ module ActionController
# the main thread. Make sure your actions are thread safe, and this shouldn't
# be a problem (don't share state across threads, etc).
#
# Note that Rails includes `Rack::ETag` by default, which will buffer your
# Note that \Rails includes +Rack::ETag+ by default, which will buffer your
# response. As a result, streaming responses may not work properly with Rack
# `2.2.x`, and you may need to implement workarounds in your application.
# You can either set the `ETag` or `Last-Modified` response headers or remove
# `Rack::ETag` from the middleware stack to address this issue.
# 2.2.x, and you may need to implement workarounds in your application.
# You can either set the +ETag+ or +Last-Modified+ response headers or remove
# +Rack::ETag+ from the middleware stack to address this issue.
#
# Here's an example of how you can set the `Last-Modified` header if your Rack
# version is `2.2.x`:
# Here's an example of how you can set the +Last-Modified+ header if your Rack
# version is 2.2.x:
#
# def stream
# response.headers["Content-Type"] = "text/event-stream"
Expand Down
26 changes: 26 additions & 0 deletions actiontext/app/models/action_text/rich_text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ module ActionText
# It also holds all the references to the embedded files, which are stored using Active Storage.
# This record is then associated with the Active Record model the application desires to have
# rich text content using the +has_rich_text+ class method.
#
# class Message < ActiveRecord::Base
# has_rich_text :content
# end
#
# message = Message.create!(content: "<h1>Funny times!</h1>")
# message.content #=> #<ActionText::RichText....
# message.content.to_s # => "<h1>Funny times!</h1>"
# message.content.to_plain_text # => "Funny times!"
#
class RichText < Record
self.table_name = "action_text_rich_texts"

Expand All @@ -20,10 +30,26 @@ class RichText < Record
self.embeds = body.attachables.grep(ActiveStorage::Blob).uniq if body.present?
end

# Returns the +body+ attribute as plain text with all HTML tags removed.
#
# message = Message.create!(content: "<h1>Funny times!</h1>")
# message.content.to_plain_text # => "Funny times!"
def to_plain_text
body&.to_plain_text.to_s
end

# Returns the +body+ attribute in a format that makes it editable in the Trix
# editor. Previews of attachments are rendered inline.
#
# content = "<h1>Funny Times!</h1><figure data-trix-attachment='{\"sgid\":\"..."\}'></figure>"
# message = Message.create!(content: content)
# message.content.to_trix_html # =>
# # <div class="trix-content">
# # <h1>Funny times!</h1>
# # <figure data-trix-attachment='{\"sgid\":\"..."\}'>
# # <img src="http://example.org/rails/active_storage/.../funny.jpg">
# # </figure>
# # </div>
def to_trix_html
body&.to_trix_html
end
Expand Down
20 changes: 20 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
* Introduce adapter for Trilogy database client

Trilogy is a MySQL-compatible database client. Rails applications can use Trilogy
by configuring their `config/database.yml`:

```yaml
development:
adapter: trilogy
database: blog_development
pool: 5
```
Or by using the `DATABASE_URL` environment variable:

```ruby
ENV['DATABASE_URL'] # => "trilogy://localhost/blog_development?pool=5"
```

*Adrianna Chang*

* `after_commit` callbacks defined on models now execute in the correct order.

```ruby
Expand Down
1 change: 1 addition & 0 deletions activerecord/RUNNING_UNIT_TESTS.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ example:
Simply executing <tt>bundle exec rake test</tt> is equivalent to the following:

$ bundle exec rake test:mysql2
$ bundle exec rake test:trilogy
$ bundle exec rake test:postgresql
$ bundle exec rake test:sqlite3

Expand Down
13 changes: 7 additions & 6 deletions activerecord/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@ def run_without_aborting(*tasks)
abort "Errors running #{errors.join(', ')}" if errors.any?
end

desc "Run mysql2, sqlite, and postgresql tests by default"
desc "Run mysql2, trilogy, sqlite, and postgresql tests by default"
task default: :test

task :package

desc "Run mysql2, sqlite, and postgresql tests"
desc "Run mysql2, trilogy, sqlite, and postgresql tests"
task :test do
tasks = defined?(JRUBY_VERSION) ?
%w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
%w(test_mysql2 test_sqlite3 test_postgresql)
%w(test_mysql2 test_trilogy test_sqlite3 test_postgresql)
run_without_aborting(*tasks)
end

namespace :test do
task :isolated do
tasks = defined?(JRUBY_VERSION) ?
%w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
%w(isolated_test_mysql2 isolated_test_sqlite3 isolated_test_postgresql)
%w(isolated_test_mysql2 isolated_test_trilogy isolated_test_sqlite3 isolated_test_postgresql)
run_without_aborting(*tasks)
end

Expand All @@ -56,18 +56,19 @@ namespace :db do
task drop: ["db:mysql:drop", "db:postgresql:drop"]
end

%w( mysql2 postgresql sqlite3 sqlite3_mem oracle jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
%w( mysql2 trilogy postgresql sqlite3 sqlite3_mem oracle jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
namespace :test do
Rake::TestTask.new(adapter => "#{adapter}:env") do |t|
adapter_short = adapter[/^[a-z0-9]+/]
t.libs << "test"
files = (FileList["test/cases/**/*_test.rb"].reject {
|x| x.include?("/adapters/") || x.include?("/encryption/performance")
} + FileList["test/cases/adapters/#{adapter_short}/**/*_test.rb"])
files = files + FileList["test/cases/adapters/abstract_mysql_adapter/**/*_test.rb"] if adapter == "mysql2"
files = files + FileList["test/cases/adapters/abstract_mysql_adapter/**/*_test.rb"] if ["mysql2", "trilogy"].include?(adapter)

t.test_files = files

t.test_files = files
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
Expand Down
2 changes: 1 addition & 1 deletion activerecord/bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Minitest
opts.separator ""
opts.separator "Active Record options:"
opts.on("-a", "--adapter [ADAPTER]",
"Run tests using a specific adapter (sqlite3, sqlite3_mem, mysql2, postgresql)") do |adapter|
"Run tests using a specific adapter (sqlite3, sqlite3_mem, mysql2, trilogy, postgresql)") do |adapter|
ENV["ARCONN"] = adapter.strip
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,9 +684,10 @@ def remove_connection_from_thread_cache(conn, owner_thread = conn.owner)
alias_method :release, :remove_connection_from_thread_cache

def new_connection
Base.public_send(db_config.adapter_method, db_config.configuration_hash).tap do |conn|
conn.check_version
end
connection = Base.public_send(db_config.adapter_method, db_config.configuration_hash)
connection.pool = self
connection.check_version
connection
end

# If the pool is not at a <tt>@size</tt> limit, establish new connection. Connecting
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module ActiveRecord
module ConnectionAdapters
module Trilogy
module Errors
# ServerShutdown will be raised when the database server was shutdown.
class ServerShutdown < ActiveRecord::ConnectionFailed
end

# ServerLost will be raised when the database connection was lost.
class ServerLost < ActiveRecord::ConnectionFailed
end

# ServerGone will be raised when the database connection is gone.
class ServerGone < ActiveRecord::ConnectionFailed
end

# BrokenPipe will be raised when a system process connection fails.
class BrokenPipe < ActiveRecord::ConnectionFailed
end

# SocketError will be raised when Ruby encounters a network error.
class SocketError < ActiveRecord::ConnectionFailed
end

# ConnectionResetByPeer will be raised when a network connection is closed
# outside the sytstem process.
class ConnectionResetByPeer < ActiveRecord::ConnectionFailed
end

# ClosedConnection will be raised when the Trilogy encounters a closed
# connection.
class ClosedConnection < ActiveRecord::ConnectionFailed
end

# InvalidSequenceId will be raised when Trilogy ecounters an invalid sequence
# id.
class InvalidSequenceId < ActiveRecord::ConnectionFailed
end

# UnexpectedPacket will be raised when Trilogy ecounters an unexpected
# response packet.
class UnexpectedPacket < ActiveRecord::ConnectionFailed
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

module ActiveRecord
module ConnectionAdapters
module Trilogy
class LostConnectionExceptionTranslator
attr_reader :exception, :message, :error_number

def initialize(exception, message, error_number)
@exception = exception
@message = message
@error_number = error_number
end

def translate
translate_database_exception || translate_ruby_exception || translate_trilogy_exception
end

private
ER_SERVER_SHUTDOWN = 1053
CR_SERVER_LOST = 2013
CR_SERVER_LOST_EXTENDED = 2055
CR_SERVER_GONE_ERROR = 2006

def translate_database_exception
case error_number
when ER_SERVER_SHUTDOWN
Errors::ServerShutdown.new(message)
when CR_SERVER_LOST, CR_SERVER_LOST_EXTENDED
Errors::ServerLost.new(message)
when CR_SERVER_GONE_ERROR
Errors::ServerGone.new(message)
end
end

def translate_ruby_exception
case exception
when Errno::EPIPE
Errors::BrokenPipe.new(message)
when SocketError, IOError
Errors::SocketError.new(message)
when ::Trilogy::ConnectionError
if message.include?("Connection reset by peer")
Errors::ConnectionResetByPeer.new(message)
end
end
end

def translate_trilogy_exception
return unless exception.is_a?(::Trilogy::Error)

case message
when /TRILOGY_CLOSED_CONNECTION/
Errors::ClosedConnection.new(message)
when /TRILOGY_INVALID_SEQUENCE_ID/
Errors::InvalidSequenceId.new(message)
when /TRILOGY_UNEXPECTED_PACKET/
Errors::UnexpectedPacket.new(message)
end
end
end
end
end
end
Loading