Class: WOWSQL::WOWSQLStorage
- Inherits:
-
Object
- Object
- WOWSQL::WOWSQLStorage
- Defined in:
- lib/wowsql/storage.rb
Overview
WowSQL Storage Client — PostgreSQL-native file storage.
Files are stored as BYTEA inside each project’s storage schema. No external S3 dependency — everything lives in PostgreSQL.
Instance Attribute Summary collapse
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
-
#project_slug ⇒ Object
readonly
Returns the value of attribute project_slug.
Instance Method Summary collapse
-
#close ⇒ Object
Close the HTTP connection.
-
#create_bucket(name, public: false, file_size_limit: nil, allowed_mime_types: nil) ⇒ StorageBucket
Create a new storage bucket.
-
#delete_bucket(name) ⇒ Hash
Delete a bucket and all its files.
-
#delete_file(bucket_name, file_path) ⇒ Hash
Delete a file from a bucket.
-
#download(bucket_name, file_path) ⇒ String
Download a file and return its binary contents.
-
#download_to_file(bucket_name, file_path, local_path) ⇒ String
Download a file and save it to a local path.
-
#get_bucket(name) ⇒ StorageBucket
Get a specific bucket by name.
-
#get_public_url(bucket_name, file_path) ⇒ String
Get the public URL for a file in a public bucket (no auth required).
-
#get_quota(force_refresh: false) ⇒ StorageQuota
Get storage quota (alias for get_stats).
-
#get_stats ⇒ StorageQuota
Get storage statistics for the project.
-
#initialize(project_url = '', api_key = '', project_slug: '', base_url: '', base_domain: 'wowsqlconnect.com', secure: true, timeout: 60, verify_ssl: true) ⇒ WOWSQLStorage
constructor
A new instance of WOWSQLStorage.
-
#list_buckets ⇒ Array<StorageBucket>
List all buckets in the project.
-
#list_files(bucket_name, prefix: nil, limit: 100, offset: 0) ⇒ Array<StorageFile>
List files in a bucket.
- #to_s ⇒ Object (also: #inspect)
-
#update_bucket(name, **options) ⇒ StorageBucket
Update bucket settings.
-
#upload(bucket_name, file_data, path: nil, file_name: nil) ⇒ StorageFile
Upload a file to a bucket.
-
#upload_from_path(file_path, bucket_name: 'default', path: nil) ⇒ StorageFile
Upload a file from a local filesystem path.
Constructor Details
#initialize(project_url = '', api_key = '', project_slug: '', base_url: '', base_domain: 'wowsqlconnect.com', secure: true, timeout: 60, verify_ssl: true) ⇒ WOWSQLStorage
Returns a new instance of WOWSQLStorage.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/wowsql/storage.rb', line 105 def initialize(project_url = '', api_key = '', project_slug: '', base_url: '', base_domain: 'wowsqlconnect.com', secure: true, timeout: 60, verify_ssl: true) if !project_slug.empty? && !base_url.empty? @base_url = base_url.chomp('/') @project_slug = project_slug elsif !project_url.empty? url = project_url.strip if url.start_with?('http://') || url.start_with?('https://') @base_url = url.chomp('/') @base_url = @base_url.split('/api').first if @base_url.include?('/api') else protocol = secure ? 'https' : 'http' if url.include?(".#{base_domain}") || url.end_with?(base_domain) @base_url = "#{protocol}://#{url}" else @base_url = "#{protocol}://#{url}.#{base_domain}" end end @project_slug = url.split('.').first .sub('https://', '') .sub('http://', '') else raise ArgumentError, 'Either project_url or (project_slug + base_url) must be provided' end @timeout = timeout @verify_ssl = verify_ssl = verify_ssl ? {} : { verify: false } @conn = Faraday.new(url: @base_url, ssl: ) do |f| f.request :multipart f.request :json f.response :json f.adapter Faraday.default_adapter f..timeout = timeout end @conn.headers['Authorization'] = "Bearer #{api_key}" end |
Instance Attribute Details
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
95 96 97 |
# File 'lib/wowsql/storage.rb', line 95 def base_url @base_url end |
#project_slug ⇒ Object (readonly)
Returns the value of attribute project_slug.
95 96 97 |
# File 'lib/wowsql/storage.rb', line 95 def project_slug @project_slug end |
Instance Method Details
#close ⇒ Object
Close the HTTP connection.
342 343 344 |
# File 'lib/wowsql/storage.rb', line 342 def close @conn.close if @conn.respond_to?(:close) end |
#create_bucket(name, public: false, file_size_limit: nil, allowed_mime_types: nil) ⇒ StorageBucket
Create a new storage bucket.
155 156 157 158 159 160 161 162 163 |
# File 'lib/wowsql/storage.rb', line 155 def create_bucket(name, public: false, file_size_limit: nil, allowed_mime_types: nil) data = request('POST', "/api/v1/storage/projects/#{@project_slug}/buckets", nil, { name: name, public: public, file_size_limit: file_size_limit, allowed_mime_types: allowed_mime_types }) StorageBucket.new(data) end |
#delete_bucket(name) ⇒ Hash
Delete a bucket and all its files.
196 197 198 |
# File 'lib/wowsql/storage.rb', line 196 def delete_bucket(name) request('DELETE', "/api/v1/storage/projects/#{@project_slug}/buckets/#{name}", nil, nil) end |
#delete_file(bucket_name, file_path) ⇒ Hash
Delete a file from a bucket.
309 310 311 |
# File 'lib/wowsql/storage.rb', line 309 def delete_file(bucket_name, file_path) request('DELETE', "/api/v1/storage/projects/#{@project_slug}/files/#{bucket_name}/#{file_path}", nil, nil) end |
#download(bucket_name, file_path) ⇒ String
Download a file and return its binary contents.
278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/wowsql/storage.rb', line 278 def download(bucket_name, file_path) url = "/api/v1/storage/projects/#{@project_slug}/files/#{bucket_name}/#{file_path}" response = @conn.get(url) if response.status >= 400 handle_error(response) end response.body rescue Faraday::Error => e raise StorageError.new("Download failed: #{e.}") end |
#download_to_file(bucket_name, file_path, local_path) ⇒ String
Download a file and save it to a local path.
296 297 298 299 300 301 302 |
# File 'lib/wowsql/storage.rb', line 296 def download_to_file(bucket_name, file_path, local_path) content = download(bucket_name, file_path) dir = File.dirname(local_path) FileUtils.mkdir_p(dir) unless dir == '.' File.open(local_path, 'wb') { |f| f.write(content) } local_path end |
#get_bucket(name) ⇒ StorageBucket
Get a specific bucket by name.
177 178 179 180 |
# File 'lib/wowsql/storage.rb', line 177 def get_bucket(name) data = request('GET', "/api/v1/storage/projects/#{@project_slug}/buckets/#{name}", nil, nil) StorageBucket.new(data) end |
#get_public_url(bucket_name, file_path) ⇒ String
Get the public URL for a file in a public bucket (no auth required).
320 321 322 |
# File 'lib/wowsql/storage.rb', line 320 def get_public_url(bucket_name, file_path) "#{@base_url}/api/v1/storage/projects/#{@project_slug}/files/#{bucket_name}/#{file_path}" end |
#get_quota(force_refresh: false) ⇒ StorageQuota
Get storage quota (alias for get_stats).
335 336 337 |
# File 'lib/wowsql/storage.rb', line 335 def get_quota(force_refresh: false) get_stats end |
#get_stats ⇒ StorageQuota
Get storage statistics for the project.
327 328 329 330 |
# File 'lib/wowsql/storage.rb', line 327 def get_stats data = request('GET', "/api/v1/storage/projects/#{@project_slug}/stats", nil, nil) StorageQuota.new(data) end |
#list_buckets ⇒ Array<StorageBucket>
List all buckets in the project.
168 169 170 171 |
# File 'lib/wowsql/storage.rb', line 168 def list_buckets data = request('GET', "/api/v1/storage/projects/#{@project_slug}/buckets", nil, nil) Array(data).map { |b| StorageBucket.new(b) } end |
#list_files(bucket_name, prefix: nil, limit: 100, offset: 0) ⇒ Array<StorageFile>
List files in a bucket.
264 265 266 267 268 269 270 271 |
# File 'lib/wowsql/storage.rb', line 264 def list_files(bucket_name, prefix: nil, limit: 100, offset: 0) params = { 'limit' => limit, 'offset' => offset } params['prefix'] = prefix if prefix data = request('GET', "/api/v1/storage/projects/#{@project_slug}/buckets/#{bucket_name}/files", params, nil) items = data.is_a?(Array) ? data : (data['files'] || data['data'] || []) items.map { |f| StorageFile.new(f) } end |
#to_s ⇒ Object Also known as: inspect
346 347 348 |
# File 'lib/wowsql/storage.rb', line 346 def to_s "WOWSQLStorage(project=#{@project_slug.inspect})" end |
#update_bucket(name, **options) ⇒ StorageBucket
Update bucket settings.
187 188 189 190 |
# File 'lib/wowsql/storage.rb', line 187 def update_bucket(name, **) data = request('PATCH', "/api/v1/storage/projects/#{@project_slug}/buckets/#{name}", nil, ) StorageBucket.new(data) end |
#upload(bucket_name, file_data, path: nil, file_name: nil) ⇒ StorageFile
Upload a file to a bucket.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/wowsql/storage.rb', line 209 def upload(bucket_name, file_data, path: nil, file_name: nil) content = file_data.respond_to?(:read) ? file_data.read : file_data name = file_name || (file_data.respond_to?(:path) ? File.basename(file_data.path) : nil) || path || 'file' name = name.split('/').last if name.include?('/') folder = '' if path && path.include?('/') folder = path.rpartition('/').first end params = {} params['folder'] = folder unless folder.empty? upload_io = Faraday::Multipart::FilePart.new( StringIO.new(content.is_a?(String) ? content : content.to_s), 'application/octet-stream', name ) response = @conn.post("/api/v1/storage/projects/#{@project_slug}/buckets/#{bucket_name}/files") do |req| req.params = params unless params.empty? req.body = { file: upload_io } end if response.status >= 400 handle_error(response) end StorageFile.new(response.body) rescue Faraday::Error => e raise StorageError.new("Upload failed: #{e.}") end |
#upload_from_path(file_path, bucket_name: 'default', path: nil) ⇒ StorageFile
Upload a file from a local filesystem path.
248 249 250 251 252 253 254 255 |
# File 'lib/wowsql/storage.rb', line 248 def upload_from_path(file_path, bucket_name: 'default', path: nil) raise StorageError.new("File not found: #{file_path}") unless File.exist?(file_path) file_name = File.basename(file_path) File.open(file_path, 'rb') do |f| upload(bucket_name, f, path: path || file_name, file_name: file_name) end end |