periodic_calculations 0.0.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.
Files changed (58) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +120 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +8 -0
  6. data/Rakefile +24 -0
  7. data/lib/periodic_calculations/base.rb +36 -0
  8. data/lib/periodic_calculations/engine.rb +5 -0
  9. data/lib/periodic_calculations/lazy_query.rb +36 -0
  10. data/lib/periodic_calculations/query.rb +136 -0
  11. data/lib/periodic_calculations/query_options.rb +61 -0
  12. data/lib/periodic_calculations/version.rb +3 -0
  13. data/lib/periodic_calculations.rb +11 -0
  14. data/periodic_calculations.gemspec +28 -0
  15. data/spec/dummy/README.rdoc +28 -0
  16. data/spec/dummy/Rakefile +6 -0
  17. data/spec/dummy/app/assets/images/.keep +0 -0
  18. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  19. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  20. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  21. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  22. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  23. data/spec/dummy/app/mailers/.keep +0 -0
  24. data/spec/dummy/app/models/.keep +0 -0
  25. data/spec/dummy/app/models/activity.rb +2 -0
  26. data/spec/dummy/app/models/concerns/.keep +0 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/spec/dummy/config/application.rb +23 -0
  29. data/spec/dummy/config/boot.rb +5 -0
  30. data/spec/dummy/config/database.yml +20 -0
  31. data/spec/dummy/config/environment.rb +5 -0
  32. data/spec/dummy/config/environments/development.rb +29 -0
  33. data/spec/dummy/config/environments/production.rb +80 -0
  34. data/spec/dummy/config/environments/test.rb +36 -0
  35. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  36. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  37. data/spec/dummy/config/initializers/inflections.rb +16 -0
  38. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  39. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  40. data/spec/dummy/config/initializers/session_store.rb +3 -0
  41. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  42. data/spec/dummy/config/locales/en.yml +23 -0
  43. data/spec/dummy/config/routes.rb +56 -0
  44. data/spec/dummy/config.ru +4 -0
  45. data/spec/dummy/db/migrate/20131203172849_create_activities.rb +9 -0
  46. data/spec/dummy/db/schema.rb +26 -0
  47. data/spec/dummy/lib/assets/.keep +0 -0
  48. data/spec/dummy/log/.keep +0 -0
  49. data/spec/dummy/public/404.html +58 -0
  50. data/spec/dummy/public/422.html +58 -0
  51. data/spec/dummy/public/500.html +57 -0
  52. data/spec/dummy/public/favicon.ico +0 -0
  53. data/spec/model_spec.rb +82 -0
  54. data/spec/periodic_calculations/lazy_query_spec.rb +38 -0
  55. data/spec/periodic_calculations/query_options_spec.rb +82 -0
  56. data/spec/periodic_calculations/query_spec.rb +211 -0
  57. data/spec/spec_helper.rb +6 -0
  58. metadata +227 -0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ pkg/*
2
+ Gemfile.lock
3
+ *.gem
4
+ .bundle
5
+ nbproject/*
6
+ bin
7
+ .rspec
8
+ .rbenv-version
9
+ coverage/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,120 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ periodic_calculations (0.0.1)
5
+ rails (>= 3.2)
6
+ railties
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionmailer (4.0.1)
12
+ actionpack (= 4.0.1)
13
+ mail (~> 2.5.4)
14
+ actionpack (4.0.1)
15
+ activesupport (= 4.0.1)
16
+ builder (~> 3.1.0)
17
+ erubis (~> 2.7.0)
18
+ rack (~> 1.5.2)
19
+ rack-test (~> 0.6.2)
20
+ activemodel (4.0.1)
21
+ activesupport (= 4.0.1)
22
+ builder (~> 3.1.0)
23
+ activerecord (4.0.1)
24
+ activemodel (= 4.0.1)
25
+ activerecord-deprecated_finders (~> 1.0.2)
26
+ activesupport (= 4.0.1)
27
+ arel (~> 4.0.0)
28
+ activerecord-deprecated_finders (1.0.3)
29
+ activesupport (4.0.1)
30
+ i18n (~> 0.6, >= 0.6.4)
31
+ minitest (~> 4.2)
32
+ multi_json (~> 1.3)
33
+ thread_safe (~> 0.1)
34
+ tzinfo (~> 0.3.37)
35
+ arel (4.0.1)
36
+ atomic (1.1.14)
37
+ builder (3.1.4)
38
+ coveralls (0.7.0)
39
+ multi_json (~> 1.3)
40
+ rest-client
41
+ simplecov (>= 0.7)
42
+ term-ansicolor
43
+ thor
44
+ diff-lcs (1.2.5)
45
+ docile (1.1.1)
46
+ erubis (2.7.0)
47
+ hike (1.2.3)
48
+ i18n (0.6.5)
49
+ mail (2.5.4)
50
+ mime-types (~> 1.16)
51
+ treetop (~> 1.4.8)
52
+ mime-types (1.25.1)
53
+ minitest (4.7.5)
54
+ multi_json (1.8.2)
55
+ pg (0.15.1)
56
+ polyglot (0.3.3)
57
+ rack (1.5.2)
58
+ rack-test (0.6.2)
59
+ rack (>= 1.0)
60
+ rails (4.0.1)
61
+ actionmailer (= 4.0.1)
62
+ actionpack (= 4.0.1)
63
+ activerecord (= 4.0.1)
64
+ activesupport (= 4.0.1)
65
+ bundler (>= 1.3.0, < 2.0)
66
+ railties (= 4.0.1)
67
+ sprockets-rails (~> 2.0.0)
68
+ railties (4.0.1)
69
+ actionpack (= 4.0.1)
70
+ activesupport (= 4.0.1)
71
+ rake (>= 0.8.7)
72
+ thor (>= 0.18.1, < 2.0)
73
+ rake (10.1.0)
74
+ rest-client (1.6.7)
75
+ mime-types (>= 1.16)
76
+ rspec-core (2.14.7)
77
+ rspec-expectations (2.14.4)
78
+ diff-lcs (>= 1.1.3, < 2.0)
79
+ rspec-mocks (2.14.4)
80
+ rspec-rails (2.14.0)
81
+ actionpack (>= 3.0)
82
+ activesupport (>= 3.0)
83
+ railties (>= 3.0)
84
+ rspec-core (~> 2.14.0)
85
+ rspec-expectations (~> 2.14.0)
86
+ rspec-mocks (~> 2.14.0)
87
+ simplecov (0.8.2)
88
+ docile (~> 1.1.0)
89
+ multi_json
90
+ simplecov-html (~> 0.8.0)
91
+ simplecov-html (0.8.0)
92
+ sprockets (2.10.1)
93
+ hike (~> 1.2)
94
+ multi_json (~> 1.0)
95
+ rack (~> 1.0)
96
+ tilt (~> 1.1, != 1.3.0)
97
+ sprockets-rails (2.0.1)
98
+ actionpack (>= 3.0)
99
+ activesupport (>= 3.0)
100
+ sprockets (~> 2.8)
101
+ term-ansicolor (1.2.2)
102
+ tins (~> 0.8)
103
+ thor (0.18.1)
104
+ thread_safe (0.1.3)
105
+ atomic
106
+ tilt (1.4.1)
107
+ tins (0.13.1)
108
+ treetop (1.4.15)
109
+ polyglot
110
+ polyglot (>= 0.3.1)
111
+ tzinfo (0.3.38)
112
+
113
+ PLATFORMS
114
+ ruby
115
+
116
+ DEPENDENCIES
117
+ coveralls
118
+ periodic_calculations!
119
+ pg
120
+ rspec-rails
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Pol Miro
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # PeriodicCalculations
2
+
3
+ [![Build Status](https://travis-ci.org/polmiro/periodic_calculations.png)](https://travis-ci.org/polmiro/periodic_calculations)
4
+ [![Code Climate](https://codeclimate.com/github/polmiro/periodic_calculations.png)](https://codeclimate.com/github/polmiro/periodic_calculations)
5
+ [![Coverage Status](https://coveralls.io/repos/polmiro/periodic_calculations/badge.png)](https://coveralls.io/r/polmiro/periodic_calculations)
6
+ [![Gem Version](https://badge.fury.io/rb/periodic_calculations.png)](http://badge.fury.io/rb/periodic_calculations)
7
+
8
+ Periodic Calculations gem allows you to retrieve periodic results of aggregates that can be accumulated over time with PostgreSQL.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/setup'
3
+ begin
4
+ require 'rdoc/task'
5
+ rescue LoadError
6
+ require 'rdoc/rdoc'
7
+ require 'rake/rdoctask'
8
+ RDoc::Task = Rake::RDocTask
9
+ end
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'PeriodicCalculations'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.rdoc')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ Bundler::GemHelper.install_tasks
20
+
21
+ require 'rspec/core/rake_task'
22
+ task :default => :spec
23
+ RSpec::Core::RakeTask.new
24
+
@@ -0,0 +1,36 @@
1
+ module PeriodicCalculations
2
+ module Base
3
+ extend ActiveSupport::Concern
4
+
5
+ # TODO:
6
+ # * Rails 4 compatible only right now (scoped vs all)
7
+
8
+ module ClassMethods
9
+ def periodic_count(*args)
10
+ periodic_calculation(:count, *args)
11
+ end
12
+
13
+ def periodic_maximum(*args)
14
+ periodic_calculation(:max, *args)
15
+ end
16
+
17
+ def periodic_minimum(*args)
18
+ periodic_calculation(:min, *args)
19
+ end
20
+
21
+ def periodic_sum(*args)
22
+ periodic_calculation(:sum, *args)
23
+ end
24
+
25
+ def periodic_average(*args)
26
+ periodic_calculation(:avg, *args)
27
+ end
28
+
29
+ def periodic_calculation(operation, column_name, window_start, window_end, options = {})
30
+ query_options = QueryOptions.new(operation, column_name, window_start, window_end, options)
31
+ query = Query.new(all, query_options)
32
+ LazyQuery.new(query)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module PeriodicCalculations
2
+ class Engine < ::Rails::Engine
3
+ ActiveRecord::Base.send(:include, PeriodicCalculations::Base)
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ module PeriodicCalculations
2
+ class LazyQuery
3
+ def initialize(query)
4
+ @query = query
5
+ @executed = false
6
+ @result = nil
7
+ end
8
+
9
+ def method_missing(method_name, *args, &block)
10
+ if method_name == :to_sql
11
+ @query.to_sql
12
+ else
13
+ lazy_result.send(method_name, *args, &block)
14
+ end
15
+ end
16
+
17
+ def respond_to?(method_name, include_private = false)
18
+ method_name == :to_sql || super || lazy_result.respond_to?(method_name)
19
+ end
20
+
21
+ def result
22
+ lazy_result
23
+ end
24
+
25
+ private
26
+
27
+ def lazy_result
28
+ if @executed
29
+ @result
30
+ else
31
+ @executed = true
32
+ @result = @query.execute
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,136 @@
1
+ module PeriodicCalculations
2
+ class Query
3
+ INTERVAL_UNIT = [:day, :week, :month, :year]
4
+
5
+ # TODO:
6
+ # * prepared statement?
7
+
8
+ # Builds a periodic operation query with PostgresSQL window functions
9
+ #
10
+ # @param relation [ActiveRecord::Relation] Object to build query from
11
+ # @param query_options [QueryOptions]
12
+ # @return [Array<Array>] for each period the time of the interval and the count of it
13
+ def initialize(relation, query_options)
14
+ @relation = relation
15
+ @target_column = query_options.target_column
16
+ @timestamp_column = query_options.timestamp_column
17
+ @operation = query_options.operation.upcase
18
+ @window_function = query_options.cumulative ? "ORDER" : "PARTITION"
19
+ @binds = {
20
+ :unit => query_options.interval_unit,
21
+ :interval => "1 #{query_options.interval_unit.upcase}",
22
+ :start => query_options.window_start,
23
+ :end => query_options.window_end,
24
+ :offset => "#{query_options.timezone_offset} seconds"
25
+ }
26
+ end
27
+
28
+ def execute
29
+ ActiveRecord::Base.connection_pool.with_connection do |connection|
30
+ connection.execute(sanitized_sql).map do |elem|
31
+ [Date.parse(elem["frame"]).to_time, elem["result"].to_i]
32
+ end
33
+ end
34
+ end
35
+
36
+ def to_sql
37
+ sanitized_sql
38
+ end
39
+
40
+ private
41
+
42
+ def sanitized_sql
43
+ ActiveRecord::Base.send(:sanitize_sql_array, [Arel.sql(sql), @binds])
44
+ end
45
+
46
+ def sql
47
+ # How are timezones managed?
48
+ # * Take into account the timezone offset throughout the search,
49
+ # so that the periods are correctly grouped.
50
+ # * Restore the timezone at the very end to return the date in UTC
51
+ # being consistent with the Rails convention
52
+
53
+ # What does it do?
54
+ # 1. group currently selected rows by the interval
55
+ # 2. trim out unneeded rows if query is not cumulative
56
+ # 3. make a union to add possible missing time points
57
+ # 4. iterate over a window function that can cumulate the previous counters if needed
58
+ # 5. trim out rows outside the time window
59
+ # Cannot be done before in the same query because window function iterates after the
60
+ # where/group by/having clauses (could be improved for non cumulative queries)
61
+
62
+ <<-SQL
63
+ WITH
64
+ -- generate series within window
65
+ -- (with shifted timezones utc_date -> zone_date)
66
+ grid AS (
67
+ SELECT date_trunc(:unit, serie) AS frame,
68
+ NULL::integer AS result
69
+ FROM generate_series(
70
+ :start::timestamp + INTERVAL :offset,
71
+ :end::timestamp + INTERVAL :offset,
72
+ :interval
73
+ ) AS serie
74
+ )
75
+
76
+ -- preprocess results grouping by interval
77
+ -- (with shifted timezones utc_date -> zone_date)
78
+ , preprocessed_results AS (
79
+ #{relation_sql}
80
+ )
81
+
82
+ -- running window function calculate results and fill up gaps
83
+ , results AS (
84
+ SELECT DISTINCT frame,
85
+ #{@operation}(result) OVER (#{@window_function} BY frame) AS result
86
+ FROM (
87
+ SELECT frame, result FROM preprocessed_results
88
+ UNION ALL
89
+ SELECT frame, result FROM grid
90
+ ) AS fulfilled_gaps
91
+ )
92
+
93
+ -- cut out values outside window
94
+ -- (with shifted timezones utc_date -> zone_date)
95
+ SELECT frame,
96
+ result
97
+ FROM results
98
+ WHERE frame BETWEEN
99
+ date_trunc(:unit, :start::timestamp + INTERVAL :offset)
100
+ AND
101
+ date_trunc(:unit, :end::timestamp + INTERVAL :offset)
102
+ ORDER BY frame ASC
103
+ SQL
104
+ end
105
+
106
+ def relation_sql
107
+ # select frames an results
108
+ relation_query = @relation
109
+ .select(<<-SQL)
110
+ date_trunc(:unit, #{@relation.table_name}.#{@timestamp_column} + INTERVAL :offset) AS frame,
111
+ #{@operation}(#{@target_column}) AS result
112
+ SQL
113
+
114
+ # optimize selection if not cumulative query
115
+ if @window_function == "PARTITION"
116
+ relation_query = relation_query.where(<<-SQL)
117
+ date_trunc(:unit, #{@relation.table_name}.#{@timestamp_column} + INTERVAL :offset) BETWEEN
118
+ date_trunc(:unit, :start::timestamp + INTERVAL :offset)
119
+ AND
120
+ date_trunc(:unit, :end::timestamp + INTERVAL :offset)
121
+ SQL
122
+ end
123
+
124
+ # group results by frames
125
+ relation_query = relation_query.group(<<-SQL)
126
+ date_trunc(:unit, #{@relation.table_name}.#{@timestamp_column} + INTERVAL :offset)
127
+ SQL
128
+
129
+ relation_query.to_sql
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+ ActiveRecord::Base.extend PeriodicCalculations
@@ -0,0 +1,61 @@
1
+ module PeriodicCalculations
2
+ class QueryOptions
3
+ OPERATION = [:count, :max, :min, :sum, :avg]
4
+ INTERVAL_UNIT = [:day, :week, :month, :year]
5
+
6
+ attr_reader :operation,
7
+ :target_column,
8
+ :timestamp_column,
9
+ :window_start,
10
+ :window_end,
11
+ :interval_unit,
12
+ :cumulative,
13
+ :timezone_offset
14
+
15
+ def initialize(operation, column_name, window_start, window_end, options = {})
16
+ @operation = operation
17
+ @target_column = column_name
18
+ @timestamp_column = options[:timestamp_column] || :created_at
19
+ @window_start = window_start
20
+ @window_end = window_end
21
+ @interval_unit = options[:interval_unit] || :day
22
+ @cumulative = !!options[:cumulative]
23
+ @timezone_offset = Time.now.in_time_zone.utc_offset
24
+
25
+ validate!
26
+ end
27
+
28
+ private
29
+
30
+ def validate!
31
+ validate_operation!
32
+ validate_target_column!
33
+ validate_window!
34
+ validate_interval_unit!
35
+ end
36
+
37
+ def validate_operation!
38
+ unless OPERATION.include?(@operation)
39
+ raise ArgumentError.new("Invalid operation")
40
+ end
41
+ end
42
+
43
+ def validate_target_column!
44
+ unless @target_column.present?
45
+ raise ArgumentError.new("Target column name must be present")
46
+ end
47
+ end
48
+
49
+ def validate_window!
50
+ unless window_start.is_a?(Time) && window_end.is_a?(Time)
51
+ raise ArgumentError.new("Invalid Time window")
52
+ end
53
+ end
54
+
55
+ def validate_interval_unit!
56
+ unless INTERVAL_UNIT.include?(@interval_unit)
57
+ raise ArgumentError.new("Invalid interval unit")
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module PeriodicCalculations
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails'
2
+ require 'active_record'
3
+
4
+ module PeriodicCalculations
5
+ require "periodic_calculations/version"
6
+ require "periodic_calculations/base"
7
+ require "periodic_calculations/query"
8
+ require "periodic_calculations/query_options"
9
+ require "periodic_calculations/lazy_query"
10
+ require "periodic_calculations/engine"
11
+ end
@@ -0,0 +1,28 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require "periodic_calculations/version"
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = "periodic_calculations"
9
+ s.version = PeriodicCalculations::VERSION
10
+ s.authors = ["Pol"]
11
+ s.email = ["polmiro@gmail.com"]
12
+ s.homepage = "https://github.com/polmiro/periodic_calculations"
13
+ s.summary = "Retrieve periodic stats in periods of time"
14
+ s.description = "Periodic Calculations gem allows you to retrieve periodic results of aggregates that can be accumulated over time with PostgreSQL."
15
+ s.license = 'MIT'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "rails", ">= 3.2"
23
+ s.add_dependency "railties"
24
+
25
+ s.add_development_dependency "rspec-rails"
26
+ s.add_development_dependency "pg"
27
+ s.add_development_dependency "coveralls"
28
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
File without changes
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ class Activity < ActiveRecord::Base
2
+ end
File without changes
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require "periodic_calculations"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
+ # config.time_zone = 'Central Time (US & Canada)'
17
+
18
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
+ # config.i18n.default_locale = :de
21
+ end
22
+ end
23
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,20 @@
1
+ development:
2
+ adapter: postgresql
3
+ encoding: utf8
4
+ database: periodic_calculations_development
5
+ pool: 5
6
+ host: 127.0.0.1
7
+ username: rewardli_su
8
+ password:
9
+ timeout: 5000
10
+
11
+ test:
12
+ adapter: postgresql
13
+ encoding: utf8
14
+ database: periodic_calculations_test
15
+ pool: 5
16
+ host: 127.0.0.1
17
+ username: rewardli_su
18
+ password:
19
+ timeout: 5000
20
+