From 06f154b933eef58f0701baf53c1ed81f7f6c5fc9 Mon Sep 17 00:00:00 2001 From: KY Date: Wed, 17 May 2023 20:33:31 +0800 Subject: [PATCH] Add few more database related APIs GET /api/database/:id GET /api/database/:id/schemas GET /api/database/:id/schema/:schema --- .metabase.db/metabase.db.mv.db | Bin 274432 -> 274432 bytes lib/metabase/endpoint/database.rb | 28 ++++ spec/metabase/endpoint/database_spec.rb | 27 ++++ .../database/success/returns_a_database.yml | 118 +++++++++++++++++ ...s_all_tables_of_a_schema_of_a_database.yml | 122 ++++++++++++++++++ .../returns_all_schemas_of_a_database.yml | 116 +++++++++++++++++ 6 files changed, 411 insertions(+) create mode 100644 spec/vcr_cassettes/Metabase_Endpoint_Database/database/success/returns_a_database.yml create mode 100644 spec/vcr_cassettes/Metabase_Endpoint_Database/schema/success/returns_all_tables_of_a_schema_of_a_database.yml create mode 100644 spec/vcr_cassettes/Metabase_Endpoint_Database/schemas/success/returns_all_schemas_of_a_database.yml diff --git a/.metabase.db/metabase.db.mv.db b/.metabase.db/metabase.db.mv.db index 29f7e2a0fca371bf14b0b1eb9854ab11d92c1c4f..8aac6efcbda09b581b1d81db9ee2504a07a48707 100644 GIT binary patch delta 27584 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 delta 27080 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 E0G~0a(f|Me diff --git a/lib/metabase/endpoint/database.rb b/lib/metabase/endpoint/database.rb index a8fb281..21841e8 100644 --- a/lib/metabase/endpoint/database.rb +++ b/lib/metabase/endpoint/database.rb @@ -11,6 +11,34 @@ module Database def databases(**params) get('/api/database', **params) end + + # Fetch a database. + # + # @param database_id [Integer, String] Database ID + # @param params [Hash] Query string + # @return [Hash] Parsed response JSON + def database(database_id, **params) + get("/api/database/#{database_id}", **params) + end + + # Fetch schemas of a database. + # + # @param database_id [Integer, String] Database ID + # @param params [Hash] Query string + # @return [Array] Parsed response JSON + def schemas(database_id) + get("/api/database/#{database_id}/schemas") + end + + # Fetch tables of a schema of a database. + # + # @param database_id [Integer, String] Database ID + # @param schema [String] Schema name + # @param params [Hash] Query string + # @return [Array] Parsed response JSON + def schema(database_id, schema) + get("/api/database/#{database_id}/schema/#{schema}") + end end end end diff --git a/spec/metabase/endpoint/database_spec.rb b/spec/metabase/endpoint/database_spec.rb index d338220..3b61cea 100644 --- a/spec/metabase/endpoint/database_spec.rb +++ b/spec/metabase/endpoint/database_spec.rb @@ -11,4 +11,31 @@ end end end + + describe 'database', vcr: true do + context 'success' do + it 'returns a database' do + database = client.database(1) + expect(database).to be_kind_of(Hash) + end + end + end + + describe 'schemas', vcr: true do + context 'success' do + it 'returns all schemas of a database' do + schemas = client.schemas(1) + expect(schemas).to be_kind_of(Array) + end + end + end + + describe 'schema', vcr: true do + context 'success' do + it 'returns all tables of a schema of a database' do + tables = client.schema(1, "PUBLIC") + expect(tables).to be_kind_of(Array) + end + end + end end diff --git a/spec/vcr_cassettes/Metabase_Endpoint_Database/database/success/returns_a_database.yml b/spec/vcr_cassettes/Metabase_Endpoint_Database/database/success/returns_a_database.yml new file mode 100644 index 0000000..af32125 --- /dev/null +++ b/spec/vcr_cassettes/Metabase_Endpoint_Database/database/success/returns_a_database.yml @@ -0,0 +1,118 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3030/api/session + body: + encoding: UTF-8 + string: '{"username":"mb@example.com","password":"p@ssw0rd"}' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:31:00 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:31:00 GMT + Strict-Transport-Security: + - max-age=31536000 + Set-Cookie: + - metabase.SESSION=6603469c-6bfb-409f-9cb0-10aec630bd9a;SameSite=Lax;HttpOnly;Path=/;Max-Age=1209600 + - metabase.SESSION_ID=;Expires=Thu, 1 Jan 1970 00:00:00 GMT;Path=/ + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '{"id":"6603469c-6bfb-409f-9cb0-10aec630bd9a"}' + recorded_at: Wed, 17 May 2023 12:31:00 GMT +- request: + method: get + uri: http://localhost:3030/api/database/1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + X-Metabase-Session: + - 6603469c-6bfb-409f-9cb0-10aec630bd9a + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:31:00 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:31:00 GMT + Strict-Transport-Security: + - max-age=31536000 + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '{"description":null,"features":["basic-aggregations","standard-deviation-aggregations","expression-aggregations","foreign-keys","right-join","left-join","native-parameters","nested-queries","expressions","case-sensitivity-string-filter-options","binning","inner-join","advanced-math-expressions"],"cache_field_values_schedule":"0 + 50 0 * * ? *","timezone":"UTC","auto_run_queries":true,"metadata_sync_schedule":"0 + 50 * * * ? *","name":"Sample Dataset","caveats":null,"is_full_sync":true,"updated_at":"2023-05-17T12:28:01.088","details":{"db":"zip:/app/metabase.jar!/sample-dataset.db;USER=GUEST;PASSWORD=guest"},"is_sample":true,"id":1,"is_on_demand":false,"options":null,"schedules":{"cache_field_values":{"schedule_day":null,"schedule_frame":null,"schedule_hour":0,"schedule_type":"daily"},"metadata_sync":{"schedule_day":null,"schedule_frame":null,"schedule_hour":null,"schedule_type":"hourly"}},"engine":"h2","created_at":"2020-06-07T05:19:27.175","points_of_interest":null}' + recorded_at: Wed, 17 May 2023 12:31:00 GMT +recorded_with: VCR 6.0.0 diff --git a/spec/vcr_cassettes/Metabase_Endpoint_Database/schema/success/returns_all_tables_of_a_schema_of_a_database.yml b/spec/vcr_cassettes/Metabase_Endpoint_Database/schema/success/returns_all_tables_of_a_schema_of_a_database.yml new file mode 100644 index 0000000..340f7c8 --- /dev/null +++ b/spec/vcr_cassettes/Metabase_Endpoint_Database/schema/success/returns_all_tables_of_a_schema_of_a_database.yml @@ -0,0 +1,122 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3030/api/session + body: + encoding: UTF-8 + string: '{"username":"mb@example.com","password":"p@ssw0rd"}' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:33:01 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:33:01 GMT + Strict-Transport-Security: + - max-age=31536000 + Set-Cookie: + - metabase.SESSION=1d6c14e1-7f5d-43f3-b38b-aa0c1c0b7c5d;SameSite=Lax;HttpOnly;Path=/;Max-Age=1209600 + - metabase.SESSION_ID=;Expires=Thu, 1 Jan 1970 00:00:00 GMT;Path=/ + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '{"id":"1d6c14e1-7f5d-43f3-b38b-aa0c1c0b7c5d"}' + recorded_at: Wed, 17 May 2023 12:33:01 GMT +- request: + method: get + uri: http://localhost:3030/api/database/1/schema/PUBLIC + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + X-Metabase-Session: + - 1d6c14e1-7f5d-43f3-b38b-aa0c1c0b7c5d + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:33:01 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:33:01 GMT + Strict-Transport-Security: + - max-age=31536000 + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '[{"description":"This is a confirmed order for a product from a user.","entity_type":"entity/TransactionTable","schema":"PUBLIC","show_in_getting_started":false,"name":"ORDERS","caveats":null,"fields_hash":"Iqz4vNbm7vh80Uo9pWdesA==","rows":null,"updated_at":"2020-06-07T05:50:00.143","entity_name":null,"active":true,"id":2,"db_id":1,"visibility_type":null,"display_name":"Orders","created_at":"2020-06-07T05:19:27.483","points_of_interest":null},{"description":"This + is a user account. Note that employees and customer support staff will have + accounts.","entity_type":"entity/UserTable","schema":"PUBLIC","show_in_getting_started":false,"name":"PEOPLE","caveats":null,"fields_hash":"CXKI5VefRbNYgZ8IStmaNw==","rows":null,"updated_at":"2020-06-07T05:50:00.152","entity_name":null,"active":true,"id":3,"db_id":1,"visibility_type":null,"display_name":"People","created_at":"2020-06-07T05:19:27.486","points_of_interest":null},{"description":"This + is our product catalog. It includes all products ever sold by the Sample Company.","entity_type":"entity/ProductTable","schema":"PUBLIC","show_in_getting_started":false,"name":"PRODUCTS","caveats":null,"fields_hash":"aqXlpsb4FjyCH5o8qP4a2A==","rows":null,"updated_at":"2020-06-07T05:50:00.163","entity_name":null,"active":true,"id":1,"db_id":1,"visibility_type":null,"display_name":"Products","created_at":"2020-06-07T05:19:27.478","points_of_interest":null},{"description":"These + are reviews our customers have left on products. Note that these are not tied + to orders so it is possible people have reviewed products they did not purchase + from us.","entity_type":"entity/GenericTable","schema":"PUBLIC","show_in_getting_started":false,"name":"REVIEWS","caveats":null,"fields_hash":"wIcr7cLnXrbpAUfOXgcmeQ==","rows":null,"updated_at":"2020-06-07T05:50:00.168","entity_name":null,"active":true,"id":4,"db_id":1,"visibility_type":null,"display_name":"Reviews","created_at":"2020-06-07T05:19:27.49","points_of_interest":null}]' + recorded_at: Wed, 17 May 2023 12:33:01 GMT +recorded_with: VCR 6.0.0 diff --git a/spec/vcr_cassettes/Metabase_Endpoint_Database/schemas/success/returns_all_schemas_of_a_database.yml b/spec/vcr_cassettes/Metabase_Endpoint_Database/schemas/success/returns_all_schemas_of_a_database.yml new file mode 100644 index 0000000..630b86f --- /dev/null +++ b/spec/vcr_cassettes/Metabase_Endpoint_Database/schemas/success/returns_all_schemas_of_a_database.yml @@ -0,0 +1,116 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3030/api/session + body: + encoding: UTF-8 + string: '{"username":"mb@example.com","password":"p@ssw0rd"}' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:31:00 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:31:00 GMT + Strict-Transport-Security: + - max-age=31536000 + Set-Cookie: + - metabase.SESSION=769a5861-114f-42b6-9ab3-06e6e73e11c8;SameSite=Lax;HttpOnly;Path=/;Max-Age=1209600 + - metabase.SESSION_ID=;Expires=Thu, 1 Jan 1970 00:00:00 GMT;Path=/ + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '{"id":"769a5861-114f-42b6-9ab3-06e6e73e11c8"}' + recorded_at: Wed, 17 May 2023 12:31:00 GMT +- request: + method: get + uri: http://localhost:3030/api/database/1/schemas + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - MetabaseRuby/0.5.0 (ruby2.7.3) + X-Metabase-Session: + - 769a5861-114f-42b6-9ab3-06e6e73e11c8 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 17 May 2023 12:31:00 GMT + X-Frame-Options: + - DENY + X-Xss-Protection: + - 1; mode=block + Last-Modified: + - Wed, 17 May 2023 12:31:00 GMT + Strict-Transport-Security: + - max-age=31536000 + X-Permitted-Cross-Domain-Policies: + - none + Cache-Control: + - max-age=0, no-cache, must-revalidate, proxy-revalidate + X-Content-Type-Options: + - nosniff + Content-Security-Policy: + - default-src 'none'; script-src 'self' 'unsafe-eval' https://maps.google.com + https://apis.google.com https://www.google-analytics.com https://*.googleapis.com + *.gstatic.com 'sha256-lMAh4yjVuDkQ9NqkK4H+YHUga+anpFs5JAuj/uZh0Rs=' 'sha256-sMNbXyc1lLzhHbH/CKs11HIQMnMkZAN2eA99WhJeEC0=' + 'sha256-JJa56hyDfUbgNfq+0nq6Qs866JKgZ/+qCq2pkDJED8k='; child-src 'self' https://accounts.google.com; + style-src 'self' 'unsafe-inline'; font-src 'self' ; img-src * 'self' data:; + connect-src 'self' metabase.us10.list-manage.com ; manifest-src 'self'; + Content-Type: + - application/json;charset=utf-8 + Expires: + - Tue, 03 Jul 2001 06:00:00 GMT + Transfer-Encoding: + - chunked + Server: + - Jetty(9.4.27.v20200227) + body: + encoding: ASCII-8BIT + string: '["PUBLIC"]' + recorded_at: Wed, 17 May 2023 12:31:00 GMT +recorded_with: VCR 6.0.0