bq_factory 0.1.0 → 0.1.1

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
  SHA1:
3
- metadata.gz: 3bc8211483c62a953a3cc99c9ee1dd9073bfcdae
4
- data.tar.gz: b7b7db7ed189385e5911144cdf5d96da4308ba95
3
+ metadata.gz: f3bf7adb9cfd5447f4c311f4c1806ae26a85f366
4
+ data.tar.gz: e22118db5564b37085690d2bef1b03b8d1f637e6
5
5
  SHA512:
6
- metadata.gz: ed059d60e5a56227512a74c6443b34b4091125be7c127e9757e766a4a5af228c84065965b83236fed43f6f5c63f602aeadc489be58b4c208400c72744f184298
7
- data.tar.gz: f982725b904d52ca2b6b24a48e47fee668270273b9c825a35b978742a0c9688dcd639d2433464121158dc92839be5abfa9a6284935acf8daab64a05a970a4ebf
6
+ metadata.gz: 5e85ed2c024c379775b0aa94d54c31533e55a794b915a0850c2172580f84d7868e5fa1b064fe265df8bda284d994fef3e1b284da4e341990a11cc8188edd2481
7
+ data.tar.gz: 24ca55a19b184418d94ba8d1b8f87c463a250e03188a717638251e3ff48ddcd58c40bc4c241c4fb024146141a9bdfd8425ffeb57a9f83390f19ad2413d1fc9b5
data/.gitignore CHANGED
@@ -10,5 +10,6 @@
10
10
  /Gemfile.local
11
11
  /Gemfile.local.lock
12
12
  /Guardfile
13
- /keys
13
+ /spec/keys/bq-factory.json
14
14
  /.env
15
+ /spec/vcr
data/.travis.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1
4
- - 2.2
5
- - 2.3.0
6
- - ruby-head
7
- before_install: gem install bundler -v "~> 1.10"
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3.0
6
+ - ruby-head
7
+ before_install:
8
+ - gem install bundler -v "~> 1.10"
8
9
  bundler_args: "--jobs=2"
9
10
  cache: bundler
10
11
  script:
data/README.md CHANGED
@@ -28,7 +28,7 @@ Or install it yourself as:
28
28
 
29
29
  Add configuration to initializer or spec_helper.
30
30
 
31
- ```
31
+ ```ruby
32
32
  # RSpec
33
33
  # spec/spec_helper.rb
34
34
 
@@ -38,19 +38,50 @@ BqFactory.configure do |config|
38
38
  end
39
39
  ```
40
40
 
41
- and, setup factories in fixture file.
41
+ ### specify schema
42
+
43
+ This pattern is fetch schema from hash(not call api access).
42
44
 
45
+ First, setup factories in fixture file:
46
+
47
+ ```ruby
48
+ BqFactory.register :user, schema: [{ name: 'name', type: 'INTEGER' }, { name: 'age', type: 'INTEGER' }]
43
49
  ```
44
- BqFactory.define do
45
- # Reference target of dataset and tables in options.
46
- # Factory read schema from reference target!
47
- factory :user, dataset: 'my_dataset', table: 'my_table'
50
+
51
+ And, In your test code:
52
+
53
+ ```
54
+ describe 'test query' do
55
+ before(:all) do
56
+ BqFactory.create_dataset!(:test_dataset)
57
+ end
58
+
59
+ describe 'query is valid' do
60
+ before { BqFactory.create_view(:test_dataset, :test_view, users) }
61
+ subject { BqFactory.query(query) }
62
+
63
+ let(:users) { [{ name: 'alice', age: 20 }] }
64
+ let(:query) { 'SELECT * FROM [test_dataset.test_view]' }
65
+
66
+ it { expect(subject.first).to eq users.first }
67
+ end
48
68
  end
