composite_primary_keys 5.0.0.rc1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,18 @@
1
+ == 5.0.0 2012-02-12
2
+ * Fix tests so they pass on MySql (Charlie Savage)
3
+ * Fix calculations to work with duplicate column names (cleesmith)
4
+ * Switch rake tasks for Postgresql and MySql to use ActiveRecord API for
5
+ creating and dropping databases (Charlie Savage)
6
+ * Follow AR 3.2 lead and introduce self.primary_keys and deprecate set_primary_keys (Charlie Savage)
7
+ * Switch from set_primary_key to self.primary_key= to avoid Rails deprecation (Charlie Savage)
8
+ * Fix issue when using multiple database connections (David Doan)
9
+ * Fix homepage in gemspec and remove email address (Charlie Savage)
10
+ * Add support for string keys to exists? (Jan Vlnas)
11
+ * Fix typo (Jason Karns)
12
+
13
+ == 5.0.0.rc1 2012-01-16
14
+ * ActiveRecord 3.2 support
15
+
1
16
  == 4.1.2 2012-01-12
2
17
  * Helper to allow the same tests to be used for both Oracle and other DBs
3
18
  by replacing quoted identifiers with all-caps equivalents on Oracle (Rhett Sutphin)
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006 Nic Williams
2
+ # Copyright (c) 2006-2012 Nic Williams and Charlie Savage
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -26,7 +26,7 @@ $:.unshift(File.dirname(__FILE__)) unless
26
26
 
27
27
  unless defined?(ActiveRecord)
28
28
  require 'rubygems'
29
- gem 'activerecord', '~> 3.2.0.rc2'
29
+ gem 'activerecord', '~> 3.2.0'
30
30
  require 'active_record'
31
31
  end
32
32
 
@@ -7,16 +7,17 @@ module ActiveRecord
7
7
  NOT_IMPLEMENTED_YET = 'Not implemented for composite primary keys yet'
8
8
 
9
9
  class << self
10
- def set_primary_keys(*keys)
11
- keys = keys.first if keys.first.is_a?(Array)
10
+ def primary_keys
11
+ @primary_keys
12
+ end
12
13
 
13
- if keys.length == 1
14
- set_primary_key(keys.first)
14
+ def primary_keys=(keys)
15
+ unless keys.kind_of?(Array)
16
+ self.primary_key = keys
15
17
  return
16
18
  end
17
19
 
18
- cattr_accessor :primary_keys
19
- self.primary_keys = keys.map { |k| k.to_sym }.to_composite_keys
20
+ @primary_keys = keys.map { |k| k.to_sym }.to_composite_keys
20
21
 
21
22
  class_eval <<-EOV
22
23
  extend CompositeClassMethods
@@ -24,6 +25,19 @@ module ActiveRecord
24
25
  EOV
25
26
  end
26
27
 
28
+ def set_primary_keys(*keys)
29
+ ActiveSupport::Deprecation.warn(
30
+ "Calling self.primary_keys = is deprecated. Please use `self.primary_keys = keys` instead."
31
+ )
32
+
33
+ keys = keys.first if keys.first.is_a?(Array)
34
+ if keys.length == 1
35
+ self.primary_key = keys.first
36
+ else
37
+ self.primary_keys = keys
38
+ end
39
+ end
40
+
27
41
  def composite?
28
42
  false
29
43
  end
@@ -107,7 +121,7 @@ module ActiveRecord
107
121
  unless ids.is_a?(Array) and ids.length == self.class.primary_keys.length
108
122
  raise "#{self.class}.id= requires #{self.class.primary_keys.length} ids"
109
123
  end
110
- [primary_keys, ids].transpose.each {|key, an_id| write_attribute(key , an_id)}
124
+ [self.class.primary_keys, ids].transpose.each {|key, an_id| write_attribute(key , an_id)}
111
125
  id
112
126
  end
113
127
 
@@ -120,7 +134,7 @@ module ActiveRecord
120
134
  end
121
135
 
122
136
  # Returns this record's primary keys values in an Array
123
- # if any value is avaliable
137
+ # if any value is available
124
138
  def to_key
125
139
  ids.to_a if !ids.compact.empty? # XXX Maybe use primary_keys with send instead of ids
126
140
  end
@@ -7,12 +7,25 @@ module CompositePrimaryKeys
7
7
  Arel::Nodes::And.new(predicates)
8
8
  end
9
9
  end
10
-
11
- def cpk_or_predicate(predicates)
12
- # Can't do or here, arel does the wrong thing and makes a really
13
- # deeply nested stack that blows up
10
+
11
+ def figure_engine(table)
12
+ case table
13
+ when Arel::Nodes::TableAlias
14
+ table.left.engine
15
+ when Arel::Table
16
+ table.engine
17
+ when ::ActiveRecord::Base
18
+ table
19
+ else
20
+ nil
21
+ end
22
+ end
23
+
24
+ def cpk_or_predicate(predicates, table = nil)
25
+ engine = figure_engine(table)
14
26
  predicates = predicates.map do |predicate|
