better_structure_sql 0.1.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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +41 -0
  3. data/LICENSE +21 -0
  4. data/README.md +557 -0
  5. data/app/controllers/better_structure_sql/application_controller.rb +61 -0
  6. data/app/controllers/better_structure_sql/schema_versions_controller.rb +243 -0
  7. data/app/helpers/better_structure_sql/schema_versions_helper.rb +46 -0
  8. data/app/views/better_structure_sql/schema_versions/index.html.erb +110 -0
  9. data/app/views/better_structure_sql/schema_versions/show.html.erb +186 -0
  10. data/app/views/layouts/better_structure_sql/application.html.erb +105 -0
  11. data/config/database.yml +3 -0
  12. data/config/routes.rb +12 -0
  13. data/lib/better_structure_sql/adapters/base_adapter.rb +234 -0
  14. data/lib/better_structure_sql/adapters/mysql_adapter.rb +476 -0
  15. data/lib/better_structure_sql/adapters/mysql_config.rb +32 -0
  16. data/lib/better_structure_sql/adapters/postgresql_adapter.rb +646 -0
  17. data/lib/better_structure_sql/adapters/postgresql_config.rb +25 -0
  18. data/lib/better_structure_sql/adapters/registry.rb +115 -0
  19. data/lib/better_structure_sql/adapters/sqlite_adapter.rb +644 -0
  20. data/lib/better_structure_sql/adapters/sqlite_config.rb +26 -0
  21. data/lib/better_structure_sql/configuration.rb +129 -0
  22. data/lib/better_structure_sql/database_version.rb +46 -0
  23. data/lib/better_structure_sql/dependency_resolver.rb +63 -0
  24. data/lib/better_structure_sql/dumper.rb +544 -0
  25. data/lib/better_structure_sql/engine.rb +28 -0
  26. data/lib/better_structure_sql/file_writer.rb +180 -0
  27. data/lib/better_structure_sql/formatter.rb +70 -0
  28. data/lib/better_structure_sql/generators/base.rb +33 -0
  29. data/lib/better_structure_sql/generators/domain_generator.rb +22 -0
  30. data/lib/better_structure_sql/generators/extension_generator.rb +23 -0
  31. data/lib/better_structure_sql/generators/foreign_key_generator.rb +43 -0
  32. data/lib/better_structure_sql/generators/function_generator.rb +33 -0
  33. data/lib/better_structure_sql/generators/index_generator.rb +50 -0
  34. data/lib/better_structure_sql/generators/materialized_view_generator.rb +31 -0
  35. data/lib/better_structure_sql/generators/pragma_generator.rb +23 -0
  36. data/lib/better_structure_sql/generators/sequence_generator.rb +27 -0
  37. data/lib/better_structure_sql/generators/table_generator.rb +126 -0
  38. data/lib/better_structure_sql/generators/trigger_generator.rb +54 -0
  39. data/lib/better_structure_sql/generators/type_generator.rb +47 -0
  40. data/lib/better_structure_sql/generators/view_generator.rb +27 -0
  41. data/lib/better_structure_sql/introspection/extensions.rb +29 -0
  42. data/lib/better_structure_sql/introspection/foreign_keys.rb +29 -0
  43. data/lib/better_structure_sql/introspection/functions.rb +29 -0
  44. data/lib/better_structure_sql/introspection/indexes.rb +29 -0
  45. data/lib/better_structure_sql/introspection/sequences.rb +29 -0
  46. data/lib/better_structure_sql/introspection/tables.rb +29 -0
  47. data/lib/better_structure_sql/introspection/triggers.rb +29 -0
  48. data/lib/better_structure_sql/introspection/types.rb +37 -0
  49. data/lib/better_structure_sql/introspection/views.rb +41 -0
  50. data/lib/better_structure_sql/introspection.rb +31 -0
  51. data/lib/better_structure_sql/manifest_generator.rb +65 -0
  52. data/lib/better_structure_sql/migration_patch.rb +196 -0
  53. data/lib/better_structure_sql/pg_version.rb +44 -0
  54. data/lib/better_structure_sql/railtie.rb +124 -0
  55. data/lib/better_structure_sql/schema_loader.rb +168 -0
  56. data/lib/better_structure_sql/schema_version.rb +86 -0
  57. data/lib/better_structure_sql/schema_versions.rb +213 -0
  58. data/lib/better_structure_sql/version.rb +5 -0
  59. data/lib/better_structure_sql/zip_generator.rb +81 -0
  60. data/lib/better_structure_sql.rb +81 -0
  61. data/lib/generators/better_structure_sql/install_generator.rb +44 -0
  62. data/lib/generators/better_structure_sql/migration_generator.rb +34 -0
  63. data/lib/generators/better_structure_sql/templates/README +49 -0
  64. data/lib/generators/better_structure_sql/templates/add_metadata_migration.rb.erb +25 -0
  65. data/lib/generators/better_structure_sql/templates/better_structure_sql.rb +46 -0
  66. data/lib/generators/better_structure_sql/templates/migration.rb.erb +26 -0
  67. data/lib/tasks/better_structure_sql.rake +190 -0
  68. metadata +299 -0
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterStructureSql
4
+ module Adapters
5
+ # Registry for database adapters using factory pattern.
6
+ # Handles adapter detection from ActiveRecord connection and caching.
7
+ class Registry
8
+ class << self
9
+ # Get adapter for a connection (with caching)
10
+ # @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
11
+ # @param adapter_override [Symbol, nil] Manual adapter override (:postgresql, :mysql, :sqlite, :auto)
12
+ # @return [BaseAdapter] Adapter instance
13
+ def adapter_for(connection, adapter_override: :auto)
14
+ # Use cache key based on connection object_id and adapter override
15
+ cache_key = "#{connection.object_id}_#{adapter_override}"
16
+
17
+ @adapter_cache ||= {}
18
+ @adapter_cache[cache_key] ||= create_adapter(connection, adapter_override)
19
+ end
20
+
21
+ # Clear adapter cache (useful for testing)
22
+ def clear_cache!
23
+ @adapter_cache = {}
24
+ end
25
+
26
+ private
27
+
28
+ # Create new adapter instance
29
+ # @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
30
+ # @param adapter_override [Symbol] Adapter type
31
+ # @return [BaseAdapter] Adapter instance
32
+ def create_adapter(connection, adapter_override)
33
+ adapter_name = resolve_adapter_name(connection, adapter_override)
34
+
35
+ case adapter_name
36
+ when :postgresql
37
+ require_relative 'postgresql_adapter'
38
+ PostgresqlAdapter.new(connection)
39
+ when :mysql
40
+ require_relative 'mysql_adapter'
41
+ validate_mysql_gem!
42
+ MysqlAdapter.new(connection)
43
+ when :sqlite
44
+ require_relative 'sqlite_adapter'
45
+ validate_sqlite_gem!
46
+ SqliteAdapter.new(connection)
47
+ else
48
+ raise Error, "Unknown database adapter: #{adapter_name}"
49
+ end
50
+ end
51
+
52
+ # Resolve adapter name from connection or override
53
+ # @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
54
+ # @param adapter_override [Symbol] Manual override or :auto
55
+ # @return [Symbol] Adapter name (:postgresql, :mysql, :sqlite)
56
+ def resolve_adapter_name(connection, adapter_override)
57
+ if adapter_override != :auto
58
+ validate_adapter_override!(adapter_override)
59
+ return adapter_override
60
+ end
61
+
62
+ # Auto-detect from ActiveRecord connection
63
+ detect_adapter_from_connection(connection)
64
+ end
65
+
66
+ # Detect adapter from ActiveRecord connection
67
+ # @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
68
+ # @return [Symbol] Adapter name
69
+ def detect_adapter_from_connection(connection)
70
+ adapter_name = connection.adapter_name.downcase
71
+
72
+ case adapter_name
73
+ when 'postgresql', 'postgis'
74
+ :postgresql
75
+ when 'mysql2', 'mysql', 'trilogy'
76
+ :mysql
77
+ when 'sqlite3', 'sqlite'
78
+ :sqlite
79
+ else
80
+ raise Error, "Unsupported database adapter: #{adapter_name}. " \
81
+ 'Supported: postgresql, mysql2, sqlite3'
82
+ end
83
+ end
84
+
85
+ # Validate manual adapter override
86
+ # @param adapter_override [Symbol]
87
+ # @raise [Error] If adapter override is invalid
88
+ def validate_adapter_override!(adapter_override)
89
+ valid_adapters = %i[postgresql mysql sqlite auto]
90
+
91
+ return if valid_adapters.include?(adapter_override)
92
+
93
+ raise Error, "Invalid adapter override: #{adapter_override}. " \
94
+ "Valid options: #{valid_adapters.join(', ')}"
95
+ end
96
+
97
+ # Validate mysql2 gem is available
98
+ # @raise [Error] If mysql2 gem is not installed
99
+ def validate_mysql_gem!
100
+ require 'mysql2'
101
+ rescue LoadError
102
+ raise Error, 'MySQL adapter requires the mysql2 gem. Add to your Gemfile: gem "mysql2"'
103
+ end
104
+
105
+ # Validate sqlite3 gem is available
106
+ # @raise [Error] If sqlite3 gem is not installed
107
+ def validate_sqlite_gem!
108
+ require 'sqlite3'
109
+ rescue LoadError
110
+ raise Error, 'SQLite adapter requires the sqlite3 gem. Add to your Gemfile: gem "sqlite3"'
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end