ahoy_matey 1.4.1 → 1.4.2

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
  SHA1:
3
- metadata.gz: 3f3a81162866c03a621491abb0194ebe878a7f48
4
- data.tar.gz: 050571dcc31a26851ee56da2b373503507d3547c
3
+ metadata.gz: 1aebb95363cb98c2b74dadb3b42f9cd04c17c421
4
+ data.tar.gz: 08785d2aa638fddb3881d4365e74ded3049cfec8
5
5
  SHA512:
6
- metadata.gz: 7259821c2286af301fcc08ca16fa6b9ef284668740d5d4e7c136adc27c250521458da9a97a859c0ecf724ab2e469a78ff4670459333e08c594af658abb6b4707
7
- data.tar.gz: 918d05e4515f41a79991324a93bb240965bb60d685279fcb53893228a87a6954c1dfd1ae4dbe162e5366d8d270fd5625546d2656795f4d51f0f839af0c6d8c85
6
+ metadata.gz: 16c58280be2b7a51a4f41c837204f701a93897b509330a0ff648d06819e2b944373fcaf5e0b595009270f5b332ec1ef81626537b824deafbd2f89cca5ece4376
7
+ data.tar.gz: 2aeb6f81dd3f0fdf09d0aee20ba52ed9349903636b9b392e87782ae135161520809aa45549dca292a479d5bae95ba893c4e6f95b29e13f6d32c601a39e204aae
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.4.2
2
+
3
+ - Fixed issues with `where_properties`
4
+
1
5
  ## 1.4.1
2
6
 
3
7
  - Added `where_properties` method
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in ahoy.gemspec
4
4
  gemspec
5
+
6
+ gem "rails", "~> 5.0.0.rc1"
data/README.md CHANGED
@@ -27,7 +27,7 @@ Ahoy supports a number of data stores out of the box. You can start with one of
27
27
 