15
- "(#{predicate.to_sql})"
27
+ predicate_sql = engine ? predicate.to_sql(engine) : predicate.to_sql
28
+ "(#{predicate_sql})"
16
29
  end
17
30
  predicates = "(#{predicates.join(" OR ")})"
18
31
  Arel::Nodes::SqlLiteral.new(predicates)
@@ -43,7 +56,7 @@ module CompositePrimaryKeys
43
56
  cpk_and_predicate(eq_predicates)
44
57
  end
45
58
 
46
- cpk_or_predicate(and_predicates)
59
+ cpk_or_predicate(and_predicates, table)
47
60
  end
48
61
  end
49
62
  end
@@ -1,6 +1,19 @@
1
1
  module CompositePrimaryKeys
2
2
  module ActiveRecord
3
3
  module Calculations
4
+ def aggregate_column(column_name)
5
+ # CPK
6
+ if column_name.kind_of?(Array)
7
+ column_name.map do |column|
8
+ Arel::Attribute.new(@klass.unscoped.table, column)
9
+ end
10
+ elsif @klass.column_names.include?(column_name.to_s)
11
+ Arel::Attribute.new(@klass.unscoped.table, column_name)
12
+ else
13
+ Arel.sql(column_name == :all ? "*" : column_name.to_s)
14
+ end
15
+ end
16
+
4
17
  def execute_simple_calculation(operation, column_name, distinct)
5
18
  # Postgresql doesn't like ORDER BY when there are no GROUP BY
6
19
  relation = reorder(nil)
@@ -33,8 +46,18 @@ module CompositePrimaryKeys
33
46
  # CPK
34
47
  # aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
35
48
  # relation.select_values = [aliased_column]
36
- column = aggregate_column(column_name)
37
- relation.select_values = ["DISTINCT #{column.to_s}"]
49
+ relation.select_values = if column_name.kind_of?(Array)
50
+ column_name.map do |column|
51
+ Arel::Attribute.new(@klass.unscoped.table, column)
52
+ end
53
+ elsif @klass.column_names.include?(column_name.to_s)
54
+ [Arel::Attribute.new(@klass.unscoped.table, column_name)]
55
+ else
56
+ [Arel.sql(column_name == :all ? "#{@klass.quoted_table_name}.*" : column_name.to_s)]
57
+ end
58
+
59
+
60
+ relation.distinct(true)
38
61
  subquery = relation.arel.as(subquery_alias)
39
62
 
40
63
  sm = Arel::SelectManager.new relation.engine
@@ -56,9 +56,11 @@ module CompositePrimaryKeys
56
56
  when CompositePrimaryKeys::CompositeKeys
57
57
  relation = relation.where(cpk_id_predicate(table, primary_key, id))
58
58
  when Array
59
- if !id.first.kind_of?(String)
59
+ pk_length = @klass.primary_keys.length
60
+
61
+ if id.length == pk_length # E.g. id = ['France', 'Paris']
60
62
  return self.exists?(id.to_composite_keys)
61
- else
63
+ else # Assume that id contains where relation
62
64
  relation = relation.where(id)
63
65
  end
64
66
  when Hash
@@ -80,8 +82,10 @@ module CompositePrimaryKeys
80
82
  # find('1,2', '3,4') -> ['1,2','3,4']
81
83
 
82
84
  # Normalize incoming data. Note the last arg can be nil. Happens
83
- # when find is called with nil options like the reload method does.
85
+ # when find is called with nil options which is then passed on
86
+ # to find_with_ids.
84
87
  ids.compact!
88
+
85
89
  ids = [ids] unless ids.first.kind_of?(Array)
86
90
 
87
91
  results = ids.map do |cpk_ids|
@@ -3,6 +3,6 @@ module CompositePrimaryKeys
3
3
  MAJOR = 5
4
4
  MINOR = 0
5
5
  TINY = 0
6
- STRING = [MAJOR, MINOR, TINY, 'rc1'].join('.')
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
7
  end
8
8
  end
@@ -2,20 +2,30 @@ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
2
  require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
3
 
4
4
  namespace :mysql do
5
+ desc 'Create the MySQL test databases'
6
+ task :create_database do
7
+ ActiveRecord::Base.clear_all_connections!
8
+ spec = CompositePrimaryKeys::ConnectionSpec['mysql'].dup
9
+ database_name = spec.delete('database')
10
+ connection = ActiveRecord::Base.establish_connection(spec)
11
+ ActiveRecord::Base.connection.create_database(database_name)
12
+ ActiveRecord::Base.clear_all_connections!
13
+ end
14
+
5
15
  desc 'Build the MySQL test databases'