49
69
  ```
50
70
 
51
- ### Use Case
71
+ ### fetch schema from bigquery
72
+
73
+ This pattern is fetch schema from bigquery(call api access).
52
74
 
53
- Example, if `user` table schema is this:
75
+ First, setup factories in fixture file:
76
+
77
+ ```ruby
78
+ # Reference target of dataset and tables in options.
79
+ # Factory fetch schema from bigquery
80
+ BqFactory.register :user, dataset: 'my_dataset' # => reference my_dataset.user table
81
+ BqFactory.register :user, dataset: 'my_dataset', table: 'my_table' # => reference my_dataset.my_table
82
+ ```
83
+
84
+ If register `:user, dataset: 'test_dataset'` and `user` table schema is this:
54
85
 
55
86
  |column_name|type|
56
87
  |:----|:----|
@@ -60,12 +91,12 @@ Example, if `user` table schema is this:
60
91
  |height|FLOAT|
61
92
  |admin|BOOLEAN|
62
93
 
63
- In your test code:
94
+ And, In your test code:
64
95
 
65
96
  ```ruby
66
97
  # RSpec
67
98
 
68
- describe TestClass do
99
+ describe 'query test' do
69
100
  before(:all) do
70
101
  BqFactory.create_dataset!('test_dataset') # => create test dataset
71
102
  end
@@ -73,32 +104,32 @@ describe TestClass do
73
104
  let(:bob) { { name: 'bob', age: 30, create_at: "2016-01-01 00:00:00", height: 170.1, admin: false } }
74
105
 
75
106
  describe 'build query' do
76
- subject { BqFactory.build_query 'user', alice }
107
+ subject { BqFactory.build_query :user, alice }
77
108
  let(:query) { 'SELECT * FROM (SELECT "alice" AS name, 20 AS age, TIMESTAMP("2016-01-01 00:00:00") AS create_at, 150.1 AS height, true AS admin )' }
78
109
  it { is_expected.to eq query }
79
110
  end
80
111
 
81
112
  describe 'from Hash' do
82
- before { BqFactory.create_view 'test_dataset', 'test_view', alice }
113
+ before { BqFactory.create_view :test_dataset, :test_view1, alice }
83
114
  # => Build query 'SELECT * FROM (SELECT "alice" AS name, 20 AS age, TIMESTAMP("2016-01-01 00:00:00") AS create_at, 150.1 AS height, true AS admin )'
84
115
  # And create view "test_view" to "test_dataset"
85
116
 
86
117
  let(:query) { "SELECT * FROM [test_dataset.test_view]" }
87
118
  subject { BqFactory.query(query) }
88
119
 
