Class: WOWSQL::WOWSQLClient

Inherits:
Object
  • Object
show all
Defined in:
lib/wowsql/client.rb

Overview

WowSQL client for PostgREST-native database operations.

All requests are sent directly to the PostgREST endpoint (/rest/v1).

Examples:

client = WOWSQL::WOWSQLClient.new("myproject", "wowsql_anon_...")
result = client.table("users").get

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project_url, api_key, base_domain: 'wowsqlconnect.com', secure: true, timeout: 30, verify_ssl: true) ⇒ WOWSQLClient

Returns a new instance of WOWSQLClient.

Parameters:

  • project_url (String)

    Project slug, domain, or full URL

  • api_key (String)

    Anonymous or service role key

  • base_domain (String) (defaults to: 'wowsqlconnect.com')

    Base domain appended when project_url is a slug (default: wowsqlconnect.com)

  • secure (Boolean) (defaults to: true)

    Use HTTPS (default: true)

  • timeout (Integer) (defaults to: 30)

    Request timeout in seconds (default: 30)

  • verify_ssl (Boolean) (defaults to: true)

    Verify SSL certificates (default: true)



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
55
56
57
58
59
# File 'lib/wowsql/client.rb', line 23

def initialize(project_url, api_key,
               base_domain: 'wowsqlconnect.com',
               secure: true,
               timeout: 30,
               verify_ssl: true)
  @api_key    = api_key
  @timeout    = timeout
  @verify_ssl = verify_ssl
  @last_content_range = nil

  if project_url.start_with?('http://', 'https://')
    base = project_url.chomp('/')
    base = base.split('/api').first if base.include?('/api')
    @base_url = base
  else
    protocol = secure ? 'https' : 'http'
    if project_url.include?(".#{base_domain}") || project_url.end_with?(base_domain)
      @base_url = "#{protocol}://#{project_url}"
    else
      @base_url = "#{protocol}://#{project_url}.#{base_domain}"
    end
  end

  @api_url = "#{@base_url}/rest/v1"

  ssl_options = verify_ssl ? {} : { verify: false }

  @conn = Faraday.new(url: @api_url, ssl: ssl_options) do |f|
    f.request  :json
    f.response :json
    f.adapter  Faraday.default_adapter
    f.options.timeout = timeout
  end

  @conn.headers['apikey']       = api_key
  @conn.headers['Content-Type'] = 'application/json'
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



15
16
17
# File 'lib/wowsql/client.rb', line 15

def api_key
  @api_key
end

#api_urlObject (readonly)

Returns the value of attribute api_url.



15
16
17
# File 'lib/wowsql/client.rb', line 15

def api_url
  @api_url
end

#last_content_rangeObject (readonly)

Returns the value of attribute last_content_range.



15
16
17
# File 'lib/wowsql/client.rb', line 15

def last_content_range
  @last_content_range
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



15
16
17
# File 'lib/wowsql/client.rb', line 15

def timeout
  @timeout
end

#verify_sslObject (readonly)

Returns the value of attribute verify_ssl.



15
16
17
# File 'lib/wowsql/client.rb', line 15

def verify_ssl
  @verify_ssl
end

Class Method Details

.parse_total_from_content_range(header, fallback) ⇒ Integer

Parse total count from a Content-Range header value.

Parameters:

  • header (String, nil)

    e.g. “0-19/100”

  • fallback (Integer)

Returns:

  • (Integer)


107
108
109
110
111
# File 'lib/wowsql/client.rb', line 107

def self.parse_total_from_content_range(header, fallback)
  return fallback unless header&.include?('/')
  val = header.split('/').last.to_i
  val > 0 ? val : fallback
end

Instance Method Details

#closeObject

Close the HTTP connection (no-op, provided for API parity).



70
71
72
# File 'lib/wowsql/client.rb', line 70

def close
  @conn.close if @conn.respond_to?(:close)
end

#request(method, path, params = nil, json = nil, headers = nil) ⇒ Array, ...

Make an HTTP request to the PostgREST endpoint.

Parameters:

  • method (String)

    HTTP method

  • path (String)

    Path (relative to /rest/v1)

  • params (Hash, nil) (defaults to: nil)

    Query parameters

  • json (Hash, nil) (defaults to: nil)

    Request body

  • headers (Hash, nil) (defaults to: nil)

    Additional headers (e.g. Prefer, on-conflict)

Returns:

  • (Array, Hash, nil)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/wowsql/client.rb', line 82

def request(method, path, params = nil, json = nil, headers = nil)
  response = @conn.public_send(method.downcase, path) do |req|
    req.params  = params  if params
    req.body    = json    if json
    req.headers = req.headers.merge(headers) if headers
  end

  @last_content_range = response.headers['content-range']

  if response.status >= 400
    error_data = response.body.is_a?(Hash) ? response.body : {}
    error_msg  = error_data['message'] || error_data['detail'] || "Request failed with status #{response.status}"
    raise WOWSQLError.new(error_msg, response.status, error_data)
  end

  response.body
rescue Faraday::Error => e
  raise WOWSQLError.new("Request failed: #{e.message}")
end

#table(table_name) ⇒ Table

Return a Table interface for the given table name.

Parameters:

  • table_name (String)

Returns:



65
66
67
# File 'lib/wowsql/client.rb', line 65

def table(table_name)
  Table.new(self, table_name)
end