6
- task :build_databases => :load_connection do
7
- options_str = connection_string
8
- # creates something like "-u#{username} -p#{password} -S#{socket}"
9
- sh %{ mysqladmin #{options_str} create "#{SPEC['database']}" }
16
+ task :build_databases => [:create_database] do
17
+ path = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'mysql.sql')
18
+ sql = File.open(path, 'rb') do |file|
19
+ file.read
20
+ end
10
21
 
11
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'mysql.sql')
12
- sh %{ mysql #{options_str} "#{SPEC['database']}" < #{schema} }
22
+ Rake::Task['mysql:load_connection'].invoke
23
+ ActiveRecord::Base.connection.execute(sql)
13
24
  end
14
25
 
15
26
  desc 'Drop the MySQL test databases'
16
- task :drop_databases => :load_connection do
17
- options_str = connection_string
18
- sh %{ mysqladmin #{options_str} -f drop "#{SPEC['database']}" }
27
+ task :drop_databases => :load_connection do
28
+ ActiveRecord::Base.connection.drop_database(SPEC['database'])
19
29
  end
20
30
 
21
31
  desc 'Rebuild the MySQL test databases'
@@ -2,17 +2,37 @@ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
2
  require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
3
 
4
4
  namespace :postgresql do
5
+ desc 'Create the PostgreSQL test databases'
6
+ task :create_database do
7
+ ActiveRecord::Base.clear_all_connections!
8
+ spec = CompositePrimaryKeys::ConnectionSpec['postgresql'].dup
9
+ database_name = spec.delete('database')
10
+ spec['database'] = 'postgres'
11
+ connection = ActiveRecord::Base.establish_connection(spec)
12
+ ActiveRecord::Base.connection.create_database(database_name)
13
+ ActiveRecord::Base.clear_all_connections!
14
+ end
15
+
5
16
  desc 'Build the PostgreSQL test databases'
6
- task :build_databases => :load_connection do
7
- sh %{ createdb #{connection_string} "#{SPEC['database']}" }
17
+ task :build_databases => [:create_database] do
18
+ path = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'postgresql.sql')
19
+ sql = File.open(path, 'rb') do |file|
20
+ file.read
21
+ end
8
22
 
9
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'postgresql.sql')
10
- sh %{ psql #{connection_string} "#{SPEC['database']}" -f #{schema} }
23
+ Rake::Task['postgresql:load_connection'].invoke
24
+ ActiveRecord::Base.connection.execute(sql)
11
25
  end
12
26
 
13
27
  desc 'Drop the PostgreSQL test databases'
14
- task :drop_databases => :load_connection do
15
- sh %{ dropdb #{connection_string} "#{SPEC['database']}" }
28
+ task :drop_databases => :load_connection do
29
+ ActiveRecord::Base.clear_all_connections!
30
+ spec = CompositePrimaryKeys::ConnectionSpec['postgresql'].dup
31
+ database_name = spec.delete('database')
32
+ spec['database'] = 'postgres'
33
+ connection = ActiveRecord::Base.establish_connection(spec)
34
+ ActiveRecord::Base.connection.drop_database(SPEC['database'])
35
+ ActiveRecord::Base.clear_all_connections!
16
36
  end
17
37
 
18
38
  desc 'Rebuild the PostgreSQL test databases'
@@ -9,11 +9,13 @@ require 'composite_primary_keys'
9
9
 
10
10
  # Now load the connection spec
11
11
  require File.join(PROJECT_ROOT, "test", "connections", "connection_spec")
12
- spec = CompositePrimaryKeys::ConnectionSpec[ENV['ADAPTER'] || 'postgresql']
12
+
13
+ spec_name = ENV['ADAPTER'] || 'postgresql'
14
+ spec = CompositePrimaryKeys::ConnectionSpec[spec_name]
13
15
 
14
16
  # And now connect to the database
15
17
  adapter = spec['adapter']
16
- require File.join(PROJECT_ROOT, "test", "connections", "native_#{adapter}", "connection")
18
+ require File.join(PROJECT_ROOT, "test", "connections", "native_#{spec_name}", "connection")
17
19
 
18
20
  # Tell active record about the configuration
19
21
  ActiveRecord::Base.configurations[:test] = spec
@@ -3,8 +3,9 @@
3
3
  # 2. Update to match the databases you want to test against.
4
4
 
5
5
  mysql:
6
- adapter: mysql
6
+ adapter: mysql2
7
7
  username: root
8
+ password: mysql
8
9
  database: composite_primary_keys_unittest
9
10
 
10
11
  sqlite3:
@@ -24,7 +24,7 @@ end
24
24
  module GlobePG
25
25
  class TeacherToSchool < PGBase
26
26
  set_table_name 'teacher_to_school'
27
- set_primary_keys ['teacherid', 'schoolid']
27
+ self.primary_keys = ['teacherid', 'schoolid']
28
28
 
29
29
  belongs_to :globe_teacher, :foreign_key => 'teacherid'
30
30
  belongs_to :globe_school, :foreign_key => 'schoolid'
@@ -34,7 +34,7 @@ end
34
34
  module GlobePG
35
35
  class GlobeSchool < PGBase
36
36
  set_table_name 'globe_school'
37
- set_primary_key 'schoolid'
37
+ self.primary_key = 'schoolid'
38
38
  has_many :teacher_to_schools, :foreign_key => :schoolid
39
39
  has_many :globe_teachers, :through => :teacher_to_schools
40
40
  end
@@ -43,7 +43,7 @@ end
43
43
  module GlobePG
44
44
  class GlobeTeacher < PGBase
45
45
  set_table_name 'globe_teacher'
46
- set_primary_key 'teacherid'
46
+ self.primary_key = 'teacherid'
47
47
  has_many :teacher_to_schools, :foreign_key => :teacherid
48
48
  has_many :globe_schools, :through => :teacher_to_schools
49
49
  end
@@ -1,3 +1,3 @@
1
1
  class Capitol < ActiveRecord::Base
2
- set_primary_keys :country, :city
2
+ self.primary_keys = :country, :city
3
3
  end
@@ -1,186 +1,186 @@
1
1
  create table reference_types (
2
- reference_type_id int(11) not null auto_increment,
2
+ reference_type_id int not null auto_increment,
3
3
  type_label varchar(50) default null,
4
4
  abbreviation varchar(50) default null,
5
5
  description varchar(50) default null,
6
6
  primary key (reference_type_id)
7
- ) type=InnoDB;
7
+ );
8
8
 
9
9
  create table reference_codes (
10
- reference_type_id int(11),
11
- reference_code int(11) not null,
10
+ reference_type_id int not null,
11
+ reference_code int not null,
12
12
  code_label varchar(50) default null,
13
13
  abbreviation varchar(50) default null,
14
14
  description varchar(50) default null,
15
15
  primary key (reference_type_id, reference_code)
16
- ) type=InnoDB;
16
+ );
17
17
 
18
18
  create table products (
19
- id int(11) not null auto_increment,
19
+ id int not null auto_increment,
20
20
  name varchar(50) default null,
21
21
  primary key (id)
22
- ) type=InnoDB;
22
+ );
23
23
 
