tableau_server_client 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 886e88eedf330cdb09d92a5fe2bd7e1452c19c9e413fb5767098376c17d03608
4
- data.tar.gz: 5884c44fc430ff3ac02fa6d94e3f5a4edc426de9597281f019694a5fb2a76ace
3
+ metadata.gz: 0e288311bd523063625df63be79cff2295f1d48b0a17c2dc8712145be68d44ec
4
+ data.tar.gz: 02db553763acd7e4de9fa06966dde66d2a92a6bcae70ed1734c16e7ddbe474bd
5
5
  SHA512:
6
- metadata.gz: 32050b19c3d0ef603e5476f879070cf3c14cdefc522beb4a4367fb33272e79c62a1a12cc65e2799a53aa6035f8c9e3ea5cd43eac3dc59c5f4db38beee53d13cb
7
- data.tar.gz: a682c5b349b0ff0a36e15535b2da7fc52a77ba2275a2c58ee0cd8d820b3a2b1f389223ed6eb446b421234c4111f4c25f2f2e6ea8ca96623a2b18ba750afbd624
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, filter)
66
+ def initialize(klass, path, query_params)
63
67
  @klass = klass
64
68
  @path = path
65
- @filter = filter
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
- def query_params
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
@@ -1,3 +1,3 @@
1
1
  module TableauServerClient
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency 'faraday', '>= 0.14.0'
30
30
  spec.add_dependency 'nokogiri', '>= 1.8.2'
31
31
  spec.add_dependency 'pry', '>= 0.11.3'
32
+ spec.add_dependency 'rubyzip', '>= 1.2.1'
32
33
  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.7
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-07-27 00:00:00.000000000 Z
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