ar_firebird_adapter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8ca6d29acdccc19c734c581fd88d10789e7a7e9aa49baba016f68668479d28cb
4
+ data.tar.gz: 0b12220547231a7bed9a27494309f1dba73f9ae27fde6cb38123906971cbf5f6
5
+ SHA512:
6
+ metadata.gz: '051176505698bd4da3565b447b0b13c1f6d228c060095b00e78f0bf73f1593244685230906bb75cdb29f359df273e573eb8889b96ba271974d670d5ed9548e30'
7
+ data.tar.gz: 07a6000f3fcb3d4cf00f87c1352676ce00b3c5f512ff0ea66b63ac39dc8f6ec004c9d796c7b9836c215f0a6d25d7e79adc578017626548f281dfe510893ab2f5
@@ -0,0 +1,18 @@
1
+ module ActiveRecord::ConnectionHandling
2
+ def ar_firebird_connection(config)
3
+ require 'active_record/extensions'
4
+ require 'active_record/internal_metadata_extensions'
5
+
6
+ config = config.symbolize_keys.dup.reverse_merge(downcase_names: true, port: 3050, encoding: ActiveRecord::ConnectionAdapters::ArFirebirdAdapter::DEFAULT_ENCODING)
7
+
8
+ if config[:host]
9
+ config[:database] = "#{config[:host]}/#{config[:port]}:#{config[:database]}"
10
+ else
11
+ config[:database] = File.expand_path(config[:database], Rails.root)
12
+ end
13
+
14
+ connection = ::Fb::Database.new(config).connect
15
+
16
+ ActiveRecord::ConnectionAdapters::ArFirebirdAdapter.new(connection, logger, config)
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ module ActiveRecord::ConnectionAdapters::ArFirebird
2
+ module DatabaseLimits
3
+
4
+ def table_alias_length
5
+ 31
6
+ end
7
+
8
+ def column_name_length
9
+ 31
10
+ end
11
+
12
+ def table_name_length
13
+ 31
14
+ end
15
+
16
+ def index_name_length
17
+ 31
18
+ end
19
+
20
+ def indexes_per_table
21
+ 65_535
22
+ end
23
+
24
+ def in_clause_length
25
+ 1_499
26
+ end
27
+
28
+ def sql_query_length
29
+ 32_767
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,96 @@
1
+ module ActiveRecord::ConnectionAdapters::ArFirebird::DatabaseStatements
2
+
3
+ delegate :boolean_domain, to: 'ActiveRecord::ConnectionAdapters::ArFirebirdAdapter'
4
+
5
+ def execute(sql, name = nil)
6
+ sql = sql.encode(encoding, 'UTF-8')
7
+
8
+ log(sql, name) do
9
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
10
+ @connection.query(sql)
11
+ end
12
+ end
13
+ end
14
+
15
+ def exec_query(sql, name = 'SQL', binds = [], prepare: false)
16
+ sql = sql.encode(encoding, 'UTF-8')
17
+
18
+ type_casted_binds = type_casted_binds(binds).map do |value|
19
+ value.encode(encoding) rescue value
20
+ end
21
+
22
+ log(sql, name, binds, type_casted_binds) do
23
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
24
+ begin
25
+ result = @connection.execute(sql, *type_casted_binds)
26
+ if result.is_a?(Fb::Cursor)
27
+ fields = result.fields.map(&:name)
28
+ rows = result.fetchall.map do |row|
29
+ row.map do |col|
30
+ col.encode('UTF-8', @connection.encoding) rescue col
31
+ end
32
+ end
33
+
34
+ result.close
35
+ ActiveRecord::Result.new(fields, rows)
36
+ else
37
+ result
38
+ end
39
+ rescue Exception => e
40
+ raise e.message.encode('UTF-8', @connection.encoding)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def begin_db_transaction
47
+ log("begin transaction", nil) { @connection.transaction('READ COMMITTED') }
48
+ end
49
+
50
+ def commit_db_transaction
51
+ log("commit transaction", nil) { @connection.commit }
52
+ end
53
+
54
+ def exec_rollback_db_transaction
55
+ log("rollback transaction", nil) { @connection.rollback }
56
+ end
57
+
58
+ def create_table(table_name, **options)
59
+ super
60
+
61
+ if options[:sequence] != false && options[:id] != false
62
+ sequence_name = options[:sequence] || default_sequence_name(table_name)
63
+ create_sequence(sequence_name)
64
+ end
65
+ end
66
+
67
+ def drop_table(table_name, options = {})
68
+ if options[:sequence] != false
69
+ sequence_name = options[:sequence] || default_sequence_name(table_name)
70
+ drop_sequence(sequence_name) if sequence_exists?(sequence_name)
71
+ end
72
+
73
+ super
74
+ end
75
+
76
+ def create_sequence(sequence_name)
77
+ execute("CREATE SEQUENCE #{sequence_name}") rescue nil
78
+ end
79
+
80
+ def drop_sequence(sequence_name)
81
+ execute("DROP SEQUENCE #{sequence_name}") rescue nil
82
+ end
83
+
84
+ def sequence_exists?(sequence_name)
85
+ @connection.generator_names.include?(sequence_name)
86
+ end
87
+
88
+ def default_sequence_name(table_name, _column = nil)
89
+ "#{table_name}_g01"
90
+ end
91
+
92
+ def next_sequence_value(sequence_name)
93
+ @connection.query("SELECT NEXT VALUE FOR #{sequence_name} FROM RDB$DATABASE")[0][0]
94
+ end
95
+
96
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module ArFirebird
4
+ class FbColumn < ActiveRecord::ConnectionAdapters::Column # :nodoc:
5
+
6
+ attr_reader :domain
7
+ def initialize(
8
+ name,
9
+ default,
10
+ sql_type_metadata = nil,
11
+ null = true,
12
+ table_name = nil,
13
+ default_function = nil,
14
+ collation = nil,
15
+ comment = nil,
16
+ firebird_options = {}
17
+ )
18
+ @domain = firebird_options.domain
19
+ super(
20
+ name,
21
+ default,
22
+ sql_type_metadata,
23
+ null,
24
+ default_function,
25
+ collation: nil,
26
+ comment: comment
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module ArFirebird
6
+ module Quoting
7
+
8
+ def unquoted_true
9
+ boolean_domain[:true]
10
+ end
11
+
12
+ def quoted_true # :nodoc:
13
+ quote unquoted_true
14
+ end
15
+
16
+ def unquoted_false
17
+ boolean_domain[:false]
18
+ end
19
+
20
+ def quoted_false # :nodoc:
21
+ quote unquoted_false
22
+ end
23
+
24
+ def lookup_cast_type_from_column(column) # :nodoc:
25
+ sql_type = (column.domain == boolean_domain[:name]) ? 'BOOLEAN' : column.sql_type
26
+ type_map.lookup(sql_type)
27
+ end
28
+
29
+ def quoted_date(value)
30
+ super.sub(/(\.\d{6})\z/, $1.to_s.first(5))
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,147 @@
1
+ module ActiveRecord::ConnectionAdapters::ArFirebird::SchemaStatements
2
+
3
+ def tables(_name = nil)
4
+ @connection.table_names
5
+ end
6
+
7
+ def views
8
+ @connection.view_names
9
+ end
10
+
11
+ def indexes(table_name)
12
+ result = query(<<~SQL, "SCHEMA")
13
+ SELECT
14
+ rdb$index_name,
15
+ rdb$unique_flag
16
+ FROM
17
+ rdb$indices
18
+ WHERE
19
+ rdb$relation_name = '#{table_name.upcase}';
20
+ SQL
21
+
22
+ result.map do |row|
23
+ index_name = row[0].strip
24
+ unique = row[1] == 1
25
+ columns = query_values(<<~SQL, "SCHEMA")
26
+ SELECT
27
+ rdb$field_name
28
+ FROM
29
+ rdb$index_segments
30
+ WHERE
31
+ rdb$index_name = '#{index_name}'
32
+ ORDER BY
33
+ rdb$field_position
34
+ SQL
35
+
36
+ ActiveRecord::ConnectionAdapters::IndexDefinition.new(
37
+ table_name.downcase,
38
+ index_name.downcase,
39
+ unique,
40
+ columns.map(&:strip).map(&:downcase),
41
+ )
42
+ end
43
+ end
44
+
45
+ def remove_index(table_name, options = {})
46
+ index_name = index_name_for_remove(table_name, options)
47
+ execute "DROP INDEX #{quote_column_name(index_name)}"
48
+ end
49
+
50
+ def foreign_keys(table_name)
51
+ result = query(<<~SQL, "SCHEMA")
52
+ WITH FK_FIELDS AS (
53
+ SELECT
54
+ AA2.RDB$RELATION_NAME,
55
+ AA2.RDB$CONSTRAINT_NAME,
56
+ BB2.RDB$CONST_NAME_UQ AS LINK_UK_OR_PK,
57
+ EE2.RDB$RELATION_NAME AS REFERENCE_TABLE,
58
+ CC2.RDB$FIELD_NAME,
59
+ AA2.RDB$CONSTRAINT_TYPE
60
+ FROM
61
+ RDB$RELATION_CONSTRAINTS AA2
62
+ LEFT JOIN RDB$REF_CONSTRAINTS BB2 ON BB2.RDB$CONSTRAINT_NAME = AA2.RDB$CONSTRAINT_NAME
63
+ LEFT JOIN RDB$INDEX_SEGMENTS CC2 ON CC2.RDB$INDEX_NAME = AA2.RDB$INDEX_NAME
64
+ LEFT JOIN RDB$RELATION_FIELDS DD2 ON DD2.RDB$FIELD_NAME = CC2.RDB$FIELD_NAME AND DD2.RDB$RELATION_NAME = AA2.RDB$RELATION_NAME
65
+ LEFT JOIN RDB$RELATION_CONSTRAINTS EE2 ON EE2.RDB$CONSTRAINT_NAME = BB2.RDB$CONST_NAME_UQ
66
+ )
67
+ SELECT
68
+ AA.RDB$CONSTRAINT_NAME,
69
+ BB.REFERENCE_TABLE,
70
+ BB.FIELDS,
71
+ BB.REFERENCE_FIELDS
72
+ FROM
73
+ RDB$RELATION_CONSTRAINTS AA
74
+ LEFT JOIN (
75
+ SELECT
76
+ AA1.RDB$RELATION_NAME,
77
+ AA1.RDB$CONSTRAINT_NAME,
78
+ AA1.LINK_UK_OR_PK,
79
+ AA1.REFERENCE_TABLE,
80
+ (
81
+ SELECT LIST(TRIM(AA3.RDB$FIELD_NAME), ', ') FROM FK_FIELDS AA3 WHERE AA3.RDB$CONSTRAINT_NAME = AA1.RDB$CONSTRAINT_NAME ROWS 1
82
+ ) AS FIELDS,
83
+ (
84
+ SELECT LIST(TRIM(AA4.RDB$FIELD_NAME), ', ') FROM FK_FIELDS AA4 WHERE AA4.RDB$CONSTRAINT_NAME = AA1.LINK_UK_OR_PK ROWS 1
85
+ ) AS REFERENCE_FIELDS
86
+ FROM
87
+ FK_FIELDS AA1
88
+ GROUP BY
89
+ AA1.RDB$RELATION_NAME,
90
+ AA1.RDB$CONSTRAINT_NAME,
91
+ AA1.REFERENCE_TABLE,
92
+ AA1.LINK_UK_OR_PK
93
+ ) BB ON BB.RDB$RELATION_NAME = AA.RDB$RELATION_NAME AND BB.RDB$CONSTRAINT_NAME = AA.RDB$CONSTRAINT_NAME
94
+ WHERE
95
+ AA.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
96
+ AND AA.RDB$RELATION_NAME = '#{table_name.upcase}';
97
+ SQL
98
+
99
+ result.map do |row|
100
+ options = {
101
+ column: row[2].downcase,
102
+ name: row[0].strip.downcase,
103
+ primary_key: row[3].downcase
104
+ }
105
+
106
+ ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, row[1].strip.downcase, options)
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def column_definitions(table_name)
113
+ @connection.columns(table_name)
114
+ end
115
+
116
+ def new_column_from_field(table_name, field)
117
+ type_metadata = fetch_type_metadata(field["sql_type"], field)
118
+ ActiveRecord::ConnectionAdapters::ArFirebird::FbColumn.new(
119
+ field["name"],
120
+ field["default"],
121
+ type_metadata,
122
+ field["nullable"],
123
+ table_name,
124
+ nil,
125
+ nil,
126
+ nil,
127
+ field
128
+ )
129
+ end
130
+
131
+ def fetch_type_metadata(sql_type, field = "")
132
+ if field['domain'] == ActiveRecord::ConnectionAdapters::ArFirebirdAdapter.boolean_domain[:name]
133
+ cast_type = lookup_cast_type("boolean")
134
+ else
135
+ cast_type = lookup_cast_type(sql_type)
136
+ end
137
+ ActiveRecord::ConnectionAdapters::ArFirebird::SqlTypeMetadata.new(
138
+ sql_type: sql_type,
139
+ type: cast_type.type,
140
+ precision: cast_type.precision,
141
+ scale: cast_type.scale,
142
+ limit: cast_type.limit,
143
+ field: field
144
+ )
145
+ end
146
+
147
+ end
@@ -0,0 +1,24 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module ArFirebird
4
+ class SqlTypeMetadata < ActiveRecord::ConnectionAdapters::SqlTypeMetadata
5
+
6
+ def initialize(sql_type: nil, type: nil, limit: nil, precision: nil, scale: nil, **firebird_options)
7
+ @sql_type = sql_type
8
+ @type = (firebird_options[:field].domain) ? :boolean : sql_type
9
+ @limit = limit
10
+ @precision = precision
11
+ @scale = scale
12
+ @firebird_options = firebird_options
13
+ end
14
+
15
+ protected
16
+
17
+ def attributes_for_hash
18
+ super + [@firebird_options]
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,126 @@
1
+ require 'fb'
2
+
3
+ require 'active_record/connection_adapters/ar_firebird/connection'
4
+ require 'active_record/connection_adapters/ar_firebird/database_limits'
5
+ require 'active_record/connection_adapters/ar_firebird/database_statements'
6
+ require 'active_record/connection_adapters/ar_firebird/schema_statements'
7
+ require 'active_record/connection_adapters/ar_firebird/sql_type_metadata'
8
+ require 'active_record/connection_adapters/ar_firebird/fb_column'
9
+ require 'active_record/connection_adapters/ar_firebird/quoting'
10
+
11
+ require 'arel/visitors/ar_firebird'
12
+
13
+ class ActiveRecord::ConnectionAdapters::ArFirebirdAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
14
+
15
+ ADAPTER_NAME = "ArFirebird".freeze
16
+ DEFAULT_ENCODING = "Windows-1252".freeze
17
+
18
+ include ActiveRecord::ConnectionAdapters::ArFirebird::DatabaseLimits
19
+ include ActiveRecord::ConnectionAdapters::ArFirebird::DatabaseStatements
20
+ include ActiveRecord::ConnectionAdapters::ArFirebird::SchemaStatements
21
+ include ActiveRecord::ConnectionAdapters::ArFirebird::Quoting
22
+
23
+
24
+
25
+ @boolean_domain = { name: "smallint", limit: 1, type: "smallint", true: 1, false: 0}
26
+
27
+ class << self
28
+ attr_accessor :boolean_domain
29
+ end
30
+
31
+ NATIVE_DATABASE_TYPES = {
32
+ primary_key: 'integer not null primary key',
33
+ string: { name: 'varchar', limit: 255 },
34
+ text: { name: 'blob sub_type text' },
35
+ integer: { name: 'integer' },
36
+ float: { name: 'float' },
37
+ decimal: { name: 'decimal' },
38
+ datetime: { name: 'timestamp' },
39
+ timestamp: { name: 'timestamp' },
40
+ date: { name: 'date' },
41
+ binary: { name: 'blob' },
42
+ boolean: { name: ActiveRecord::ConnectionAdapters::ArFirebirdAdapter.boolean_domain[:name] }
43
+ }
44
+
45
+ def native_database_types
46
+ NATIVE_DATABASE_TYPES
47
+ end
48
+
49
+ def arel_visitor
50
+ @arel_visitor ||= Arel::Visitors::ArFirebird.new(self)
51
+ end
52
+
53
+ def prefetch_primary_key?(table_name = nil)
54
+ true
55
+ end
56
+
57
+ def active?
58
+ return false unless @connection.open?
59
+
60
+ @connection.query("SELECT 1 FROM RDB$DATABASE")
61
+ true
62
+ rescue
63
+ false
64
+ end
65
+
66
+ def reconnect!
67
+ disconnect!
68
+ @connection = ::Fb::Database.connect(@config)
69
+ end
70
+
71
+ def disconnect!
72
+ super
73
+ @connection.close rescue nil
74
+ end
75
+
76
+ def reset!
77
+ reconnect!
78
+ end
79
+
80
+ def primary_keys(table_name)
81
+ raise ArgumentError unless table_name.present?
82
+
83
+ names = query_values(<<~SQL, "SCHEMA")
84
+ SELECT
85
+ s.rdb$field_name
86
+ FROM
87
+ rdb$indices i
88
+ JOIN rdb$index_segments s ON i.rdb$index_name = s.rdb$index_name
89
+ LEFT JOIN rdb$relation_constraints c ON i.rdb$index_name = c.rdb$index_name
90
+ WHERE
91
+ i.rdb$relation_name = '#{table_name.upcase}'
92
+ AND c.rdb$constraint_type = 'PRIMARY KEY';
93
+ SQL
94
+
95
+ names.map(&:strip).map(&:downcase)
96
+ end
97
+
98
+ def encoding
99
+ @connection.encoding
100
+ end
101
+
102
+ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
103
+ sql = sql.encode('UTF-8', encoding) if sql.encoding.to_s == encoding
104
+ super
105
+ end
106
+
107
+ def supports_foreign_keys?
108
+ true
109
+ end
110
+
111
+ protected
112
+
113
+ def translate_exception(e, message)
114
+ case e.message
115
+ when /violation of FOREIGN KEY constraint/
116
+ ActiveRecord::InvalidForeignKey.new(message)
117
+ when /violation of PRIMARY or UNIQUE KEY constraint/, /attempt to store duplicate value/
118
+ ActiveRecord::RecordNotUnique.new(message)
119
+ when /This operation is not defined for system tables/
120
+ ActiveRecord::ActiveRecordError.new(message)
121
+ else
122
+ super
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,15 @@
1
+ ActiveRecord::Calculations.module_eval do
2
+ def count(column_name = nil)
3
+ return super() if block_given?
4
+ calculate(:count, column_name || 1)
5
+ end
6
+ end
7
+
8
+ class ActiveRecord::ConnectionAdapters::AbstractAdapter
9
+ def combine_bind_parameters(from_clause: [], join_clause: [], where_clause: [], having_clause: [], limit: nil, offset: nil)
10
+ result = from_clause + join_clause + where_clause + having_clause
11
+ result.unshift(offset) if offset
12
+ result.unshift(limit) if limit
13
+ result
14
+ end
15
+ end if ActiveRecord::VERSION::STRING < '5.2.0'
@@ -0,0 +1,31 @@
1
+ class ActiveRecord::InternalMetadata
2
+ class << self
3
+ def adapter_name
4
+ connection.adapter_name.downcase.to_sym
5
+ end
6
+
7
+ def value_name
8
+ adapter_name == :ar_firebird ? :value_ : :value
9
+ end
10
+
11
+ def []=(key, value)
12
+ find_or_initialize_by(key: key).update!(value_name => value)
13
+ end
14
+
15
+ def [](key)
16
+ where(key: key).pluck(value_name).first
17
+ end
18
+
19
+ def create_table
20
+ unless table_exists?
21
+ key_options = connection.internal_string_options_for_primary_key
22
+
23
+ connection.create_table(table_name, id: false) do |t|
24
+ t.string :key, key_options
25
+ t.string value_name
26
+ t.timestamps
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Arel::Visitors::ArFirebird < Arel::Visitors::ToSql
4
+
5
+ private
6
+
7
+ def visit_Arel_Nodes_SelectStatement o, collector
8
+ if o.with
9
+ collector = visit o.with, collector
10
+ collector << ' '
11
+ end
12
+
13
+ collector = o.cores.inject(collector) do |c, x|
14
+ visit_Arel_Nodes_SelectCore(x, c, o)
15
+ end
16
+
17
+ unless o.orders.empty?
18
+ collector << ' ORDER BY '
19
+ o.orders.each_with_index do |x, i|
20
+ collector << ', ' unless i == 0
21
+ collector = visit(x, collector)
22
+ end
23
+ end
24
+
25
+ collector
26
+ end
27
+
28
+ def visit_Arel_Nodes_SelectCore(core, collector, o)
29
+ # We need to use the Arel::Nodes::SelectCore `core`
30
+ # as well as Arel::Nodes::SelectStatement `o` in
31
+ # contradiction to the super class because we access
32
+ # the `visit_Arel_Nodes_SelectOptions` method because
33
+ # we need to set our limit and offset in the select
34
+ # clause (Firebird specific SQL)
35
+ collector << 'SELECT'
36
+
37
+ visit_Arel_Nodes_SelectOptions(o, collector)
38
+
39
+ collector = maybe_visit core.set_quantifier, collector
40
+
41
+ collect_nodes_for core.projections, collector, ' '
42
+
43
+ if core.source && !core.source.empty?
44
+ collector << ' FROM '
45
+ collector = visit core.source, collector
46
+ end
47
+
48
+ collect_nodes_for core.wheres, collector, ' WHERE ', ' AND '
49
+ collect_nodes_for core.groups, collector, ' GROUP BY '
50
+ unless core.havings.empty?
51
+ collector << ' HAVING '
52
+ inject_join core.havings, collector, ' AND '
53
+ end
54
+ collect_nodes_for core.windows, collector, ' WINDOW '
55
+
56
+ collector
57
+ end
58
+
59
+ def visit_Arel_Nodes_Limit(o, collector)
60
+ collector << 'FIRST '
61
+ visit o.expr, collector
62
+ end
63
+
64
+ def visit_Arel_Nodes_Offset(o, collector)
65
+ collector << 'SKIP '
66
+ visit o.expr, collector
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ar_firebird_adapter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Fábio Rodrigues
8
+ - Gernot Gradwohl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-10-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fb
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.9.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.9.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 5.2.0
35
+ - - "<"
36
+ - !ruby/object:Gem::Version
37
+ version: 6.1.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 5.2.0
45
+ - - "<"
46
+ - !ruby/object:Gem::Version
47
+ version: 6.1.0
48
+ - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.16'
62
+ - !ruby/object:Gem::Dependency
63
+ name: database_cleaner
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ - !ruby/object:Gem::Dependency
77
+ name: pry-meta
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.0.10
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.0.10
90
+ - !ruby/object:Gem::Dependency
91
+ name: rake
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: rspec
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.7'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.7'
118
+ description:
119
+ email:
120
+ - grnt.grdwhl@gmail.com
121
+ executables: []
122
+ extensions: []
123
+ extra_rdoc_files: []
124
+ files:
125
+ - lib/active_record/connection_adapters/ar_firebird/connection.rb
126
+ - lib/active_record/connection_adapters/ar_firebird/database_limits.rb
127
+ - lib/active_record/connection_adapters/ar_firebird/database_statements.rb
128
+ - lib/active_record/connection_adapters/ar_firebird/fb_column.rb
129
+ - lib/active_record/connection_adapters/ar_firebird/quoting.rb
130
+ - lib/active_record/connection_adapters/ar_firebird/schema_statements.rb
131
+ - lib/active_record/connection_adapters/ar_firebird/sql_type_metadata.rb
132
+ - lib/active_record/connection_adapters/ar_firebird_adapter.rb
133
+ - lib/active_record/extensions.rb
134
+ - lib/active_record/internal_metadata_extensions.rb
135
+ - lib/arel/visitors/ar_firebird.rb
136
+ homepage: https://github.com/rails-firebird/ar_firebird_adapter/
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '2.5'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubygems_version: 3.0.3
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: ActiveRecord Firebird Adapter for Rails 5 and 6.
159
+ test_files: []