24
24
  create table tariffs (
25
- tariff_id int(11) not null,
25
+ tariff_id int not null,
26
26
  start_date date not null,
27
27
  amount integer(11) default null,
28
28
  primary key (tariff_id, start_date)
29
- ) type=InnoDB;
29
+ );
30
30
 
31
31
  create table product_tariffs (
32
- product_id int(11) not null,
33
- tariff_id int(11) not null,
32
+ product_id int not null,
33
+ tariff_id int not null,
34
34
  tariff_start_date date not null,
35
35
  primary key (product_id, tariff_id, tariff_start_date)
36
- ) type=InnoDB;
36
+ );
37
37
 
38
38
  create table suburbs (
39
- city_id int(11) not null,
40
- suburb_id int(11) not null,
39
+ city_id int not null,
40
+ suburb_id int not null,
41
41
  name varchar(50) not null,
42
42
  primary key (city_id, suburb_id)
43
- ) type=InnoDB;
43
+ );
44
44
 
45
45
  create table streets (
46
- id int(11) not null auto_increment,
47
- city_id int(11) not null,
48
- suburb_id int(11) not null,
46
+ id int not null auto_increment,
47
+ city_id int not null,
48
+ suburb_id int not null,
49
49
  name varchar(50) not null,
50
50
  primary key (id)
51
- ) type=InnoDB;
51
+ );
52
52
 
53
53
  create table users (
54
- id int(11) not null auto_increment,
54
+ id int not null auto_increment,
55
55
  name varchar(50) not null,
56
56
  primary key (id)
57
- ) type=InnoDB;
57
+ );
58
58
 
59
59
  create table articles (
60
- id int(11) not null auto_increment,
60
+ id int not null auto_increment,
61
61
  name varchar(50) not null,
62
62
  primary key (id)
63
- ) type=InnoDB;
63
+ );
64
64
 
65
65
  create table readings (
66
- id int(11) not null auto_increment,
67
- user_id int(11) not null,
68
- article_id int(11) not null,
69
- rating int(11) not null,
66
+ id int not null auto_increment,
67
+ user_id int not null,
68
+ article_id int not null,
69
+ rating int not null,
70
70
  primary key (id)
71
- ) type=InnoDB;
71
+ );
72
72
 
