Module: Strata::CLI::DatasourceHelper
- Included in:
- Helpers::CommandContext, SubCommands::Audit, SubCommands::Datasource
- Defined in:
- lib/strata/cli/helpers/datasource_helper.rb
Constant Summary collapse
- ADAPTER_DRIVER_GEMS =
{ postgres: %w[pg], redshift: %w[pg], mysql: %w[mysql2], sqlserver: %w[tiny_tds], athena: %w[aws-sdk-athena aws-sdk-s3 rexml], trino: %w[trino-client], sqlite: %w[sqlite3], duckdb: %w[duckdb] }.freeze
Instance Method Summary collapse
- #apply_readonly_mode(adapter_sym, config) ⇒ Object
- #create_adapter(ds_key) ⇒ Object
- #ds_config(ds_key) ⇒ Object
- #ensure_adapter_driver_gems!(adapter_sym) ⇒ Object
- #load_adapter_driver_gems!(adapter_sym) ⇒ Object
- #resolve_datasource(ds_key_arg = nil, prompt: TTY::Prompt.new) ⇒ Object
- #resolve_datasource_value(value) ⇒ Object
Instance Method Details
#apply_readonly_mode(adapter_sym, config) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 69 def apply_readonly_mode(adapter_sym, config) case adapter_sym when :duckdb config["duck_config"] ||= {} config["duck_config"]["access_mode"] = "READ_ONLY" when :sqlite config["readonly"] = true end # Client-server databases (postgres, mysql, snowflake, etc.) # don't need special handling - no file lock issues end |
#create_adapter(ds_key) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 56 def create_adapter(ds_key) config = ds_config(ds_key).merge(Credentials.fetch(ds_key)) adapter_sym = config["adapter"].to_sym ensure_adapter_driver_gems!(adapter_sym) load_adapter_driver_gems!(adapter_sym) # CLI only performs read operations (test, tables, metadata). # Use read-only mode for file-based databases to avoid lock conflicts. apply_readonly_mode(adapter_sym, config) DWH.create(adapter_sym, config) end |
#ds_config(ds_key) ⇒ Object
126 127 128 129 130 131 132 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 126 def ds_config(ds_key) unless datasources.key?(ds_key) raise "Datasource definition with key #{ds_key} was not found in datasources.yml file." end datasources[ds_key] end |
#ensure_adapter_driver_gems!(adapter_sym) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 81 def ensure_adapter_driver_gems!(adapter_sym) required = ADAPTER_DRIVER_GEMS.fetch(adapter_sym, []) return if required.empty? missing = required.reject { gem_installed?(it) } return if missing.empty? if respond_to?(:say) say "Required gem(s) for '#{adapter_sym}' not found (#{missing.join(", ")}). Attempting to install...", :yellow end missing.each do |gem_name| system("gem", "install", gem_name, "-q", "--no-document") end still_missing = missing.reject { gem_installed?(it) } return if still_missing.empty? details = adapter_driver_gem_help(adapter_sym, still_missing) msg = <<~MSG Missing required gem(s) for adapter '#{adapter_sym}': #{still_missing.join(", ")} This adapter can't be used until the driver gem(s) are installed. Install manually: gem install #{still_missing.join(" ")} #{details} MSG raise Strata::CommandError, msg end |
#load_adapter_driver_gems!(adapter_sym) ⇒ Object
116 117 118 119 120 121 122 123 124 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 116 def load_adapter_driver_gems!(adapter_sym) required = ADAPTER_DRIVER_GEMS.fetch(adapter_sym, []) required.each do |gem_name| require gem_name rescue LoadError => e raise Strata::CommandError, "Installed gem '#{gem_name}' for adapter '#{adapter_sym}' could not be loaded: #{e.}" end end |
#resolve_datasource(ds_key_arg = nil, prompt: TTY::Prompt.new) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 19 def resolve_datasource(ds_key_arg = nil, prompt: TTY::Prompt.new) # 1. Use argument if provided return validate_datasource(ds_key_arg) if ds_key_arg # 2. Use option if provided return validate_datasource([:datasource]) if [:datasource] # 3. Check available datasources ds_keys = datasources.keys if agent_mode? if ds_keys.empty? agent_emit_no_datasources! elsif ds_keys.length == 1 return ds_keys.first else AgentOutput.emit_error( "Datasource key required. Available: #{ds_keys.join(", ")}", code: "datasource_key_required" ) end end if ds_keys.empty? say "No datasources configured. Run 'strata datasource add' first.", :red nil elsif ds_keys.length == 1 # Auto-select if only one ds_key = ds_keys.first say "Using datasource: #{ds_key}", :cyan ds_key else # Prompt selection if multiple prompt.select("Select datasource:", ds_keys) end end |
#resolve_datasource_value(value) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/strata/cli/helpers/datasource_helper.rb', line 134 def resolve_datasource_value(value) return nil if value.nil? || value.to_s.strip.empty? normalized = value.to_s.downcase.strip # Match by key first return value if datasources.key?(normalized) # Match by name (case-insensitive) datasources.each do |key, config| return key if config.is_a?(Hash) && config["name"].to_s.downcase.strip == normalized end nil end |