tableau_server_client 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e288311bd523063625df63be79cff2295f1d48b0a17c2dc8712145be68d44ec
|
4
|
+
data.tar.gz: 02db553763acd7e4de9fa06966dde66d2a92a6bcae70ed1734c16e7ddbe474bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c105d2be4dd5e12fc6230fe3edc7c3927c5ed900912e8130a68cbc8dfd948b66b74ffd187a3bf8e66cc877d7edb2e0a84bd11681c11ba1f588b4c6e6dfb64dc
|
7
|
+
data.tar.gz: 66d0710f717c507e1f5e32ac7dcebbb46d6e07c9f4bc71afb9d09f181ccb9636004f1fe82bf3bf694e01bc77f2b38e9ee4ae875a31907e3df38d47732636c4fc
|
@@ -5,6 +5,9 @@ require 'tableau_server_client/request_url'
|
|
5
5
|
require 'tableau_server_client/request_builder'
|
6
6
|
require 'tableau_server_client/token'
|
7
7
|
require 'tableau_server_client/paginatable_response'
|
8
|
+
require 'tempfile'
|
9
|
+
require 'zip'
|
10
|
+
require 'stringio'
|
8
11
|
|
9
12
|
module TableauServerClient
|
10
13
|
|
@@ -46,6 +49,25 @@ module TableauServerClient
|
|
46
49
|
def create(resource)
|
47
50
|
end
|
48
51
|
|
52
|
+
def download(resource_location)
|
53
|
+
req_url = request_url("#{resource_location.path}/content", resource_location.query_params)
|
54
|
+
response = session.get req_url.to_s
|
55
|
+
type, disposition = response.headers.values_at('content-type', 'content-disposition')
|
56
|
+
case type
|
57
|
+
when 'application/xml'
|
58
|
+
return Nokogiri::XML(response.body)
|
59
|
+
when 'application/octet-stream'
|
60
|
+
Zip::InputStream.open(StringIO.new(response.body)) do |io|
|
61
|
+
while entry = io.get_next_entry
|
62
|
+
return Nokogiri::XML(io.read) if entry.name =~ /.*\.(tds|twb)/
|
63
|
+
end
|
64
|
+
raise "TDS or TWB file not found for: #{resource_location.path}"
|
65
|
+
end
|
66
|
+
else
|
67
|
+
raise "Unknown content-type: #{type}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
49
71
|
def update(resource)
|
50
72
|
session.put do |req|
|
51
73
|
req.url request_url(resource.path).to_s
|
@@ -26,7 +26,7 @@ module TableauServerClient
|
|
26
26
|
|
27
27
|
def self.location(prefix, id=nil, filter: [])
|
28
28
|
path = [prefix, "#{resource_name}s", id].compact.join("/")
|
29
|
-
Location.new(self, path, filter)
|
29
|
+
Location.new(self, path, filter.empty? ? {} : {filter: filter.join(',')})
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.extract_attributes(xml)
|
@@ -49,6 +49,10 @@ module TableauServerClient
|
|
49
49
|
@path
|
50
50
|
end
|
51
51
|
|
52
|
+
def location(query_params: {})
|
53
|
+
Location.new(self, path, query_params)
|
54
|
+
end
|
55
|
+
|
52
56
|
def site_path
|
53
57
|
self.class.extract_site_path(path)
|
54
58
|
end
|
@@ -59,21 +63,13 @@ module TableauServerClient
|
|
59
63
|
|
60
64
|
class Location
|
61
65
|
|
62
|
-
def initialize(klass, path,
|
66
|
+
def initialize(klass, path, query_params)
|
63
67
|
@klass = klass
|
64
68
|
@path = path
|
65
|
-
@
|
66
|
-
end
|
67
|
-
|
68
|
-
attr_reader :klass, :path
|
69
|
-
|
70
|
-
def filter
|
71
|
-
@filter.empty? ? {} : {filter: @filter.join(",")}
|
69
|
+
@query_params = query_params
|
72
70
|
end
|
73
71
|
|
74
|
-
|
75
|
-
filter
|
76
|
-
end
|
72
|
+
attr_reader :klass, :path, :query_params
|
77
73
|
end
|
78
74
|
|
79
75
|
class Attribute < String
|
@@ -49,6 +49,70 @@ module TableauServerClient
|
|
49
49
|
@client.update self
|
50
50
|
end
|
51
51
|
|
52
|
+
def custom_queries
|
53
|
+
relations.select {|r| r['type'] == 'text' }.map {|c| c.content }
|
54
|
+
end
|
55
|
+
|
56
|
+
def tables
|
57
|
+
tables = []
|
58
|
+
redshift_connections = named_connections.select {|c| c.class == 'redshift' }.map {|c| c.name }
|
59
|
+
relations.each do |rel|
|
60
|
+
next unless redshift_connections.include? rel['connection']
|
61
|
+
case rel['type']
|
62
|
+
when 'table'
|
63
|
+
tables << rel['table']
|
64
|
+
when 'text'
|
65
|
+
tables.concat extract_tables(rel.content)
|
66
|
+
else
|
67
|
+
next
|
68
|
+
end
|
69
|
+
end
|
70
|
+
tables.map {|t| t.gsub(/[\[\]")]/, '')}.uniq
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
NamedConnection = Struct.new("NamedConnections", :class, :caption, :name)
|
76
|
+
def named_connections
|
77
|
+
download.xpath('//named-connection').map do |c|
|
78
|
+
NamedConnection.new(c.first_element_child['class'], c['caption'], c['name'])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def download
|
83
|
+
@twb ||= @client.download location(query_params: {"includeExtract": "False"})
|
84
|
+
end
|
85
|
+
|
86
|
+
def relations
|
87
|
+
download.xpath('//datasources//datasource//relation')
|
88
|
+
end
|
89
|
+
|
90
|
+
def extract_tables(query)
|
91
|
+
q = query.dup
|
92
|
+
q.gsub!(/(\<\[Parameters\]\.\[.*?\]\>)/, "'\\1'")\
|
93
|
+
.gsub!(/(--[^\r\n]*)|(\/\*[\w\W]*?(?=\*\/)\*\/)/m, '')\
|
94
|
+
.gsub!(/[\t\r\n]/, ' ')\
|
95
|
+
.gsub!(/\s+/, ' ')
|
96
|
+
|
97
|
+
tables = []
|
98
|
+
may_be_table = false
|
99
|
+
q.split(' ').each do |t|
|
100
|
+
t.downcase!
|
101
|
+
if may_be_table
|
102
|
+
tables << t unless t =~ /(^select|^\(.*)/
|
103
|
+
may_be_table = false
|
104
|
+
end
|
105
|
+
if ['from', 'join'].include?(t)
|
106
|
+
may_be_table = true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
tables
|
110
|
+
# ParseError with sub-query without alias name
|
111
|
+
#PgQuery.parse(no_parameter_query).tables.each do |t|
|
112
|
+
# yield t
|
113
|
+
#end
|
114
|
+
end
|
115
|
+
|
52
116
|
end
|
53
117
|
end
|
54
118
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tableau_server_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- shimpeko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 0.11.3
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubyzip
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.2.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.2.1
|
111
125
|
description: REST API Client for Tableau Server.
|
112
126
|
email:
|
113
127
|
- shimpeko@swimmingpython.com
|