73
73
  create table groups (
74
- id int(11) not null auto_increment,
74
+ id int not null auto_increment,
75
75
  name varchar(50) not null,
76
76
  primary key (id)
77
- ) type=InnoDB;
77
+ );
78
78
 
79
79
  create table memberships (
80
- user_id int(11) not null,
81
- group_id int(11) not null,
80
+ user_id int not null,
81
+ group_id int not null,
82
82
  primary key (user_id,group_id)
83
- ) type=InnoDB;
83
+ );
84
84
 
85
85
  create table membership_statuses (
86
- id int(11) not null auto_increment,
87
- user_id int(11) not null,
88
- group_id int(11) not null,
86
+ id int not null auto_increment,
87
+ user_id int not null,
88
+ group_id int not null,
89
89
  status varchar(50) not null,
90
90
  primary key (id)
91
- ) type=InnoDB;
91
+ );
92
92
 
93
93
  create table departments (
94
- department_id int(11) not null,
95
- location_id int(11) not null,
94
+ department_id int not null,
95
+ location_id int not null,
96
96
  primary key (department_id, location_id)
97
- ) type=InnoDB;
97
+ );
98
98
 
99
99
  create table employees (
100
- id int(11) not null auto_increment,
101
- department_id int(11) default null,
102
- location_id int(11) default null,
100
+ id int not null auto_increment,
101
+ department_id int default null,
102
+ location_id int default null,
103
103
  primary key (id)
104
- ) type=InnoDB;
104
+ );
105
105
 
106
106
  create table comments (
107
- id int(11) not null auto_increment,
108
- person_id int(11) default null,
107
+ id int not null auto_increment,
108
+ person_id int default null,
109
109
  person_type varchar(100) default null,
110
- hack_id int(11) default null,
110
+ hack_id int default null,
111
111
  primary key (id)
112
- ) type=InnoDB;
112
+ );
113
113
 
114
114
  create table hacks (
115
- id int(11) not null auto_increment,
115
+ id int not null auto_increment,
116
116
  name varchar(50) not null,
117
117
  primary key (id)
118
- ) type=InnoDB;
118
+ );
119
119
 
120
120
  create table restaurants (
121
- franchise_id int(11) not null,
122
- store_id int(11) not null,
121
+ franchise_id int not null,
122
+ store_id int not null,
123
123
  name varchar(100),
124
124
  primary key (franchise_id, store_id)
125
- ) type=InnoDB;
125
+ );
126
126
 
127
127
  create table restaurants_suburbs (
128
- franchise_id int(11) not null,
129
- store_id int(11) not null,
130
- city_id int(11) not null,
131
- suburb_id int(11) not null
132
- ) type=InnoDB;
128
+ franchise_id int not null,
129
+ store_id int not null,
130
+ city_id int not null,
131
+ suburb_id int not null
132
+ );
133
133
 
134
134
  create table dorms (
135
- id int(11) not null auto_increment,
135
+ id int not null auto_increment,
136
136
  primary key(id)
137
- ) type=InnoDB;
137
+ );
138
138
 
139
139
  create table rooms (
140
- dorm_id int(11) not null,
141
- room_id int(11) not null,
140
+ dorm_id int not null,
141
+ room_id int not null,
142
142
  primary key (dorm_id, room_id)
143
- ) type=InnoDB;
143
+ );
144
144
 
145
145
  create table room_attributes (
146
- id int(11) not null auto_increment,
146
+ id int not null auto_increment,
147
147
  name varchar(50),
148
148
  primary key(id)
149
- ) type=InnoDB;
149
+ );
150
150
 
151
151
  create table room_attribute_assignments (
152
- dorm_id int(11) not null,
153
- room_id int(11) not null,
154
- room_attribute_id int(11) not null
155
- ) type=InnoDB;
152
+ dorm_id int not null,
153
+ room_id int not null,
154
+ room_attribute_id int not null
155
+ );
156
156
 
157
157
  create table students (
158
- id int(11) not null auto_increment,
158
+ id int not null auto_increment,
159
159
  primary key(id)
160
- ) type=InnoDB;
160
+ );
161
161
 
162
162
  create table room_assignments (
163
- student_id int(11) not null,
164
- dorm_id int(11) not null,
165
- room_id int(11) not null
166
- ) type=InnoDB;
163
+ student_id int not null,
164
+ dorm_id int not null,
165
+ room_id int not null
166
+ );
167
167
 
168
168
  create table seats (
169
- flight_number int(11) not null,
170
- seat int(11) not null,
169
+ flight_number int not null,
170
+ seat int not null,
171
171
  customer int,
172
172
  primary key (flight_number, seat)
173
- ) type=InnoDB;
173
+ );
174
174
 
175
175
  create table capitols (
176
176
  country varchar(100) default null,
177
177
  city varchar(100) default null,
178
178
  primary key (country, city)
179
- ) type=InnoDB;
179
+ );
180
180
 
