yancya-big_query 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6d5bd68e33c49a23f96f348b24d41aa9e2140af2
4
+ data.tar.gz: a4ae4adae7acf4754728e94ca31a9726239aa1ad
5
+ SHA512:
6
+ metadata.gz: dcae7d1b73287106727ac1ebbf5a4e0f344ad6f981c78686f4ae47de33cda2b93fbf36a0e108a6052b56ad763f1e1eed93bf9af891589aafa94cf8f37a653025
7
+ data.tar.gz: aa6af3940f7b669a3b00a727cc75638f550f1fa4690bbfffb83fee0d145fb7c95142963d74865dfe84f4f5dda11c229ebcf4ea238f6b3fe593593422ad203ba4
data/.gitignore ADDED
@@ -0,0 +1,37 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
35
+
36
+ # IDEA config file
37
+ .idea
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.0.2
2
+
3
+ * Can use streaming insert
4
+ * Add simple tests
5
+
6
+ # 0.0.1
7
+
8
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in big_query.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ big_query (0.0.2)
5
+ google-api-client
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (4.2.1)
11
+ i18n (~> 0.7)
12
+ json (~> 1.7, >= 1.7.7)
13
+ minitest (~> 5.1)
14
+ thread_safe (~> 0.3, >= 0.3.4)
15
+ tzinfo (~> 1.1)
16
+ addressable (2.3.8)
17
+ autoparse (0.3.3)
18
+ addressable (>= 2.3.1)
19
+ extlib (>= 0.9.15)
20
+ multi_json (>= 1.0.0)
21
+ extlib (0.9.16)
22
+ faraday (0.9.1)
23
+ multipart-post (>= 1.2, < 3)
24
+ google-api-client (0.8.6)
25
+ activesupport (>= 3.2)
26
+ addressable (~> 2.3)
27
+ autoparse (~> 0.3)
28
+ extlib (~> 0.9)
29
+ faraday (~> 0.9)
30
+ googleauth (~> 0.3)
31
+ launchy (~> 2.4)
32
+ multi_json (~> 1.10)
33
+ retriable (~> 1.4)
34
+ signet (~> 0.6)
35
+ googleauth (0.4.1)
36
+ faraday (~> 0.9)
37
+ jwt (~> 1.4)
38
+ logging (~> 2.0)
39
+ memoist (~> 0.12)
40
+ multi_json (= 1.11)
41
+ signet (~> 0.6)
42
+ i18n (0.7.0)
43
+ json (1.8.3)
44
+ jwt (1.5.0)
45
+ launchy (2.4.3)
46
+ addressable (~> 2.3)
47
+ little-plugger (1.1.3)
48
+ logging (2.0.0)
49
+ little-plugger (~> 1.1)
50
+ multi_json (~> 1.10)
51
+ memoist (0.12.0)
52
+ minitest (5.7.0)
53
+ multi_json (1.11.0)
54
+ multipart-post (2.0.0)
55
+ power_assert (0.2.3)
56
+ rake (10.4.2)
57
+ retriable (1.4.1)
58
+ signet (0.6.1)
59
+ addressable (~> 2.3)
60
+ extlib (~> 0.9)
61
+ faraday (~> 0.9)
62
+ jwt (~> 1.5)
63
+ multi_json (~> 1.10)
64
+ test-unit (3.1.1)
65
+ power_assert
66
+ thread_safe (0.3.5)
67
+ tzinfo (1.2.2)
68
+ thread_safe (~> 0.1)
69
+
70
+ PLATFORMS
71
+ ruby
72
+
73
+ DEPENDENCIES
74
+ big_query!
75
+ bundler (~> 1.6)
76
+ rake
77
+ test-unit
78
+
79
+ BUNDLED WITH
80
+ 1.10.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Shinta Koyanagi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # BigQuery
2
+
3
+ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/yancya/big_query?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+
5
+ Google BigQuery API client library
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'big_query', github: "yancya/big_query"
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or build and install it yourself as:
18
+
19
+ $ git clone git@github.com:yancya/big_query.git
20
+ $ cd big_query
21
+ $ rake install
22
+
23
+ ## Usage
24
+
25
+ ```rb
26
+ bq = BigQuery.new(
27
+ key_path: "path_to_secret_key"
28
+ issuer: "mail@address"
29
+ )
30
+
31
+ job = bq.jobs.query(
32
+ project_id: "name_of_project",
33
+ sql: "select 1 as a, 2 as b, 3 as c"
34
+ )
35
+
36
+ begin
37
+ result = job.query_results
38
+ end until result["jobComplete"]
39
+
40
+ result["schema"]["fields"].map{|f| f["name"]}.join(",") #=> "a,b,c"
41
+ result["rows"].map{|row| row["f"].map{|col| col["v"]}.join(",")} #=> ["1,2,3"]
42
+ ```
43
+
44
+ ## Google BigQuery API Reference
45
+
46
+ https://developers.google.com/bigquery/docs/reference/v2/
47
+
48
+ ## Contributing
49
+
50
+ 1. Fork it ( https://github.com/yancya/big_query/fork )
51
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
52
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
53
+ 4. Push to the branch (`git push origin my-new-feature`)
54
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => :test
4
+
5
+ require "rake/testtask"
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "test"
9
+ t.test_files = Dir["test/**/test_*.rb"]
10
+ end
data/big_query.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'yancya/big_query/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "yancya-big_query"
8
+ spec.version = Yancya::BigQuery::VERSION
9
+ spec.authors = ["yancya"]
10
+ spec.email = ["yancya@upec.jp"]
11
+ spec.summary = %q{Google BigQuery API client library.}
12
+ spec.description = %q{Google BigQuery API client library. This is simple wrapper.}
13
+ spec.homepage = "https://github.com/yancya/big_query"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "google-api-client", "~> 0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake", "~> 0"
25
+ spec.add_development_dependency "test-unit", "~> 0"
26
+ end
data/bin/big_query ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'big_query'
@@ -0,0 +1,31 @@
1
+ require_relative 'tables'
2
+
3
+ module Yancya
4
+ class BigQuery::Dataset
5
+ def initialize(resource:, bq:)
6
+ @resource = resource
7
+ @tables = BigQuery::Tables.new(bq: bq)
8
+ end
9
+
10
+ def tables
11
+ @tables.list(
12
+ project_id: project_id,
13
+ dataset_id: dataset_id
14
+ )
15
+ end
16
+
17
+ def project_id
18
+ dataset_reference["projectId"]
19
+ end
20
+
21
+ def dataset_id
22
+ dataset_reference["datasetId"]
23
+ end
24
+
25
+ private
26
+
27
+ def dataset_reference
28
+ @resource["datasetReference"]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,63 @@
1
+ require_relative 'initializer'
2
+ require_relative 'request_executor'
3
+
4
+ require_relative 'dataset'
5
+
6
+ module Yancya
7
+ class BigQuery::Datasets
8
+ include Initializer
9
+ include RequestExecutor
10
+
11
+ def delete(project_id:, dataset_id:)
12
+ execute(
13
+ api_method: @bq.api.datasets.delete,
14
+ parameters: {projectId: project_id, datasetId: dataset_id, deleteContents: true}
15
+ )
16
+ end
17
+
18
+ def get(project_id:, dataset_id:)
19
+ execute(
20
+ api_method: @bq.api.datasets.get,
21
+ parameters: {projectId: project_id, datasetId: dataset_id}
22
+ )
23
+ end
24
+
25
+ def insert(project_id:, dataset:)
26
+ execute(
27
+ api_method: @bq.api.datasets.insert,
28
+ parameters: {projectId: project_id},
29
+ body_object: dataset
30
+ )
31
+ end
32
+
33
+ def list(project_id:)
34
+ resources = execute(
35
+ api_method: @bq.api.datasets.list,
36
+ parameters: {projectId: project_id}
37
+ )
38
+
39
+ resources["datasets"].map{ |resource|
40
+ Yancya::BigQuery::Dataset.new(
41
+ resource: resource,
42
+ bq: @bq
43
+ )
44
+ }
45
+ end
46
+
47
+ def patch(project_id:, dataset_id:, dataset:)
48
+ execute(
49
+ api_method: @bq.api.datasets.patch,
50
+ parameters: {projectId: project_id, datasetId: dataset_id},
51
+ body_object: dataset
52
+ )
53
+ end
54
+
55
+ def update(project_id:, dataset_id:, dataset:)
56
+ execute(
57
+ api_method: @bq.api.datasets.update,
58
+ parameters: {projectId: project_id, datasetId: dataset_id},
59
+ body_object: dataset
60
+ )
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ module Yancya
2
+ module Initializer
3
+ def self.included(_)
4
+ define_method(:initialize) do |bq:|
5
+ @bq = bq
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,53 @@
1
+ module Yancya
2
+ class BigQuery::Job
3
+ def initialize(resource:, bq:)
4
+ @resource = resource
5
+ @jobs = BigQuery::Jobs.new(bq: bq)
6
+ end
7
+
8
+ def query_results
9
+ @jobs.get_query_results(
10
+ project_id: project_id,
11
+ job_id: job_id
12
+ )
13
+ end
14
+
15
+ def reload
16
+ @jobs.get(project_id: project_id, job_id: job_id)
17
+ end
18
+
19
+ def project_id
20
+ job_reference["projectId"]
21
+ end
22
+
23
+ def job_id
24
+ job_reference["jobId"]
25
+ end
26
+
27
+ def query
28
+ (configuration["query"]||{})["query"]
29
+ end
30
+
31
+ def state
32
+ status["state"]
33
+ end
34
+
35
+ def errors
36
+ status["errors"]
37
+ end
38
+
39
+ private
40
+
41
+ def configuration
42
+ @resource["configuration"]
43
+ end
44
+
45
+ def status
46
+ @resource["status"]
47
+ end
48
+
49
+ def job_reference
50
+ @resource["jobReference"]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,61 @@
1
+ require 'json'
2
+
3
+ require_relative 'initializer'
4
+ require_relative 'request_executor'
5
+ require_relative 'job'
6
+
7
+ module Yancya
8
+ class BigQuery::Jobs
9
+ include Initializer
10
+ include RequestExecutor
11
+
12
+ def cancel(project_id:, job_id:)
13
+ execute(
14
+ api_method: @bq.api.jobs.cancel,
15
+ parameters: { projectId: project_id, jobId: job_id }
16
+ )
17
+ end
18
+
19
+ def get(project_id:, job_id:)
20
+ resource = execute(
21
+ api_method: @bq.api.jobs.get,
22
+ parameters: { projectId: project_id, jobId: job_id }
23
+ )
24
+
25
+ BigQuery::Job.new(resource: resource, bq: @bq)
26
+ end
27
+
28
+ def get_query_results(project_id:, job_id:)
29
+ execute(
30
+ api_method: @bq.api.jobs.get_query_results,
31
+ parameters: { projectId: project_id, jobId: job_id }
32
+ )
33
+ end
34
+
35
+ def insert(project_id:)
36
+ # TODO: https://developers.google.com/bigquery/docs/reference/v2/jobs/insert
37
+ raise "This method is not yet working"
38
+ end
39
+
40
+ def list(project_id:)
41
+ resources = execute(
42
+ api_method: @bq.api.jobs.list,
43
+ parameters: { projectId: project_id, projection: "full" }
44
+ )
45
+
46
+ resources["jobs"].map{|job|
47
+ BigQuery::Job.new(resource: job, bq: @bq)
48
+ }
49
+ end
50
+
51
+ def query(project_id:, sql:)
52
+ resource = execute(
53
+ api_method: @bq.api.jobs.query,
54
+ body_object: { query: sql },
55
+ parameters: { projectId: project_id }
56
+ )
57
+
58
+ BigQuery::Job.new(resource: resource, bq: @bq)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'jobs'
2
+ require_relative 'datasets'
3
+ require_relative 'request_executor'
4
+
5
+ module Yancya
6
+ class BigQuery::Project
7
+ include RequestExecutor
8
+
9
+ def initialize(resource:, bq:)
10
+ @resource = resource
11
+ @jobs = BigQuery::Jobs.new(bq: bq)
12
+ @datasets = BigQuery::Datasets.new(bq: bq)
13
+ @bq = bq
14
+ end
15
+
16
+ def query(sql)
17
+ @jobs.query(project_id: project_id, sql: sql)
18
+ end
19
+
20
+ def jobs
21
+ @jobs.list(project_id: project_id)
22
+ end
23
+
24
+ def datasets
25
+ @datasets.list(project_id: project_id)
26
+ end
27
+
28
+ def project_id
29
+ @resource["projectReference"]["projectId"]
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,21 @@
1
+ require_relative 'request_executor'
2
+ require_relative 'initializer'
3
+
4
+ require_relative 'project'
5
+
6
+ module Yancya
7
+ class BigQuery::Projects
8
+ include Initializer
9
+ include RequestExecutor
10
+
11
+ def list
12
+ resources = execute(
13
+ api_method: @bq.api.projects.list
14
+ )
15
+
16
+ resources["projects"].map do |resource|
17
+ BigQuery::Project.new(resource: resource, bq: @bq)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Yancya
2
+ module RequestExecutor
3
+ private
4
+
5
+ def response_to_json(obj)
6
+ return {} if obj.response.body.empty?
7
+ JSON.parse(obj.response.body).tap do |resource|
8
+ raise resource["error"].to_s if resource["error"]
9
+ break resource
10
+ end
11
+ end
12
+
13
+ def execute(api_method:, body_object: nil, parameters: nil)
14
+ response_to_json(
15
+ @bq.client.execute(
16
+ api_method: api_method,
17
+ body_object: body_object,
18
+ parameters: parameters
19
+ )
20
+ )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,68 @@
1
+ module Yancya
2
+ class BigQuery::Table
3
+ def initialize(resource:, tables:)
4
+ @resource = resource
5
+ @tables = tables
6
+ end
7
+
8
+ def project_id
9
+ table_reference["projectId"]
10
+ end
11
+
12
+ def dataset_id
13
+ table_reference["datasetId"]
14
+ end
15
+
16
+ def table_id
17
+ table_reference["tableId"]
18
+ end
19
+
20
+ def description
21
+ @resource["description"]
22
+ end
23
+
24
+ def schema
25
+ @resource["schema"]
26
+ end
27
+
28
+ def reload
29
+ @tables.get(
30
+ project_id: project_id,
31
+ dataset_id: dataset_id,
32
+ table_id: table_id
33
+ )
34
+ end
35
+
36
+ def delete
37
+ @tables.delete(
38
+ project_id: project_id,
39
+ dataset_id: dataset_id,
40
+ table_id: table_id
41
+ )
42
+ end
43
+
44
+ def patch(table_reference:)
45
+ @tables.patch(
46
+ project_id: project_id,
47
+ dataset_id: dataset_id,
48
+ table_id: table_id,
49
+ table: table_reference
50
+ )
51
+ end
52
+
53
+ def update(table_reference:)
54
+ @tables.update(
55
+ project_id: project_id,
56
+ dataset_id: dataset_id,
57
+ table_id: table_id,
58
+ table: table_reference
59
+ )
60
+ end
61
+
62
+ private
63
+ def table_reference
64
+ @resource["tableReference"]
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,37 @@
1
+ require_relative 'request_executor'
2
+
3
+ module Yancya
4
+ class BigQuery::Tabledata
5
+ include RequestExecutor
6
+
7
+ def initialize(project_id:, dataset_id:, table_id:, bq:)
8
+ @project_id = project_id
9
+ @dataset_id = dataset_id
10
+ @table_id = table_id
11
+ @bq = bq
12
+ end
13
+
14
+ def insert_all(rows)
15
+ execute(
16
+ api_method: @bq.api.tabledata.insert_all,
17
+ body_object: {rows: rows},
18
+ parameters: {
19
+ datasetId: @dataset_id,
20
+ projectId: @project_id,
21
+ tableId: @table_id
22
+ }
23
+ )
24
+ end
25
+
26
+ def list
27
+ execute(
28
+ api_method: @bq.api.tabledata.list,
29
+ parameters: {
30
+ datasetId: @dataset_id,
31
+ projectId: @project_id,
32
+ tableId: @table_id
33
+ }
34
+ )
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,90 @@
1
+ require_relative 'initializer'
2
+ require_relative 'request_executor'
3
+
4
+ require_relative 'table'
5
+
6
+ module Yancya
7
+ class BigQuery::Tables
8
+ include Initializer
9
+ include RequestExecutor
10
+
11
+ def delete(project_id:, dataset_id:, table_id:)
12
+ execute(
13
+ api_method: @bq.api.tables.delete,
14
+ parameters: {
15
+ datasetId: dataset_id,
16
+ projectId: project_id,
17
+ tableId: table_id,
18
+ }
19
+ )
20
+ end
21
+
22
+ def get(project_id:, dataset_id:, table_id:)
23
+ resource = execute(
24
+ api_method: @bq.api.tables.get,
25
+ parameters: {
26
+ datasetId: dataset_id,
27
+ projectId: project_id,
28
+ tableId: table_id,
29
+ }
30
+ )
31
+
32
+ BigQuery::Table.new(resource: resource, tables: self)
33
+ end
34
+
35
+ def insert(project_id:, dataset_id:, table:)
36
+ resource = execute(
37
+ api_method: @bq.api.tables.insert,
38
+ parameters: {
39
+ datasetId: dataset_id,
40
+ projectId: project_id,
41
+ },
42
+ body_object: table
43
+ )
44
+
45
+ BigQuery::Table.new(resource: resource, tables: self)
46
+ end
47
+
48
+ def list(project_id:, dataset_id:)
49
+ resources = execute(
50
+ api_method: @bq.api.tables.list,
51
+ parameters: {
52
+ datasetId: dataset_id,
53
+ projectId: project_id,
54
+ }
55
+ )
56
+
57
+ (resources["tables"]||[]).map do |resource|
58
+ BigQuery::Table.new(resource: resource, tables: self)
59
+ end
60
+ end
61
+
62
+ def patch(project_id:, dataset_id:, table_id:, table:)
63
+ resource = execute(
64
+ api_method: @bq.api.tables.patch,
65
+ parameters: {
66
+ datasetId: dataset_id,
67
+ projectId: project_id,
68
+ tableId: table_id,
69
+ },
70
+ body_object: table
71
+ )
72
+
73
+ BigQuery::Table.new(resource: resource, tables: self)
74
+ end
75
+
76
+ def update(project_id:, dataset_id:, table_id:, table:)
77
+ resource = execute(
78
+ api_method: @bq.api.tables.update,
79
+ parameters: {
80
+ datasetId: dataset_id,
81
+ projectId: project_id,
82
+ tableId: table_id,
83
+ },
84
+ body_object: table
85
+ )
86
+
87
+ BigQuery::Table.new(resource: resource, tables: self)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,5 @@
1
+ module Yancya
2
+ class BigQuery
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ require_relative "big_query/version"
2
+ require_relative "big_query/datasets"
3
+ require_relative "big_query/jobs"
4
+ require_relative "big_query/projects"
5
+ require_relative "big_query/tabledata"
6
+ require_relative "big_query/tables"
7
+
8
+ require 'google/api_client'
9
+
10
+ module Yancya
11
+ class BigQuery
12
+ attr_reader :client
13
+
14
+ BQ = Struct.new(:client) do
15
+ def api
16
+ client.discovered_api("bigquery", "v2")
17
+ end
18
+ end
19
+
20
+ def initialize(key_path:,
21
+ issuer:,
22
+ application_name: "github.com/yancya/big_query",
23
+ application_version: BigQuery::VERSION)
24
+
25
+ app_info = {
26
+ application_name: application_name,
27
+ application_version: application_version
28
+ }
29
+
30
+ client = Google::APIClient.new(app_info)
31
+
32
+ asserter = Google::APIClient::JWTAsserter.new(
33
+ issuer,
34
+ "https://www.googleapis.com/auth/bigquery",
35
+ Google::APIClient::PKCS12.load_key(File.open(key_path), "notasecret")
36
+ )
37
+
38
+ client.authorization = asserter.authorize
39
+
40
+ @bq = BQ.new(client)
41
+ end
42
+
43
+ def datasets
44
+ Datasets.new(bq: @bq)
45
+ end
46
+
47
+ def jobs
48
+ Jobs.new(bq: @bq)
49
+ end
50
+
51
+ def projects
52
+ Projects.new(bq: @bq)
53
+ end
54
+
55
+ def tabledata(project_id:, dataset_id:, table_id:)
56
+ Tabledata.new(
57
+ project_id: project_id,
58
+ dataset_id: dataset_id,
59
+ table_id: table_id,
60
+ bq: @bq
61
+ )
62
+ end
63
+
64
+ def tables
65
+ Tables.new(bq: @bq)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,176 @@
1
+ require 'test-unit'
2
+ require 'pp'
3
+ require_relative '../lib/yancya/big_query'
4
+
5
+ class TestBigQuery < Test::Unit::TestCase
6
+ TEST_DATASET_ID = "test_dataset_for_yancya_big_query_gem"
7
+ TEST_DATASET_ID_MODIFIED = "test_dataset_for_yancya_big_query_gem_"
8
+ TEST_TABLE_ID = "test_table"
9
+ TEST_TABLE_INFO = {
10
+ schema: {
11
+ fields: [
12
+ {name: "column_s", type: "STRING"},
13
+ {name: "column_i", type: "INTEGER"},
14
+ {name: "column_f", type: "FLOAT"},
15
+ {name: "column_b", type: "BOOLEAN"}
16
+ ]
17
+ },
18
+ tableReference: {
19
+ tableId: TEST_TABLE_ID
20
+ }
21
+ }
22
+
23
+ setup do
24
+ @bq = Yancya::BigQuery.new(
25
+ key_path: ENV["GCP_KEY_PATH"],
26
+ issuer: ENV["GCP_ISSUER"]
27
+ )
28
+
29
+ @project_id = ENV["BQ_PROJECT_ID"]
30
+
31
+ if @bq.datasets.list(project_id: @project_id).map{ |ds| ds.dataset_id }.include? TEST_DATASET_ID
32
+ @bq.datasets.delete(project_id: @project_id, dataset_id: TEST_DATASET_ID)
33
+ end
34
+
35
+ dataset = {
36
+ datasetReference: {
37
+ datasetId: TEST_DATASET_ID
38
+ }
39
+ }
40
+
41
+ @bq.datasets.insert(project_id: @project_id, dataset: dataset)
42
+ end
43
+
44
+ teardown do
45
+ @bq.datasets.delete(project_id: @project_id, dataset_id: TEST_DATASET_ID)
46
+ end
47
+
48
+ test "get dataset" do
49
+ dataset = @bq.
50
+ datasets.
51
+ get(
52
+ project_id: @project_id,
53
+ dataset_id: TEST_DATASET_ID
54
+ )["datasetReference"]
55
+
56
+ assert { TEST_DATASET_ID == dataset["datasetId"] }
57
+ end
58
+
59
+ test "jobs list" do
60
+ job_list = @bq.jobs.list(project_id: @project_id)
61
+ assert { job_list.is_a? Array }
62
+ end
63
+
64
+ test "get job" do
65
+ job_id = @bq.jobs.list(project_id: @project_id).last.job_id
66
+ assert do
67
+ job_id == @bq.jobs.get(project_id: @project_id, job_id: job_id).job_id
68
+ end
69
+ end
70
+
71
+ test "project list" do
72
+ assert do
73
+ @bq.projects.list.map{ |project| project.project_id }.include? @project_id
74
+ end
75
+ end
76
+
77
+ test "select without table" do
78
+ result = execute_query("select 1 as a, 2 as b, 3 as c")
79
+
80
+ assert do
81
+ "1,2,3" == result["rows"].map{|row| row["f"].map{|col| col["v"]}.join(",")}.first
82
+ end
83
+ end
84
+
85
+ test "create table" do
86
+ result = create_table
87
+
88
+ assert { TEST_TABLE_ID == result.table_id }
89
+ end
90
+
91
+ test "insert_all data" do
92
+ create_table
93
+
94
+ table_data = @bq.tabledata(
95
+ project_id: @project_id,
96
+ dataset_id: TEST_DATASET_ID,
97
+ table_id: TEST_TABLE_ID
98
+ )
99
+
100
+ rows = [{ json: { column_s: "hoge", column_i: 1, column_f: 0.1, column_b: false } }]
101
+
102
+ assert { table_data.insert_all(rows)["insertErrors"].nil? }
103
+ assert { table_data.list["totalRows"] }
104
+ end
105
+
106
+ test "table list" do
107
+ create_table
108
+
109
+ assert { 1 == @bq.tables.list(project_id: @project_id, dataset_id: TEST_DATASET_ID).size }
110
+ end
111
+
112
+ test "get table"do
113
+ create_table
114
+
115
+ table = @bq.tables.get(project_id: @project_id, dataset_id: TEST_DATASET_ID, table_id: TEST_TABLE_ID)
116
+
117
+ assert { TEST_TABLE_ID == table.table_id }
118
+ end
119
+
120
+ test "delete table" do
121
+ table = create_table
122
+ @bq.tables.delete(project_id: @project_id, dataset_id: TEST_DATASET_ID, table_id: table.table_id)
123
+
124
+ assert { @bq.tables.list(project_id: @project_id, dataset_id: TEST_DATASET_ID).empty? }
125
+ end
126
+
127
+ test "patch table" do
128
+ create_table
129
+
130
+ table = @bq.tables.patch(
131
+ project_id: @project_id,
132
+ dataset_id: TEST_DATASET_ID,
133
+ table_id: TEST_TABLE_ID,
134
+ table: {
135
+ description: "hello world"
136
+ }
137
+ )
138
+
139
+ assert { "hello world" == table.description }
140
+ end
141
+
142
+ test "update table" do
143
+ schema = create_table.schema
144
+
145
+ table = @bq.tables.update(
146
+ project_id: @project_id,
147
+ dataset_id: TEST_DATASET_ID,
148
+ table_id: TEST_TABLE_ID,
149
+ table: {
150
+ schema: schema.tap { |hash| hash["fields"] << { name: "hoge", type: "STRING" }; break hash }
151
+ }
152
+ )
153
+
154
+ assert { table.schema["fields"].map { |field| field["name"] }.include? "hoge" }
155
+ end
156
+
157
+ private
158
+
159
+ def create_table
160
+ @bq.tables.insert(
161
+ project_id: @project_id,
162
+ dataset_id: TEST_DATASET_ID,
163
+ table: TEST_TABLE_INFO
164
+ )
165
+ end
166
+
167
+ def execute_query(sql)
168
+ job = @bq.jobs.query(project_id: @project_id, sql: sql)
169
+
170
+ begin
171
+ result = job.query_results
172
+ end until result["jobComplete"]
173
+
174
+ result
175
+ end
176
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yancya-big_query
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - yancya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-api-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Google BigQuery API client library. This is simple wrapper.
70
+ email:
71
+ - yancya@upec.jp
72
+ executables:
73
+ - big_query
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - LICENSE
82
+ - README.md
83
+ - Rakefile
84
+ - big_query.gemspec
85
+ - bin/big_query
86
+ - lib/yancya/big_query.rb
87
+ - lib/yancya/big_query/dataset.rb
88
+ - lib/yancya/big_query/datasets.rb
89
+ - lib/yancya/big_query/initializer.rb
90
+ - lib/yancya/big_query/job.rb
91
+ - lib/yancya/big_query/jobs.rb
92
+ - lib/yancya/big_query/project.rb
93
+ - lib/yancya/big_query/projects.rb
94
+ - lib/yancya/big_query/request_executor.rb
95
+ - lib/yancya/big_query/table.rb
96
+ - lib/yancya/big_query/tabledata.rb
97
+ - lib/yancya/big_query/tables.rb
98
+ - lib/yancya/big_query/version.rb
99
+ - test/test_big_query.rb
100
+ homepage: https://github.com/yancya/big_query
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.4.5
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Google BigQuery API client library.
124
+ test_files:
125
+ - test/test_big_query.rb