activerecord-materialize-adapter 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/lib/active_record/connection_adapters/materialize/column.rb +30 -0
  4. data/lib/active_record/connection_adapters/materialize/database_statements.rb +199 -0
  5. data/lib/active_record/connection_adapters/materialize/explain_pretty_printer.rb +44 -0
  6. data/lib/active_record/connection_adapters/materialize/oid/array.rb +91 -0
  7. data/lib/active_record/connection_adapters/materialize/oid/bit.rb +53 -0
  8. data/lib/active_record/connection_adapters/materialize/oid/bit_varying.rb +15 -0
  9. data/lib/active_record/connection_adapters/materialize/oid/bytea.rb +17 -0
  10. data/lib/active_record/connection_adapters/materialize/oid/cidr.rb +50 -0
  11. data/lib/active_record/connection_adapters/materialize/oid/date.rb +23 -0
  12. data/lib/active_record/connection_adapters/materialize/oid/date_time.rb +23 -0
  13. data/lib/active_record/connection_adapters/materialize/oid/decimal.rb +15 -0
  14. data/lib/active_record/connection_adapters/materialize/oid/enum.rb +20 -0
  15. data/lib/active_record/connection_adapters/materialize/oid/hstore.rb +70 -0
  16. data/lib/active_record/connection_adapters/materialize/oid/inet.rb +15 -0
  17. data/lib/active_record/connection_adapters/materialize/oid/jsonb.rb +15 -0
  18. data/lib/active_record/connection_adapters/materialize/oid/legacy_point.rb +44 -0
  19. data/lib/active_record/connection_adapters/materialize/oid/money.rb +41 -0
  20. data/lib/active_record/connection_adapters/materialize/oid/oid.rb +15 -0
  21. data/lib/active_record/connection_adapters/materialize/oid/point.rb +64 -0
  22. data/lib/active_record/connection_adapters/materialize/oid/range.rb +96 -0
  23. data/lib/active_record/connection_adapters/materialize/oid/specialized_string.rb +18 -0
  24. data/lib/active_record/connection_adapters/materialize/oid/type_map_initializer.rb +112 -0
  25. data/lib/active_record/connection_adapters/materialize/oid/uuid.rb +25 -0
  26. data/lib/active_record/connection_adapters/materialize/oid/vector.rb +28 -0
  27. data/lib/active_record/connection_adapters/materialize/oid/xml.rb +30 -0
  28. data/lib/active_record/connection_adapters/materialize/oid.rb +35 -0
  29. data/lib/active_record/connection_adapters/materialize/quoting.rb +205 -0
  30. data/lib/active_record/connection_adapters/materialize/referential_integrity.rb +43 -0
  31. data/lib/active_record/connection_adapters/materialize/schema_creation.rb +76 -0
  32. data/lib/active_record/connection_adapters/materialize/schema_definitions.rb +222 -0
  33. data/lib/active_record/connection_adapters/materialize/schema_dumper.rb +49 -0
  34. data/lib/active_record/connection_adapters/materialize/schema_statements.rb +742 -0
  35. data/lib/active_record/connection_adapters/materialize/type_metadata.rb +36 -0
  36. data/lib/active_record/connection_adapters/materialize/utils.rb +80 -0
  37. data/lib/active_record/connection_adapters/materialize/version.rb +9 -0
  38. data/lib/active_record/connection_adapters/materialize_adapter.rb +952 -0
  39. data/lib/active_record/tasks/materialize_database_tasks.rb +130 -0
  40. data/lib/activerecord-materialize-adapter.rb +3 -0
  41. data/lib/materialize/errors/database_error.rb +10 -0
  42. data/lib/materialize/errors/incomplete_input.rb +10 -0
  43. metadata +170 -0
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+ require "active_record"
5
+
6
+ module ActiveRecord
7
+ module Tasks # :nodoc:
8
+ class MaterializeDatabaseTasks # :nodoc:
9
+ ON_ERROR_STOP_1 = "ON_ERROR_STOP=1"
10
+ SQL_COMMENT_BEGIN = "--"
11
+
12
+ delegate :connection, :establish_connection, :clear_active_connections!,
13
+ to: ActiveRecord::Base
14
+
15
+ def initialize(configuration)
16
+ @configuration = configuration
17
+ end
18
+
19
+ def create(master_established = false)
20
+ establish_master_connection unless master_established
21
+ connection.create_database configuration["database"], configuration
22
+ establish_connection configuration
23
+ rescue ActiveRecord::StatementInvalid => error
24
+ if error.cause.is_a?(PG::DuplicateDatabase)
25
+ raise DatabaseAlreadyExists
26
+ else
27
+ raise
28
+ end
29
+ end
30
+
31
+ def drop
32
+ establish_master_connection
33
+ connection.drop_database configuration["database"]
34
+ end
35
+
36
+ def collation
37
+ connection.collation
38
+ end
39
+
40
+ def purge
41
+ clear_active_connections!
42
+ drop
43
+ create true
44
+ end
45
+
46
+ def structure_dump(filename, extra_flags)
47
+ set_psql_env
48
+
49
+ search_path = \
50
+ case ActiveRecord::Base.dump_schemas
51
+ when :schema_search_path
52
+ configuration["schema_search_path"]
53
+ when :all
54
+ nil
55
+ when String
56
+ ActiveRecord::Base.dump_schemas
57
+ end
58
+
59
+ args = ["-s", "-x", "-O", "-f", filename]
60
+ args.concat(Array(extra_flags)) if extra_flags
61
+ unless search_path.blank?
62
+ args += search_path.split(",").map do |part|
63
+ "--schema=#{part.strip}"
64
+ end
65
+ end
66
+
67
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
68
+ if ignore_tables.any?
69
+ args += ignore_tables.flat_map { |table| ["-T", table] }
70
+ end
71
+
72
+ args << configuration["database"]
73
+ run_cmd("pg_dump", args, "dumping")
74
+ remove_sql_header_comments(filename)
75
+ File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
76
+ end
77
+
78
+ def structure_load(filename, extra_flags)
79
+ set_psql_env
80
+ args = ["-v", ON_ERROR_STOP_1, "-q", "-X", "-f", filename]
81
+ args.concat(Array(extra_flags)) if extra_flags
82
+ args << configuration["database"]
83
+ run_cmd("psql", args, "loading")
84
+ end
85
+
86
+ private
87
+ attr_reader :configuration
88
+
89
+ def establish_master_connection
90
+ establish_connection configuration.merge(
91
+ "database" => "materialize"
92
+ )
93
+ end
94
+
95
+ def set_psql_env
96
+ ENV["PGHOST"] = configuration["host"] if configuration["host"]
97
+ ENV["PGPORT"] = configuration["port"].to_s if configuration["port"]
98
+ ENV["PGPASSWORD"] = configuration["password"].to_s if configuration["password"]
99
+ ENV["PGUSER"] = configuration["username"].to_s if configuration["username"]
100
+ end
101
+
102
+ def run_cmd(cmd, args, action)
103
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
104
+ end
105
+
106
+ def run_cmd_error(cmd, args, action)
107
+ msg = +"failed to execute:\n"
108
+ msg << "#{cmd} #{args.join(' ')}\n\n"
109
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
110
+ msg
111
+ end
112
+
113
+ def remove_sql_header_comments(filename)
114
+ removing_comments = true
115
+ tempfile = Tempfile.open("uncommented_structure.sql")
116
+ begin
117
+ File.foreach(filename) do |line|
118
+ unless removing_comments && (line.start_with?(SQL_COMMENT_BEGIN) || line.blank?)
119
+ tempfile << line
120
+ removing_comments = false
121
+ end
122
+ end
123
+ ensure
124
+ tempfile.close
125
+ end
126
+ FileUtils.cp(tempfile.path, filename)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/materialize_adapter.rb'
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Materialize
4
+ module Errors
5
+
6
+ # Base class for all Materialize errors
7
+ class DatabaseError < StandardError
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'materialize/errors/database_error'
4
+
5
+ module Materialize
6
+ module Errors
7
+ class IncompleteInput < DatabaseError
8
+ end
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-materialize-adapter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Henry Tseng
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-07-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.3.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.3.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 6.0.3.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 6.0.3.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: retriable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.9.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.9.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.18'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.18'
97
+ description: Materialize is a streaming database for real-time applications. Materialize
98
+ accepts input data from a variety of streaming sources (e.g. Kafka) and files (e.g.
99
+ CSVs), and lets you query them using SQL.
100
+ email: henry@heycanvas.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - LICENSE
106
+ - lib/active_record/connection_adapters/materialize/column.rb
107
+ - lib/active_record/connection_adapters/materialize/database_statements.rb
108
+ - lib/active_record/connection_adapters/materialize/explain_pretty_printer.rb
109
+ - lib/active_record/connection_adapters/materialize/oid.rb
110
+ - lib/active_record/connection_adapters/materialize/oid/array.rb
111
+ - lib/active_record/connection_adapters/materialize/oid/bit.rb
112
+ - lib/active_record/connection_adapters/materialize/oid/bit_varying.rb
113
+ - lib/active_record/connection_adapters/materialize/oid/bytea.rb
114
+ - lib/active_record/connection_adapters/materialize/oid/cidr.rb
115
+ - lib/active_record/connection_adapters/materialize/oid/date.rb
116
+ - lib/active_record/connection_adapters/materialize/oid/date_time.rb
117
+ - lib/active_record/connection_adapters/materialize/oid/decimal.rb
118
+ - lib/active_record/connection_adapters/materialize/oid/enum.rb
119
+ - lib/active_record/connection_adapters/materialize/oid/hstore.rb
120
+ - lib/active_record/connection_adapters/materialize/oid/inet.rb
121
+ - lib/active_record/connection_adapters/materialize/oid/jsonb.rb
122
+ - lib/active_record/connection_adapters/materialize/oid/legacy_point.rb
123
+ - lib/active_record/connection_adapters/materialize/oid/money.rb
124
+ - lib/active_record/connection_adapters/materialize/oid/oid.rb
125
+ - lib/active_record/connection_adapters/materialize/oid/point.rb
126
+ - lib/active_record/connection_adapters/materialize/oid/range.rb
127
+ - lib/active_record/connection_adapters/materialize/oid/specialized_string.rb
128
+ - lib/active_record/connection_adapters/materialize/oid/type_map_initializer.rb
129
+ - lib/active_record/connection_adapters/materialize/oid/uuid.rb
130
+ - lib/active_record/connection_adapters/materialize/oid/vector.rb
131
+ - lib/active_record/connection_adapters/materialize/oid/xml.rb
132
+ - lib/active_record/connection_adapters/materialize/quoting.rb
133
+ - lib/active_record/connection_adapters/materialize/referential_integrity.rb
134
+ - lib/active_record/connection_adapters/materialize/schema_creation.rb
135
+ - lib/active_record/connection_adapters/materialize/schema_definitions.rb
136
+ - lib/active_record/connection_adapters/materialize/schema_dumper.rb
137
+ - lib/active_record/connection_adapters/materialize/schema_statements.rb
138
+ - lib/active_record/connection_adapters/materialize/type_metadata.rb
139
+ - lib/active_record/connection_adapters/materialize/utils.rb
140
+ - lib/active_record/connection_adapters/materialize/version.rb
141
+ - lib/active_record/connection_adapters/materialize_adapter.rb
142
+ - lib/active_record/tasks/materialize_database_tasks.rb
143
+ - lib/activerecord-materialize-adapter.rb
144
+ - lib/materialize/errors/database_error.rb
145
+ - lib/materialize/errors/incomplete_input.rb
146
+ homepage: https://rubygems.org/gems/activerecord-materialize-adapter
147
+ licenses:
148
+ - MIT
149
+ metadata:
150
+ source_code_uri: https://github.com/henrytseng/activerecord-materialize-adapter
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubygems_version: 3.0.6
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Database adapter for materialize.io database.
170
+ test_files: []