181
181
  create table products_restaurants (
182
- product_id int(11) not null,
183
- franchise_id int(11) not null,
184
- store_id int(11) not null
185
- ) type=InnoDB;
182
+ product_id int not null,
183
+ franchise_id int not null,
184
+ store_id int not null
185
+ );
186
186
 
@@ -1,5 +1,5 @@
1
1
  class Department < ActiveRecord::Base
2
- set_primary_keys :department_id, :location_id
2
+ self.primary_keys = :department_id, :location_id
3
3
  has_many :employees, :foreign_key => [:department_id, :location_id]
4
4
  has_one :head, :class_name => 'Employee', :foreign_key => [:department_id, :location_id], :dependent => :delete
5
5
  end
@@ -1,3 +1,3 @@
1
1
  class Dorm < ActiveRecord::Base
2
- has_many :rooms, :include => :room_attributes, :primary_key => [:id]
2
+ has_many :rooms, :include => :room_attributes, :primary_key => [:id]
3
3
  end
@@ -1,6 +1,6 @@
1
1
  class Membership < ActiveRecord::Base
2
- # set_primary_keys *keys - turns on composite key functionality
3
- set_primary_keys :user_id, :group_id
2
+ # self.primary_keys = *keys - turns on composite key functionality
3
+ self.primary_keys = :user_id, :group_id
4
4
  belongs_to :user
5
5
  belongs_to :group
6
6
  has_many :statuses, :class_name => 'MembershipStatus', :foreign_key => [:user_id, :group_id]
@@ -1,5 +1,5 @@
1
1
  class Product < ActiveRecord::Base
2
- set_primary_keys :id # redundant
2
+ self.primary_keys = :id # redundant
3
3
  has_many :product_tariffs, :foreign_key => :product_id, :dependent => :delete_all
4
4
  has_many :tariffs, :through => :product_tariffs, :foreign_key => [:tariff_id, :tariff_start_date]
5
5
 
@@ -1,5 +1,5 @@
1
1
  class ProductTariff < ActiveRecord::Base
2
- set_primary_keys :product_id, :tariff_id, :tariff_start_date
2
+ self.primary_keys = :product_id, :tariff_id, :tariff_start_date
3
3
  belongs_to :product, :foreign_key => :product_id
4
4
  belongs_to :tariff, :foreign_key => [:tariff_id, :tariff_start_date]
5
5
  end
@@ -1,5 +1,5 @@
1
1
  class ReferenceCode < ActiveRecord::Base
2
- set_primary_keys :reference_type_id, :reference_code
2
+ self.primary_keys = :reference_type_id, :reference_code
3
3
 
4
4
  belongs_to :reference_type, :foreign_key => "reference_type_id"
5
5
 
@@ -1,5 +1,5 @@
1
1
  class ReferenceType < ActiveRecord::Base
2
- set_primary_key :reference_type_id
2
+ self.primary_key = :reference_type_id
3
3
  has_many :reference_codes, :foreign_key => "reference_type_id", :dependent => :destroy
4
4
 
5
5
  validates_presence_of :type_label, :abbreviation
@@ -1,5 +1,5 @@
1
1
  class Restaurant < ActiveRecord::Base
2
- set_primary_keys :franchise_id, :store_id
2
+ self.primary_keys = :franchise_id, :store_id
3
3
  has_and_belongs_to_many :suburbs,
4
4
  :foreign_key => [:franchise_id, :store_id],
5
5
  :association_foreign_key => [:city_id, :suburb_id]
@@ -1,5 +1,5 @@
1
1
  class Room < ActiveRecord::Base
2
- set_primary_keys :dorm_id, :room_id
2
+ self.primary_keys = :dorm_id, :room_id
3
3
  belongs_to :dorm
4
4
  has_many :room_assignments, :foreign_key => [:dorm_id, :room_id]
5
5
  has_many :room_attribute_assignments, :foreign_key => [:dorm_id, :room_id]
@@ -1,5 +1,5 @@
1
1
  class RoomAssignment < ActiveRecord::Base
2
- set_primary_keys :student_id, :dorm_id, :room_id
2
+ self.primary_keys = :student_id, :dorm_id, :room_id
3
3
  belongs_to :student
4
4
  belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
5
5
 
@@ -1,5 +1,5 @@
1
1
  class RoomAttributeAssignment < ActiveRecord::Base
2
- set_primary_keys :dorm_id, :room_id, :room_attribute_id
2
+ self.primary_keys = :dorm_id, :room_id, :room_attribute_id
3
3
  belongs_to :room, :foreign_key => [:dorm_id, :room_id]
4
4
  belongs_to :room_attribute
5
5
  end
@@ -1,5 +1,5 @@
1
1
  class Seat < ActiveRecord::Base
