composite_primary_keys 5.0.0.rc1 → 5.0.0

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.
@@ -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