diff --git a/.circleci/config.yml b/.circleci/config.yml index 2a9b70e1..8d21f447 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,9 +9,7 @@ jobs: # a collection of steps BUNDLE_RETRY: 3 BUNDLE_PATH: vendor/bundle RAILS_ENV: test - - image: mysql:5.6 # database image - environment: # environment variables for database - MYSQL_ROOT_PASSWORD=password + - image: postgres:9.4.11 # database image steps: # a collection of executable commands - checkout # special step to check out source code to working directory @@ -37,7 +35,7 @@ jobs: # a collection of steps paths: - vendor/bundle - # Our primary container isn't MYSQL so wait for it + # Our primary container isn't Postgres so wait for it - run: name: Install dockerize command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz @@ -45,8 +43,8 @@ jobs: # a collection of steps DOCKERIZE_VERSION: v0.6.1 - run: - name: Waiting for MySQL to be ready - command: dockerize -wait tcp://localhost:3306 -timeout 1m + name: Waiting for Postgres to be ready + command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: name: Database setup diff --git a/Dockerfile b/Dockerfile index 1b2a5870..c317f472 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ FROM ruby:1.9.3 MAINTAINER Alon Salant -RUN apt-get update && apt-get install -y mysql-client +RUN apt-get update && apt-get install -y mysql-client postgresql-client pgloader # Configure the main working directory. This is the base # directory used in any further RUN, COPY, and ENTRYPOINT diff --git a/Gemfile b/Gemfile index 8584b5f8..6df22120 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' gem "rails", "2.3.17" -gem "mysql" +gem "pg", "0.18.4" gem "authorization", github: "asalant/rails-authorization-plugin" gem 'json', '1.7.7' # (CVE-2013-026) Can remove once rails depends on > 1.7.6 gem 'haml', "3.0.25" diff --git a/Gemfile.lock b/Gemfile.lock index 63496c36..c40a3854 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,8 +30,8 @@ GEM builder json (1.7.7) kgio (2.11.2) - mysql (2.9.1) newrelic_rpm (3.7.3.204) + pg (0.18.4) power_assert (0.3.0) rack (1.1.6) rails (2.3.17) @@ -65,8 +65,8 @@ DEPENDENCIES haml (= 3.0.25) hoptoad_notifier json (= 1.7.7) - mysql newrelic_rpm + pg (= 0.18.4) rails (= 2.3.17) rdoc test-unit diff --git a/app/models/note.rb b/app/models/note.rb index ce6abf2b..2cc8edbe 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -43,7 +43,8 @@ def self.for_person_sql(person, options={}) OR (notes.notable_type = 'Visit' AND notes.notable_id IN (SELECT visits.id FROM visits WHERE visits.person_id = #{person.id}))" sql += " ORDER BY #{options[:order]}" if options[:order] - sql += " LIMIT #{options[:offset]},#{options[:limit]}" if options[:limit] + sql += " LIMIT #{options[:limit]}" if options[:limit] + sql += " OFFSET #{options[:offset]} " sql end diff --git a/app/models/organization.rb b/app/models/organization.rb index 4282a223..5b0cfb78 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -52,7 +52,8 @@ def tags unless @tags tags = Set.new ActsAsTaggableOn::Tag.find(:all, :select => 'tags.id, tags.name', - :joins => "left join (taggings, people) on (tags.id = taggings.tag_id and taggings.taggable_type = 'Person' and taggings.context = 'tags' and taggings.taggable_id = people.id)", + :joins => ["left join taggings on (tags.id = taggings.tag_id and taggings.taggable_type = 'Person' and taggings.context = 'tags')", + "left join people on (taggings.taggable_id = people.id)"], :conditions => ["people.organization_id = ?", self]) @tags = tags.sort_by {|tag| tag.name.downcase} end diff --git a/app/models/person.rb b/app/models/person.rb index a67f0c59..2579b0e0 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -65,12 +65,12 @@ def on(service_type, time) } } named_scope :after, lambda { |date| { - :conditions => [ "convert_tz(people.created_at,'+00:00','#{Time.zone.formatted_offset}') >= ?", date.to_date.to_time.utc ] + :conditions => [ "timezone('#{Time.zone.formatted_offset}', people.created_at) >= ?", date.to_date.to_time.utc ] } } named_scope :before, lambda { |date| { - :conditions => [ "convert_tz(people.created_at,'+00:00','#{Time.zone.formatted_offset}') < ?", date.to_date.to_time.utc ] + :conditions => [ "timezone('#{Time.zone.formatted_offset}', people.created_at) < ?", date.to_date.to_time.utc ] } } named_scope :matching_name, lambda { |name| { diff --git a/app/models/visit.rb b/app/models/visit.rb index 974ac006..42d19c1f 100644 --- a/app/models/visit.rb +++ b/app/models/visit.rb @@ -34,11 +34,11 @@ class Visit < ActiveRecord::Base } } named_scope :after, lambda { |date| { - :conditions => [ "convert_tz(visits.arrived_at,'+00:00','#{Time.zone.formatted_offset}') >= ?", date.to_date.to_time.utc ] + :conditions => [ "timezone('#{Time.zone.formatted_offset}', visits.arrived_at) >= ?", date.to_date.to_time.utc ] } } named_scope :before, lambda { |date| { - :conditions => [ "convert_tz(visits.arrived_at,'+00:00','#{Time.zone.formatted_offset}') < ?", date.to_date.to_time.utc ] + :conditions => [ "timezone('#{Time.zone.formatted_offset}', visits.arrived_at) < ?", date.to_date.to_time.utc ] } } def initialize(params={}) diff --git a/app/models/visits_summary.rb b/app/models/visits_summary.rb index b5b6816c..3739bd28 100644 --- a/app/models/visits_summary.rb +++ b/app/models/visits_summary.rb @@ -18,13 +18,13 @@ def summarize_days date_condition += "and visits.arrived_at > '#{criteria[:from].to_date.to_time.utc.to_s(:db)}' " if criteria[:from] date_condition += "and visits.arrived_at < '#{criteria[:to].to_date.to_time.utc.to_s(:db)}' " if criteria[:to] visits_result = ActiveRecord::Base.connection.select_all(<<-END - select date(convert_tz(visits.arrived_at,'+00:00','#{Time.zone.formatted_offset}')) as date, visits.staff, visits.member, visits.volunteer, count(*) as count + select date(timezone('#{Time.zone.formatted_offset}', visits.arrived_at)) as date, visits.staff, visits.member, visits.volunteer, count(*) as count from visits left join people on visits.person_id = people.id where people.organization_id = #{criteria[:organization_id]} #{date_condition} - group by date(visits.arrived_at), visits.staff, visits.member, visits.volunteer - order by visits.arrived_at asc + group by date(timezone('#{Time.zone.formatted_offset}', visits.arrived_at)), visits.staff, visits.member, visits.volunteer + order by date(timezone('#{Time.zone.formatted_offset}', visits.arrived_at)) asc END ) visit_days, day = [], nil @@ -80,16 +80,20 @@ def initialize(date) @staff, @member, @volunteer, @patron = 0, 0, 0, 0 end + def to_bool(value) + ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) + end + def add_row(row) - if row['staff'] == '1' - if row['volunteer'] == '1' + if to_bool(row['staff']) + if to_bool(row['volunteer']) @staff += row['count'].to_i else @member += row['count'].to_i # count non-volunteering staff as members end - elsif row['volunteer'] == '1' + elsif to_bool(row['volunteer']) @volunteer = row['count'].to_i - elsif row['member'] == '1' + elsif to_bool(row['member']) @member = row['count'].to_i else @patron = row['count'].to_i diff --git a/config/database.yml b/config/database.yml index 8a4ce2d2..e15ce929 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,18 +1,19 @@ development: - adapter: mysql - encoding: utf8 + adapter: postgresql + encoding: unicode database: freehub_for_all_development - username: root - password: password + username: postgres host: <%= ENV['DATABASE_HOST'] %> + port: 5432 # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. test: - adapter: mysql - encoding: utf8 + adapter: postgresql + encoding: unicode database: freehub_for_all_test - username: root - password: password + username: postgres host: <%= ENV['DATABASE_HOST'] %> + port: 5432 + diff --git a/db/schema.rb b/db/schema.rb index 8366d556..3cb1955f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -21,9 +21,7 @@ t.datetime "updated_at" end - add_index "notes", ["created_by_id"], :name => "fk_notes_created_by" add_index "notes", ["notable_type", "notable_id"], :name => "index_notes_on_notable_type_and_notable_id" - add_index "notes", ["updated_by_id"], :name => "fk_notes_updated_by" create_table "organizations", :force => true do |t| t.string "name" @@ -58,10 +56,6 @@ t.integer "yob" end - add_index "people", ["created_by_id"], :name => "fk_people_created_by" - add_index "people", ["organization_id"], :name => "fk_people_organization" - add_index "people", ["updated_by_id"], :name => "fk_people_updated_by" - create_table "roles", :force => true do |t| t.string "name", :limit => 40 t.string "authorizable_type", :limit => 40 @@ -90,10 +84,6 @@ t.integer "updated_by_id" end - add_index "services", ["created_by_id"], :name => "fk_services_created_by" - add_index "services", ["person_id"], :name => "fk_services_person" - add_index "services", ["updated_by_id"], :name => "fk_services_updated_by" - create_table "taggings", :force => true do |t| t.integer "tag_id" t.integer "taggable_id" @@ -138,8 +128,4 @@ t.boolean "member" end - add_index "visits", ["created_by_id"], :name => "fk_visits_created_by" - add_index "visits", ["person_id"], :name => "fk_visits_person" - add_index "visits", ["updated_by_id"], :name => "fk_visits_updated_by" - end diff --git a/docker-compose.yaml b/docker-compose.yaml index 468b00ae..2e460442 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,13 +2,14 @@ app: build: . environment: - - DATABASE_HOST=mysql + - DATABASE_HOST=postgres command: /app/script/server volumes: - .:/app ports: - "3000:3000" links: + - postgres - mysql mysql: image: mysql:5.6 @@ -16,3 +17,7 @@ mysql: - MYSQL_ROOT_PASSWORD=password ports: - "3306" +postgres: + image: postgres:9.4 + ports: + - "5432" diff --git a/pgloader.load b/pgloader.load new file mode 100644 index 00000000..6bd3ce13 --- /dev/null +++ b/pgloader.load @@ -0,0 +1,14 @@ +-- See https://github.com/dimitri/pgloader/blob/master/pgloader.1.md for +-- connection string options. + +LOAD DATABASE + FROM mysql://root:password@mysql/freehub_for_all_development + INTO postgresql://postgres@postgres/freehub_for_all_development + +-- data only: We don't need pgloader to touch the schema as Rails does a better +-- job using rake db:schema:load. +-- truncate: Ensure all tables are empty first (especially schema_migrations). +-- WARNING: THIS WILL SMOKE YOUR DATABASE! + +WITH data only, truncate +EXCLUDING table names matching 'schema_info'; \ No newline at end of file