2
- set_primary_keys [:flight_number, :seat]
2
+ self.primary_keys = [:flight_number, :seat]
3
3
 
4
4
  validates_uniqueness_of :customer
5
5
  end
@@ -1,5 +1,5 @@
1
1
  class Suburb < ActiveRecord::Base
2
- set_primary_keys :city_id, :suburb_id
2
+ self.primary_keys = :city_id, :suburb_id
3
3
  has_many :streets, :foreign_key => [:city_id, :suburb_id]
4
4
  has_many :first_streets, :foreign_key => [:city_id, :suburb_id],
5
5
  :class_name => 'Street', :conditions => "streets.name = 'First Street'"
@@ -1,5 +1,5 @@
1
1
  class Tariff < ActiveRecord::Base
2
- set_primary_keys [:tariff_id, :start_date]
2
+ self.primary_keys = [:tariff_id, :start_date]
3
3
  has_many :product_tariffs, :foreign_key => [:tariff_id, :tariff_start_date]
4
4
  has_many :products, :through => :product_tariffs, :foreign_key => [:tariff_id, :tariff_start_date]
5
5
  end
@@ -5,27 +5,6 @@ class TestAssociations < ActiveSupport::TestCase
5
5
  :dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
6
6
  :departments, :employees, :memberships, :membership_statuses
7
7
 
8
- def test_count
9
- assert_equal(3, Product.count(:include => :product_tariffs))
10
- assert_equal(3, Tariff.count(:include => :product_tariffs))
11
-
12
- expected = {Date.today => 2,
13
- Date.today.next => 1}
14
-
15
- assert_equal(expected, Tariff.count(:group => :start_date))
16
- end
17
-
18
- def test_count_distinct
19
- product = products(:first_product)
20
- assert_equal(2, product.product_tariffs.count(:distinct => true))
21
- end
22
-
23
- def test_count_includes
24
- count = Dorm.count(:include => :rooms,
25
- :conditions => ["rooms.room_id = ?", 2])
26
- assert_equal(1, count)
27
- end
28
-
29
8
  def test_products
30
9
  assert_not_nil products(:first_product).product_tariffs
31
10
  assert_equal 2, products(:first_product).product_tariffs.length
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestCalculations < ActiveSupport::TestCase
4
+ fixtures :articles, :products, :tariffs, :product_tariffs, :suburbs, :streets, :restaurants,
5
+ :dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
6
+ :departments, :employees, :memberships, :membership_statuses
7
+
8
+ def test_count
9
+ assert_equal(3, Product.count(:include => :product_tariffs))
10
+ assert_equal(3, Tariff.count(:include => :product_tariffs))
11
+
12
+ expected = {Date.today => 2,
13
+ Date.today.next => 1}
14
+
15
+ assert_equal(expected, Tariff.count(:group => :start_date))
16
+ end
17
+
18
+ def test_count_distinct
19
+ product = products(:first_product)
20
+ assert_equal(2, product.product_tariffs.count(:distinct => true))
21
+ end
22
+
23
+ def test_count_includes
24
+ count = Dorm.count(:include => :rooms,
25
+ :conditions => ["rooms.room_id = ?", 2])
26
+ assert_equal(1, count)
27
+ end
28
+
29
+ def test_count_includes_dup_columns
30
+ count = Tariff.includes(:product_tariffs).where("product_tariffs.tariff_id = ?", 2).count
31
+ assert_equal(1, count)
32
+ end
33
+ end
@@ -1,7 +1,7 @@
1
1
  require File.expand_path('../abstract_unit', __FILE__)
2
2
 
3
3
  class TestExists < ActiveSupport::TestCase
4
- fixtures :articles, :departments
4
+ fixtures :articles, :departments, :capitols
5
5
 
6
6
  def test_id
7
7
  assert(Article.exists?(1))
@@ -32,4 +32,9 @@ class TestExists < ActiveSupport::TestCase
32
32
  assert(Department.exists?(['department_id = ? and location_id = ?', 1, 1]))
33
33
  assert(!Department.exists?(['department_id = ? and location_id = ?', 1, -1]))
34
34
  end
35
+
36
+ def test_cpk_array_string_id
37
+ assert(Capitol.exists?(['The Netherlands', 'Amsterdam']))
38
+ assert(!Capitol.exists?(['The Netherlands', 'Paris']))
39
+ end
35
40
  end
@@ -50,7 +50,13 @@ class TestFind < ActiveSupport::TestCase
50
50
  error = assert_raise(::ActiveRecord::RecordNotFound) do
51
51
  ReferenceCode.find(['999', '999'])
52
52
  end