89
- it { expect(subject.first.name).to eq alise["name"] }
120
+ it { expect(subject.first).to eq alice
90
121
  end
91
122
 
92
123
  describe 'from Array' do
93
- before { BqFactory.create_view 'test_dataset', 'test_view', [alice, bob] }
124
+ before { BqFactory.create_view :test_dataset, :test_view2, [alice, bob] }
94
125
  # => Build query 'SELECT * FROM (SELECT "alice" AS name, 20 AS age, TIMESTAMP("2016-01-01 00:00:00") AS create_at, 150.1 AS height, true AS admin ), (SELECT "bob" AS name, 30 AS age, TIMESTAMP("2016-01-01 00:00:00") AS create_at, 170.1 AS height, false AS admafterin)'
95
126
  # And create view "test_view" to "test_dataset"
96
127
 
97
128
  let(:query) { "SELECT * FROM [test_dataset.test_view]" }
98
129
  subject { BqFactory.query(query) }
99
130
 
100
- it { expect(subject.first.name).to eq alise["name"] }
101
- it { expect(subject.last.name).to eq bob["name"] }
131
+ it { expect(subject.first).to eq alise }
132
+ it { expect(subject.last).to eq bob }
102
133
  end
103
134
 
104
135
  after(:all) do
@@ -112,13 +143,13 @@ end
112
143
  ### Install dependencies
113
144
 
114
145
  ```shell
115
- bundle install
146
+ $ bundle install
116
147
  ```
117
148
 
118
149
  ### Run rspec
119
150
 
120
- ```
121
- bundle exec rspec
151
+ ```shell
152
+ $ bundle exec rspec
122
153
  ```
123
154
 
124
155
  ## Contributing
data/bq_factory.gemspec CHANGED
@@ -20,12 +20,10 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_dependency "gcloud", "~> 0.6.1"
23
- spec.add_dependency "hashie", "~> 3.4"
24
23
  spec.add_development_dependency "bundler", "~> 1.10"
25
24
  spec.add_development_dependency "rake", "~> 10.0"
26
25
  spec.add_development_dependency "rspec"
27
26
  spec.add_development_dependency "shoulda-matchers"
28
27
  spec.add_development_dependency "rubocop"
29
28
  spec.add_development_dependency "simplecov", "~> 0.8.0"
30
- spec.add_development_dependency "dotenv"
31
29
  end
@@ -1,13 +1,5 @@
1
1
  module BqFactory
2
2
  class Configuration
3
3
  attr_accessor :project_id, :keyfile_path
4
-
5
- def schemas
6
- @schemas ||= RegistoryDecorator.new(Registory.new('schema'))
7
- end
8
-
9
- def client
10
- @client ||= BqFactory::Client.new(project_id, keyfile_path)
11
- end
12
4
  end
13
5
  end
@@ -1,3 +1,3 @@
1
1
  module BqFactory
2
- class DuplicateDefinitionError < StandardError; end
2
+ class DuplicateDefinitionError < RuntimeError; end
3
3
  end
@@ -0,0 +1,23 @@
1
+ module BqFactory
2
+ class Proxy
3
+ delegate :fetch_schema, :create_dataset!, :delete_dataset!, :create_table!, :delete_table!, :query, to: :client
4
+ alias :fetch_schema_from_bigquery :fetch_schema
5
+
6
+ delegate :register, :find, to: :schemas
7
+ alias :table_by_name :find
8
+
9
+ delegate :project_id, :keyfile_path, to: :configuration
10
+
11
+ def configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def schemas
16
+ @schemas ||= RegistoryDecorator.new(Registory.new('schema'))
17
+ end
18
+
19
+ def client
20
+ @client ||= Client.new(project_id, keyfile_path)
21
+ end
22
+ end
23
+ end
@@ -1,12 +1,20 @@
1
1
  module BqFactory
2
2
  class QueryBuilder < Array
3
- attr_reader :records
3
+ attr_reader :schema
4
4
 
5
- def initialize(records)
6
- @records = records
5
+ def initialize(schema)
6
+ @schema = schema
7
7
  end
8
8
 
9
- def build
9
+ def build(rows)
10
+ rows = [rows] unless rows.is_a? Array
11
+ records = rows.flatten.map { |row| Record.new(schema, row) }
12
+ build_query(records)
13
+ end
14
+
15
+ private
16
+
17
+ def build_query(records)
10
18
  %{SELECT * FROM #{records.map { |record| build_subquery(record) }.join(', ')}}
11
19
  end
12
20
 
@@ -1,4 +1,4 @@
1
- require 'hashie'
1
+ require 'ostruct'
2
2
 
3
3
  module BqFactory
4
4
  class Record
@@ -10,7 +10,7 @@ module BqFactory
10
10
  raise ArgumentError.new, "Schema is not Array" unless schema.is_a? Array
11
11
 
12
12
  schema.each do |hash|
13
- column = Hashie::Mash.new(hash)
13
+ column = OpenStruct.new(hash)
14
14
  items[column.name] = Attribute.new(column.name, column.type)
15
15
  end
16
16
 
@@ -0,0 +1,12 @@
1
+ module BqFactory
2
+ class Table
3
+ attr_reader :name, :dataset
4
+ attr_accessor :schema
5
+
6
+ def initialize(name, dataset, schema = nil)
7
+ @name = name
8
+ @dataset = dataset
9
+ @schema = schema
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module BqFactory
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/bq_factory.rb CHANGED
@@ -5,72 +5,52 @@ require "bq_factory/attribute"
5
5
  require "bq_factory/record"
6
6
  require "bq_factory/client"
7
7
  require "bq_factory/configuration"
8
- require "bq_factory/dsl"
9
8
  require "bq_factory/errors"
9
+ require "bq_factory/proxy"
10
10
  require "bq_factory/query_builder"
11
+ require "bq_factory/table"
11
12
  require "bq_factory/record"
12
13
  require "bq_factory/registory"
13
14
  require "bq_factory/registory_decorator"
14
15
 
15
16
  module BqFactory
16
17
  class << self
17
- delegate :client, :project_id, :keyfile_path, :schemas, to: :configuration
18
+ delegate :fetch_schema_from_bigquery, :create_dataset!, :delete_dataset!, :create_table!, :delete_table!, :query,
19
+ :table_by_name, :configuration, :project_id, :keyfile_path, :client, to: :proxy
18
20
 
19
21
  def configure
20
22
  yield configuration if block_given?
21
23
  configuration
22
24
  end
23
25
 
24
- def configuration
25
- @configuration ||= Configuration.new
26
- end
27
-
28
- def define(&block)
29
- DSL.run(block)
30
- end
31
-
32
26
  def create_view(dataset_name, factory_name, rows)
33
27
  query = build_query(factory_name, rows)
34
28
  client.create_view(dataset_name, factory_name, query)
35
29
  end
36
30
 
37
- def build_query(factory_name, rows)
38
- rows = [rows] unless rows.instance_of? Array
39
- schema = schema_by_name(factory_name)
40
- records = rows.flatten.map { |row| Record.new(schema, row) }
41
- QueryBuilder.new(records).build
42
- end
43
-
44
- def schema_by_name(factory_name)
45
- schemas.find(factory_name)
46
- end
47
-
48
- def create_dataset!(dataset_name)
49
- client.create_dataset!(dataset_name)
50
- end
31
+ def build_query(register_name, rows)
32
+ table = table_by_name(register_name)
33
+ schema = table.schema
51
34
 
52
- def create_table!(dataset_name, table_name, schema)
53
- client.create_table!(dataset_name, table_name, schema)
54
- end
35
+ if schema.nil?
36
+ schema = proxy.fetch_schema_from_bigquery(table.dataset, table.name)
37
+ table.schema = schema
38
+ end
55
39
 
56
- def delete_dataset!(dataset_name)
57
- client.delete_dataset!(dataset_name)
40
+ QueryBuilder.new(schema).build(rows)
58
41
  end
59
42
 
60
- def delete_table!(dataset_name, table_name)
61
- client.delete_table!(dataset_name, table_name)
62
- end
43
+ def register(name, dataset:, table: nil, schema: nil)
44
+ name = name.to_sym
45
+ table_name = table.nil? ? name : table
63
46
 
64
- def fetch_schema_from_bigquery(dataset_name, table_name)
65
- client.fetch_schema(dataset_name, table_name)
47
+ proxy.register(name, Table.new(table_name, dataset, schema))
66
48
  end
67
49
 
68
- def query(query)
69
- client.query(query)
70
- end
50
+ private
71
51
 
72
- def register(factory_name, schema)
73
- schemas.register(factory_name, schema)
52
+ def proxy
53
+ @proxy ||= Proxy.new
74
54
  end
75
55
  end
76
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bq_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - yuemori
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gcloud
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.6.1
27
- - !ruby/object:Gem::Dependency
28
- name: hashie
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '3.4'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '3.4'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: bundler
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +108,6 @@ dependencies:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
110
  version: 0.8.0
125
- - !ruby/object:Gem::Dependency
126
- name: dotenv
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
111
  description: Create BigQuery view from hash
140
112
  email:
141
113
  - yuemori@aiming-inc.com
@@ -160,12 +132,13 @@ files:
160
132
  - lib/bq_factory/attribute.rb
161
133
  - lib/bq_factory/client.rb
162
134
  - lib/bq_factory/configuration.rb
163
- - lib/bq_factory/dsl.rb
164
135
  - lib/bq_factory/errors.rb
136
+ - lib/bq_factory/proxy.rb
165
137
  - lib/bq_factory/query_builder.rb
166
138
  - lib/bq_factory/record.rb
167
139
  - lib/bq_factory/registory.rb
168
140
  - lib/bq_factory/registory_decorator.rb
141
+ - lib/bq_factory/table.rb
169
142
  - lib/bq_factory/version.rb
170
143
  homepage: http://github.com/yuemori/bq_factory
171
144
  licenses:
@@ -1,15 +0,0 @@
1
- module BqFactory
2
- class DSL
3
- def self.run(block)
4
- new.instance_eval(&block)
5
- end
6
-
7
- def factory(name, options = {})
8
- name = name.to_sym
9
- dataset_name = options.key?(:dataset) ? options[:dataset] : BqFactory.default_dataset
10
- table_name = options.key?(:table) ? options[:table] : name
11
- schema = BqFactory.fetch_schema_from_bigquery(dataset_name, table_name)
12
- BqFactory.register(name, schema)
13
- end
14
- end
15
- end