28
28
  - [PostgreSQL, MySQL, or SQLite](#postgresql-mysql-or-sqlite)
29
29
  - [MongoDB](#mongodb)
30
- - [Kafka](#kafka-master) [master]
30
+ - [Kafka](#kafka)
31
31
  - [Fluentd](#fluentd)
32
32
  - [RabbitMQ](#rabbitmq)
33
33
  - [Amazon Kinesis Firehose](#amazon-kinesis-firehose)
@@ -49,7 +49,7 @@ rake db:migrate
49
49
  rails generate ahoy:stores:mongoid
50
50
  ```
51
51
 
52
- ### Kafka [master]
52
+ ### Kafka
53
53
 
54
54
  Add [ruby-kafka](https://github.com/zendesk/ruby-kafka) to your Gemfile.
55
55
 
@@ -489,11 +489,13 @@ The same approach also works with visitor tokens.
489
489
 
490
490
  ### Querying Properties
491
491
 
492
+ With ActiveRecord, use:
493
+
492
494
  ```ruby
493
- Ahoy::Event.where_properties(store_id: 1).count
495
+ Ahoy::Event.where(name: "Viewed product").where_properties(product_id: 123).count
494
496
  ```
495
497
 
496
- **Note:** If you get a `NoMethodError`, upgrade Ahoy and add to your model `include Ahoy::Properties`.
498
+ **Note:** If you get a `NoMethodError`, upgrade Ahoy and add `include Ahoy::Properties` to your model.
497
499
 
498
500
  ## Native Apps
499
501
 
data/ahoy_matey.gemspec CHANGED
@@ -32,4 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "bundler", "~> 1.5"
33
33
  spec.add_development_dependency "rake"
34
34
  spec.add_development_dependency "minitest"
35
+ spec.add_development_dependency "activerecord"
36
+ spec.add_development_dependency "pg"
37
+ spec.add_development_dependency "mysql2"
35
38
  end
data/lib/ahoy.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "active_support"
1
2
  require "active_support/core_ext"
2
3
  require "addressable/uri"
3
4
  require "browser"
@@ -28,7 +29,7 @@ require "ahoy/stores/mongoid_store"
28
29
  require "ahoy/stores/kafka_store"
29
30
  require "ahoy/stores/kinesis_firehose_store"
30
31
  require "ahoy/stores/bunny_store"
31
- require "ahoy/engine"
32
+ require "ahoy/engine" if defined?(Rails)
32
33
  require "ahoy/warden" if defined?(Warden)
33
34
 
34
35
  # background jobs
@@ -106,19 +107,21 @@ module Ahoy
106
107
  self.track_bots = false
107
108
  end
108
109
 
109
- ActionController::Base.send :include, Ahoy::Controller
110
- ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord)
111
-
112
- # ensure logger silence will not be added by activerecord-session_store
113
- # otherwise, we get SystemStackError: stack level too deep
114
- begin
115
- require "active_record/session_store/extension/logger_silencer"
116
- rescue LoadError
117
- require "ahoy/logger_silencer"
118
- Logger.send :include, Ahoy::LoggerSilencer
110
+ if defined?(Rails)
111
+ ActionController::Base.send :include, Ahoy::Controller
112
+ ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord)
119
113
 
114
+ # ensure logger silence will not be added by activerecord-session_store
115
+ # otherwise, we get SystemStackError: stack level too deep
120
116
  begin
121
- require "syslog/logger"
122
- Syslog::Logger.send :include, Ahoy::LoggerSilencer
123
- rescue LoadError; end
117
+ require "active_record/session_store/extension/logger_silencer"
118
+ rescue LoadError
119
+ require "ahoy/logger_silencer"
120
+ Logger.send :include, Ahoy::LoggerSilencer
121
+
122
+ begin
123
+ require "syslog/logger"
124
+ Syslog::Logger.send :include, Ahoy::LoggerSilencer
125
+ rescue LoadError; end
126
+ end
124
127
  end
@@ -6,16 +6,50 @@ module Ahoy
6
6
  def where_properties(properties)
7
7
  relation = self
8
8
  column_type = columns_hash["properties"].type
9
- case column_type
10
- when :jsonb, :json
11
- properties.each do |k, v|
12
- relation = relation.where("properties ->> ? = ?", k, v)
9
+ adapter_name = connection.adapter_name.downcase
10
+ case adapter_name
11
+ when /mysql/
12
+ if column_type == :json
13
+ properties.each do |k, v|
14
+ if v.nil?
15
+ v = "null"
16
+ elsif v == true
17
+ v = "true"
18
+ end
19
+
20
+ relation = relation.where("JSON_UNQUOTE(properties -> ?) = ?", "$.#{k.to_s}", v.as_json)
21
+ end
22
+ else
23
+ properties.each do |k, v|
24
+ relation = relation.where("properties REGEXP ?", "[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}[,}]")
25
+ end
13
26
  end
14
- else
15
- properties.each do |k, v|
16
- # not 100%, but will do
17
- relation = relation.where("properties LIKE ?", "%#{{k => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}%")
27
+ when /postgres/
28
+ if column_type == :jsonb || column_type == :json
29
+ properties.each do |k, v|
30
+ relation =
31
+ if v.nil?
32
+ relation.where("properties ->> ? IS NULL", k.to_s)
33
+ else
34
+ relation.where("properties ->> ? = ?", k.to_s, v.as_json.to_s)
35
+ end
36
+ end
37
+ elsif column_type == :hstore
38
+ properties.each do |k, v|
39
+ relation =
40
+ if v.nil?
41
+ relation.where("properties -> ? IS NULL", k.to_s)
42
+ else
43
+ relation.where("properties -> ? = ?", k.to_s, v.to_s)
44
+ end
45
+ end
46
+ else
47
+ properties.each do |k, v|
48
+ relation = relation.where("properties SIMILAR TO ?", "%[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}[,}]%")
49
+ end
18
50
  end
51
+ else
52
+ raise "Adapter not supported: #{adapter_name}"
19
53
  end
20
54
  relation
21
55
  end
data/lib/ahoy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "1.4.1"
2
+ VERSION = "1.4.2"
3
3
  end
@@ -0,0 +1,18 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :mysql_json_events, force: true do |t|
6
+ t.json :properties
7
+ end
8
+
9
+ class MysqlJsonEvent < MysqlBase
10
+ end
11
+
12
+ class MysqlJsonTest < Minitest::Test
13
+ include PropertiesTest
14
+
15
+ def model
16
+ MysqlJsonEvent
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :mysql_text_events, force: true do |t|
6
+ t.text :properties
7
+ end
8
+
9
+ class MysqlTextEvent < MysqlBase
10
+ serialize :properties, JSON
11
+ end
12
+
13
+ class MysqlTextTest < Minitest::Test
14
+ include PropertiesTest
15
+
16
+ def model
17
+ MysqlTextEvent
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :postgresql_hstore_events, force: true do |t|
6
+ t.hstore :properties
7
+ end
8
+
9
+ class PostgresqlHstoreEvent < PostgresqlBase
10
+ end
11
+
12
+ class PostgresqlHstoreTest < Minitest::Test
13
+ include PropertiesTest
14
+
15
+ def model
16
+ PostgresqlHstoreEvent
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :postgresql_json_events, force: true do |t|
6
+ t.json :properties
7
+ end
8
+
9
+ class PostgresqlJsonEvent < PostgresqlBase
10
+ end
11
+
12
+ class PostgresqlJsonTest < Minitest::Test
13
+ include PropertiesTest
14
+
15
+ def model
16
+ PostgresqlJsonEvent
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :postgresql_jsonb_events, force: true do |t|
6
+ t.jsonb :properties
7
+ end
8
+
9
+ class PostgresqlJsonbEvent < PostgresqlBase
10
+ end
11
+
12
+ class PostgresqlJsonbTest < Minitest::Test
13
+ include PropertiesTest
14
+
15
+ def model
16
+ PostgresqlJsonbEvent
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require_relative "../test_helper"
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
4
+
5
+ ActiveRecord::Migration.create_table :postgresql_text_events, force: true do |t|
6
+ t.text :properties
7
+ end
8
+
9
+ class PostgresqlTextEvent < PostgresqlBase
10
+ serialize :properties, JSON
11
+ end
12
+
13
+ class PostgresqlTextTest < Minitest::Test
14
+ include PropertiesTest
15
+
16
+ def model
17
+ PostgresqlTextEvent
18
+ end
19
+ end
data/test/test_helper.rb CHANGED
@@ -2,3 +2,98 @@ require "bundler/setup"
2
2
  Bundler.require(:default)
3
3
  require "minitest/autorun"
4
4
  require "minitest/pride"
5
+ require "active_record"
6
+
7
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"]
8
+
9
+ class PostgresqlBase < ActiveRecord::Base
10
+ include Ahoy::Properties
11
+ establish_connection adapter: "postgresql", database: "ahoy_test"
12
+ self.abstract_class = true
13
+ end
14
+
15
+ class MysqlBase < ActiveRecord::Base
16
+ include Ahoy::Properties
17
+ establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
18
+ self.abstract_class = true
19
+ end
20
+
21
+ module PropertiesTest
22
+ def setup
23
+ model.delete_all
24
+ end
25
+
26
+ def test_empty
27
+ assert_equal 0, count_events({})
28
+ end
29
+
30
+ def test_string
31
+ create_event value: "world"
32
+ assert_equal 1, count_events(value: "world")
33
+ end
34
+
35
+ def test_number
36
+ create_event value: 1
37
+ assert_equal 1, count_events(value: 1)
38
+ end
39
+
40
+ def test_date
41
+ today = Date.today
42
+ create_event value: today
43
+ assert_equal 1, count_events(value: today)
44
+ end
45
+
46
+ def test_time
47
+ now = Time.now
48
+ create_event value: now
49
+ assert_equal 1, count_events(value: now)
50
+ end
51
+
52
+ def test_true
53
+ create_event value: true
54
+ assert_equal 1, count_events(value: true)
55
+ end
56
+
57
+ def test_false
58
+ create_event value: false
59
+ assert_equal 1, count_events(value: false)
60
+ end
61
+
62
+ def test_nil
63
+ create_event value: nil
64
+ assert_equal 1, count_events(value: nil)
65
+ end
66
+
67
+ def test_any
68
+ create_event hello: "world", prop2: "hi"
69
+ assert_equal 1, count_events(hello: "world")
70
+ end
71
+
72
+ def test_multiple
73
+ create_event prop1: "hi", prop2: "bye"
74
+ assert_equal 1, count_events(prop1: "hi", prop2: "bye")
75
+ end
76
+
77
+ def test_multiple_order
78
+ create_event prop2: "bye", prop1: "hi"
79
+ assert_equal 1, count_events(prop1: "hi", prop2: "bye")
80
+ end
81
+
82
+ def test_partial
83
+ create_event hello: "world"
84
+ assert_equal 0, count_events(hello: "world", prop2: "hi")
85
+ end
86
+
87
+ def test_prefix
88
+ create_event value: 123
89
+ assert_equal 0, count_events(value: 1)
90
+ end
91
+
92
+ def create_event(properties)
93
+ model.create(properties: properties)
94
+ end
95
+
96
+ def count_events(properties)
97
+ model.where_properties(properties).count
98
+ end
99
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_matey
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -192,6 +192,48 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: activerecord
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: pg
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: mysql2
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
195
237
  description: Simple, powerful visit tracking for Rails
196
238
  email:
197
239
  - andrew@chartkick.com
@@ -264,6 +306,12 @@ files:
264
306
  - lib/generators/ahoy/stores/templates/mongoid_event_model.rb
265
307
  - lib/generators/ahoy/stores/templates/mongoid_initializer.rb
266
308
  - lib/generators/ahoy/stores/templates/mongoid_visit_model.rb
309
+ - test/properties/mysql_json_test.rb
310
+ - test/properties/mysql_text_test.rb
311
+ - test/properties/postgresql_hstore_test.rb
312
+ - test/properties/postgresql_json_test.rb
313
+ - test/properties/postgresql_jsonb_test.rb
314
+ - test/properties/postgresql_text_test.rb
267
315
  - test/test_helper.rb
268
316
  - test/visit_properties_test.rb
269
317
  - vendor/assets/javascripts/ahoy.js
@@ -292,5 +340,11 @@ signing_key:
292
340
  specification_version: 4
293
341
  summary: Simple, powerful visit tracking for Rails
294
342
  test_files:
343
+ - test/properties/mysql_json_test.rb
344
+ - test/properties/mysql_text_test.rb
345
+ - test/properties/postgresql_hstore_test.rb
346
+ - test/properties/postgresql_json_test.rb
347
+ - test/properties/postgresql_jsonb_test.rb
348
+ - test/properties/postgresql_text_test.rb
295
349
  - test/test_helper.rb
296
350
  - test/visit_properties_test.rb