53
- assert_equal(with_quoted_identifiers("Couldn't find ReferenceCode with ID=999,999 WHERE \"reference_codes\".\"reference_type_id\" = 999 AND \"reference_codes\".\"reference_code\" = 999"),
53
+
54
+ connection = ActiveRecord::Base.connection
55
+ ref_type_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_type_id')}"
56
+ ref_code_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_code')}"
57
+ expected = "Couldn't find ReferenceCode with ID=999,999 WHERE #{ref_type_quoted} = 999 AND #{ref_code_quoted} = 999"
58
+
59
+ assert_equal(with_quoted_identifiers(expected),
54
60
  error.message)
55
61
  end
56
62
 
@@ -29,9 +29,4 @@ class TestMiscellaneous < ActiveSupport::TestCase
29
29
  assert_equal composite?, @first.composite?
30
30
  end
31
31
  end
32
-
33
- def test_count
34
- assert_equal 3, Product.count
35
- end
36
-
37
32
  end
@@ -14,9 +14,12 @@ class TestEqual < ActiveSupport::TestCase
14
14
  predicates << dep[:id].eq(i)
15
15
  end
16
16
 
17
+ connection = ActiveRecord::Base.connection
18
+ quoted = "#{connection.quote_table_name('departments')}.#{connection.quote_column_name('id')}"
19
+ expected = "((#{quoted} = 0) OR (#{quoted} = 1) OR (#{quoted} = 2))"
20
+
17
21
  pred = cpk_or_predicate(predicates)
18
- assert_equal(with_quoted_identifiers('(("departments"."id" = 0) OR ("departments"."id" = 1) OR ("departments"."id" = 2))'),
19
- pred)
22
+ assert_equal(with_quoted_identifiers(expected), pred.to_s)
20
23
  end
21
24
 
22
25
  def test_and
@@ -28,8 +31,11 @@ class TestEqual < ActiveSupport::TestCase
28
31
  predicates << dep[:id].eq(i)
29
32
  end
30
33
 
34
+ connection = ActiveRecord::Base.connection
35
+ quoted = "#{connection.quote_table_name('departments')}.#{connection.quote_column_name('id')}"
36
+ expected = "#{quoted} = 0 AND #{quoted} = 1 AND #{quoted} = 2"
37
+
31
38
  pred = cpk_and_predicate(predicates)
32
- assert_equal(with_quoted_identifiers('"departments"."id" = 0 AND "departments"."id" = 1 AND "departments"."id" = 2'),
33
- pred.to_sql)
39
+ assert_equal(with_quoted_identifiers(expected), pred.to_sql)
34
40
  end
35
41
  end
@@ -4,6 +4,7 @@ require 'test/unit'
4
4
  test_associations
5
5
  test_attribute_methods
6
6
  test_attributes
7
+ test_calculations
7
8
  test_composite_arrays
8
9
  test_create
9
10
  test_delete
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_primary_keys
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.rc1
5
- prerelease: 6
4
+ version: 5.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dr Nic Williams
@@ -10,22 +10,21 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-01-16 00:00:00.000000000 Z
13
+ date: 2012-02-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
17
- requirement: &24769260 !ruby/object:Gem::Requirement
17
+ requirement: &24424140 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: 3.2.0.rc2
22
+ version: 3.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *24769260
26
- description: Composite key support for ActiveRecord 3
27
- email:
28
- - drnicwilliams@gmail.com
25
+ version_requirements: *24424140
26
+ description: Composite key support for ActiveRecord
27
+ email:
29
28
  executables: []
30
29
  extensions: []
31
30
  extra_rdoc_files: []
@@ -154,6 +153,7 @@ files:
154
153
  - test/test_associations.rb
155
154
  - test/test_attributes.rb
156
155
  - test/test_attribute_methods.rb
156
+ - test/test_calculations.rb
157
157
  - test/test_composite_arrays.rb
158
158
  - test/test_create.rb
159
159
  - test/test_delete.rb
@@ -172,7 +172,7 @@ files:
172
172
  - test/test_tutorial_example.rb
173
173
  - test/test_update.rb
174
174
  - test/test_validations.rb
175
- homepage: http://github.com/cfis/composite_primary_keys
175
+ homepage: https://github.com/drnic/composite_primary_keys
176
176
  licenses: []
177
177
  post_install_message:
178
178
  rdoc_options: []
@@ -187,9 +187,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
187
  required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  none: false
189
189
  requirements:
190
- - - ! '>'
190
+ - - ! '>='
191
191
  - !ruby/object:Gem::Version
192
- version: 1.3.1
192
+ version: '0'
193
193
  requirements: []
194
194
  rubyforge_project: compositekeys
195
195
  rubygems_version: 1.8.15
@@ -205,6 +205,7 @@ test_files:
205
205
  - test/test_associations.rb
206
206
  - test/test_attributes.rb
207
207
  - test/test_attribute_methods.rb
208
+ - test/test_calculations.rb
208
209
  - test/test_composite_arrays.rb
209
210
  - test/test_create.rb
210
211
  - test/test_delete.rb