Skip to content

Commit effcd11

Browse files
committed
adds endpoints for database/list and sqllab/execute
1 parent bf4c46c commit effcd11

File tree

6 files changed

+239
-6
lines changed

6 files changed

+239
-6
lines changed

doc/setting_up_personal_api_credentials.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ Create your own .env file with
99

1010
Adjust .env as required.
1111
```
12-
ENV['SUPERSET_HOST'] = "https://your-superset-host.com"
13-
ENV['SUPERSET_API_USERNAME']="your-username"
14-
ENV['SUPERSET_API_PASSWORD']="your-password"
12+
SUPERSET_HOST="https://your-superset-host.com"
13+
SUPERSET_API_USERNAME="your-username"
14+
SUPERSET_API_PASSWORD="your-password"
1515
```
1616

1717
If you have multiple superset hosts across various environments you also have the option

lib/superset/database/list.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Usage: Superset::Database::List.call
2+
# Usage: Superset::Dashboard::List.new(title_contains: 'test').list
3+
4+
module Superset
5+
module Database
6+
class List < Superset::Request
7+
attr_reader :title_contains
8+
9+
def initialize(page_num: 0, title_contains: '')
10+
@title_contains = title_contains
11+
super(page_num: page_num)
12+
end
13+
14+
def self.call
15+
self.new.list
16+
end
17+
18+
def response
19+
validate_constructor_args
20+
super
21+
end
22+
23+
def ids
24+
result.map { |d| d[:id] }
25+
end
26+
27+
private
28+
29+
def route
30+
"database/?q=(#{query_params})"
31+
end
32+
33+
def filters
34+
# TODO filtering across all list classes can be refactored to support multiple options in a more flexible way
35+
filter_set = []
36+
filter_set << "(col:database_name,opr:ct,value:'#{title_contains}')" if title_contains.present?
37+
unless filter_set.empty?
38+
"filters:!(" + filter_set.join(',') + "),"
39+
end
40+
end
41+
42+
def list_attributes
43+
[:id, :database_name, :backend, :expose_in_sqllab]
44+
end
45+
46+
def validate_constructor_args
47+
raise InvalidParameterError, "title_contains must be a String type" unless title_contains.is_a?(String)
48+
end
49+
end
50+
end
51+
end

lib/superset/sqllab/execute.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module Superset
2+
module Sqllab
3+
class Execute < Superset::Request
4+
class InvalidParameterError < StandardError; end
5+
6+
attr_reader :database_id, :query, :schema
7+
8+
def initialize(database_id: , query: , schema: 'public')
9+
@database_id = database_id
10+
@query = query
11+
@schema = schema
12+
end
13+
14+
def perform
15+
validate_constructor_args
16+
response
17+
data
18+
end
19+
20+
def response
21+
@response ||= client.post(route, query_params)
22+
end
23+
24+
def data
25+
response["data"]
26+
end
27+
28+
private
29+
30+
def route
31+
"sqllab/execute/"
32+
end
33+
34+
def query_params
35+
{
36+
database_id: database_id,
37+
sql: query,
38+
schema: schema,
39+
queryLimit: 1000,
40+
runAsync: false,
41+
}
42+
end
43+
44+
def validate_constructor_args
45+
raise InvalidParameterError, "database_id integer is required" unless database_id.present? && database_id.is_a?(Integer)
46+
raise InvalidParameterError, "query string is required" unless query.present? && query.is_a?(String)
47+
raise InvalidParameterError, "schema must be a String type" unless schema.is_a?(String)
48+
end
49+
end
50+
end
51+
end

spec/superset/dashboard/list_spec.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,5 @@
108108
"),page:3,page_size:100")
109109
end
110110
end
111-
112-
113111
end
114-
115112
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe Superset::Database::List do
4+
subject { described_class.new }
5+
let(:result) do
6+
[
7+
{
8+
id: 1,
9+
database_name: 'Test 1',
10+
backend: 'postgres',
11+
expose_in_sqllab: 'true'
12+
},
13+
{
14+
id: 2,
15+
database_name: 'Test 2',
16+
backend: 'mysql',
17+
expose_in_sqllab: 'false'
18+
}
19+
]
20+
end
21+
22+
before do
23+
allow(subject).to receive(:result).and_return(result)
24+
end
25+
26+
describe '#rows' do
27+
specify do
28+
expect(subject.rows).to match_array(
29+
[
30+
['1', "Test 1", "postgres", "true"],
31+
['2', 'Test 2', 'mysql', "false"]
32+
]
33+
)
34+
end
35+
end
36+
37+
describe '#query_params' do
38+
context 'for pagination' do
39+
context 'with defaults' do
40+
specify do
41+
expect(subject.query_params).to eq("page:0,page_size:100")
42+
end
43+
end
44+
45+
context 'with specifiec page' do
46+
subject { described_class.new(page_num: 5) }
47+
48+
specify do
49+
expect(subject.query_params).to eq("page:5,page_size:100")
50+
end
51+
end
52+
end
53+
54+
context 'with title_contains filters' do
55+
subject { described_class.new(title_contains: 'acme') }
56+
57+
specify do
58+
expect(subject.query_params).to eq("filters:!((col:database_name,opr:ct,value:'acme')),page:0,page_size:100")
59+
end
60+
end
61+
end
62+
end
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe Superset::Sqllab::Execute do
4+
subject { described_class.new(
5+
database_id: database_id,
6+
query: query) }
7+
8+
let(:database_id) { 1 }
9+
let(:query) { 'select id, category, country from sales order by id asc limit 2' }
10+
let(:response) {
11+
{
12+
"query_id"=>1111,
13+
"status"=>"success",
14+
"data"=>
15+
[
16+
{"id"=>1, "category"=>"A", "country"=>"Australia"},
17+
{"id"=>2, "category"=>"B", "country"=>"New Zealand"}
18+
]
19+
}
20+
}
21+
22+
before do
23+
allow(subject).to receive(:response).and_return(response)
24+
end
25+
26+
describe 'perform' do
27+
context 'with valid params' do
28+
it 'returns the new dashboard object' do
29+
expect(subject.perform).to eq(response["data"])
30+
end
31+
end
32+
33+
context 'with invalid params' do
34+
context 'when database_id is not an integer' do
35+
let(:database_id) { 'q' }
36+
37+
it 'raises an error' do
38+
expect { subject.perform }.to raise_error(Superset::Sqllab::Execute::InvalidParameterError,
39+
"database_id integer is required")
40+
end
41+
end
42+
43+
context 'when database_id is not present' do
44+
let(:database_id) { nil }
45+
46+
it 'raises an error' do
47+
expect { subject.perform }.to raise_error(Superset::Sqllab::Execute::InvalidParameterError,
48+
"database_id integer is required")
49+
end
50+
end
51+
52+
context 'when query is not a string' do
53+
let(:query) { 1 }
54+
55+
it 'raises an error' do
56+
expect { subject.perform }.to raise_error(Superset::Sqllab::Execute::InvalidParameterError,
57+
"query string is required")
58+
end
59+
end
60+
61+
context 'when query is not present' do
62+
let(:query) { nil }
63+
64+
it 'raises an error' do
65+
expect { subject.perform }.to raise_error(Superset::Sqllab::Execute::InvalidParameterError,
66+
"query string is required")
67+
end
68+
end
69+
70+
end
71+
end
72+
end

0 commit comments

Comments
 (0)