composite_primary_keys 7.0.13 → 7.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +615 -608
  3. data/lib/composite_primary_keys.rb +110 -110
  4. data/lib/composite_primary_keys/associations/association.rb +23 -23
  5. data/lib/composite_primary_keys/associations/association_scope.rb +77 -77
  6. data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +59 -59
  7. data/lib/composite_primary_keys/associations/has_many_association.rb +56 -56
  8. data/lib/composite_primary_keys/associations/join_dependency.rb +89 -89
  9. data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +38 -38
  10. data/lib/composite_primary_keys/associations/preloader/association.rb +78 -78
  11. data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +46 -46
  12. data/lib/composite_primary_keys/attribute_methods/dirty.rb +26 -26
  13. data/lib/composite_primary_keys/attribute_methods/read.rb +34 -34
  14. data/lib/composite_primary_keys/attribute_methods/write.rb +36 -36
  15. data/lib/composite_primary_keys/base.rb +0 -6
  16. data/lib/composite_primary_keys/composite_arrays.rb +30 -30
  17. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +4 -2
  18. data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +17 -0
  19. data/lib/composite_primary_keys/core.rb +47 -47
  20. data/lib/composite_primary_keys/persistence.rb +60 -60
  21. data/lib/composite_primary_keys/relation.rb +56 -56
  22. data/lib/composite_primary_keys/relation/calculations.rb +75 -65
  23. data/lib/composite_primary_keys/relation/finder_methods.rb +196 -196
  24. data/lib/composite_primary_keys/sanitization.rb +52 -52
  25. data/lib/composite_primary_keys/validations/uniqueness.rb +37 -39
  26. data/lib/composite_primary_keys/version.rb +8 -8
  27. data/tasks/databases/sqlserver.rake +40 -27
  28. data/test/connections/databases.example.yml +18 -18
  29. data/test/connections/native_sqlserver/connection.rb +14 -11
  30. data/test/fixtures/db_definitions/mysql.sql +208 -208
  31. data/test/fixtures/db_definitions/postgresql.sql +210 -210
  32. data/test/fixtures/db_definitions/sqlite.sql +197 -197
  33. data/test/fixtures/db_definitions/sqlserver.drop.sql +94 -91
  34. data/test/fixtures/db_definitions/sqlserver.sql +232 -226
  35. data/test/fixtures/employee.rb +5 -5
  36. data/test/test_associations.rb +275 -275
  37. data/test/test_attributes.rb +60 -60
  38. data/test/test_create.rb +112 -112
  39. data/test/test_delete.rb +152 -148
  40. data/test/test_delete_all.rb +21 -21
  41. data/test/test_enum.rb +20 -20
  42. data/test/test_equal.rb +1 -1
  43. data/test/test_tutorial_example.rb +21 -21
  44. metadata +3 -2
@@ -1,52 +1,52 @@
1
- module ActiveRecord
2
- module Sanitization
3
- module ClassMethods
4
- protected
5
- # Accepts a hash of SQL conditions and replaces those attributes
6
- # that correspond to a +composed_of+ relationship with their expanded
7
- # aggregate attribute values.
8
- # Given:
9
- # class Person < ActiveRecord::Base
10
- # composed_of :address, class_name: "Address",
11
- # mapping: [%w(address_street street), %w(address_city city)]
12
- # end
13
- # Then:
14
- # { address: Address.new("813 abc st.", "chicago") }
15
- # # => { address_street: "813 abc st.", address_city: "chicago" }
16
- def expand_hash_conditions_for_aggregates(attrs)
17
- expanded_attrs = {}
18
- attrs.each do |attr, value|
19
- if attr.is_a?(CompositePrimaryKeys::CompositeKeys)
20
- attr.each_with_index do |key,i|
21
- expanded_attrs[key] = value.flatten[i]
22
- end
23
- elsif aggregation = reflect_on_aggregation(attr.to_sym)
24
- mapping = aggregation.mapping
25
- mapping.each do |field_attr, aggregate_attr|
26
- if mapping.size == 1 && !value.respond_to?(aggregate_attr)
27
- expanded_attrs[field_attr] = value
28
- else
29
- expanded_attrs[field_attr] = value.send(aggregate_attr)
30
- end
31
- end
32
- else
33
- expanded_attrs[attr] = value
34
- end
35
- end
36
- expanded_attrs
37
- end
38
-
39
- def quoted_id
40
- # CPK
41
- #quote_value(id, column_for_attribute(self.class.primary_key))
42
- if self.composite?
43
- [self.class.primary_keys, ids].
44
- transpose.
45
- map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
46
- else
47
- quote_value(id, column_for_attribute(self.class.primary_key))
48
- end
49
- end
50
- end
51
- end
52
- end
1
+ module ActiveRecord
2
+ module Sanitization
3
+ module ClassMethods
4
+ protected
5
+ # Accepts a hash of SQL conditions and replaces those attributes
6
+ # that correspond to a +composed_of+ relationship with their expanded
7
+ # aggregate attribute values.
8
+ # Given:
9
+ # class Person < ActiveRecord::Base
10
+ # composed_of :address, class_name: "Address",
11
+ # mapping: [%w(address_street street), %w(address_city city)]
12
+ # end
13
+ # Then:
14
+ # { address: Address.new("813 abc st.", "chicago") }
15
+ # # => { address_street: "813 abc st.", address_city: "chicago" }
16
+ def expand_hash_conditions_for_aggregates(attrs)
17
+ expanded_attrs = {}
18
+ attrs.each do |attr, value|
19
+ if attr.is_a?(CompositePrimaryKeys::CompositeKeys)
20
+ attr.each_with_index do |key,i|
21
+ expanded_attrs[key] = value.flatten[i]
22
+ end
23
+ elsif aggregation = reflect_on_aggregation(attr.to_sym)
24
+ mapping = aggregation.mapping
25
+ mapping.each do |field_attr, aggregate_attr|
26
+ if mapping.size == 1 && !value.respond_to?(aggregate_attr)
27
+ expanded_attrs[field_attr] = value
28
+ else
29
+ expanded_attrs[field_attr] = value.send(aggregate_attr)
30
+ end
31
+ end
32
+ else
33
+ expanded_attrs[attr] = value
34
+ end
35
+ end
36
+ expanded_attrs
37
+ end
38
+
39
+ def quoted_id
40
+ # CPK
41
+ #quote_value(id, column_for_attribute(self.class.primary_key))
42
+ if self.composite?
43
+ [self.class.primary_keys, ids].
44
+ transpose.
45
+ map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
46
+ else
47
+ quote_value(id, column_for_attribute(self.class.primary_key))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,40 +1,38 @@
1
- module ActiveRecord
2
- module Validations
3
- class UniquenessValidator
4
- def validate_each(record, attribute, value)
5
- finder_class = find_finder_class_for(record)
6
- table = finder_class.arel_table
7
-
8
- coder = record.class.serialized_attributes[attribute.to_s]
9
-
10
- if value && coder
11
- value = coder.dump value
12
- end
13
-
14
- relation = build_relation(finder_class, table, attribute, value)
15
- # CPK
16
- # relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.send(:id))) if record.persisted?
17
- if record.persisted?
18
- not_eq_conditions = Array(finder_class.primary_key).zip(Array(record.send(:id))).map do |name, value|
19
- table[name.to_sym].not_eq(value)
20
- end
21
-
22
- condition = not_eq_conditions.shift
23
- not_eq_conditions.each do |not_eq_condition|
24
- condition = condition.or(not_eq_condition)
25
- end
26
- relation = relation.and(condition)
27
- end
28
-
29
- Array.wrap(options[:scope]).each do |scope_item|
30
- scope_value = record.send(scope_item)
31
- relation = relation.and(table[scope_item].eq(scope_value))
32
- end
33
-
34
- if finder_class.unscoped.where(relation).exists?
35
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
36
- end
37
- end
38
- end
39
- end
1
+ module ActiveRecord
2
+ module Validations
3
+ class UniquenessValidator
4
+ def validate_each(record, attribute, value)
5
+ finder_class = find_finder_class_for(record)
6
+ table = finder_class.arel_table
7
+ value = map_enum_attribute(finder_class,attribute,value)
8
+ value = deserialize_attribute(record, attribute, value)
9
+
10
+ relation = build_relation(finder_class, table, attribute, value)
11
+ # CPK
12
+ # relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
13
+ if record.persisted?
14
+ not_eq_conditions = Array(finder_class.primary_key).zip(Array(record.send(:id))).map do |name, value|
15
+ table[name.to_sym].not_eq(value)
16
+ end
17
+
18
+ condition = not_eq_conditions.shift
19
+ not_eq_conditions.each do |not_eq_condition|
20
+ condition = condition.or(not_eq_condition)
21
+ end
22
+ relation = relation.and(condition)
23
+ end
24
+
25
+ relation = scope_relation(record, table, relation)
26
+ relation = finder_class.unscoped.where(relation)
27
+ relation = relation.merge(options[:conditions]) if options[:conditions]
28
+
29
+ if relation.exists?
30
+ error_options = options.except(:case_sensitive, :scope, :conditions)
31
+ error_options[:value] = value
32
+
33
+ record.errors.add(attribute, :taken, error_options)
34
+ end
35
+ end
36
+ end
37
+ end
40
38
  end
@@ -1,8 +1,8 @@
1
- module CompositePrimaryKeys
2
- module VERSION
3
- MAJOR = 7
4
- MINOR = 0
5
- TINY = 13
6
- STRING = [MAJOR, MINOR, TINY].join('.')
7
- end
8
- end
1
+ module CompositePrimaryKeys
2
+ module VERSION
3
+ MAJOR = 7
4
+ MINOR = 0
5
+ TINY = 14
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
+ end
8
+ end
@@ -1,27 +1,40 @@
1
- require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
- require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
-
4
- namespace :sqlserver do
5
- desc 'Build the SQL Server test database'
6
- task :build_database => :load_connection do
7
- options_str = connection_string
8
-
9
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'sqlserver.sql')
10
- sh %( sqsh #{options_str} -i #{schema} )
11
- end
12
-
13
- desc 'Drop the SQL Server test database'
14
- task :drop_database => :load_connection do
15
- options_str = connection_string
16
-
17
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'sqlserver.drop.sql')
18
- sh %( sqsh #{options_str} -i #{schema} )
19
- end
20
-
21
- desc 'Rebuild the SQL Server test database'
22
- task :rebuild_database => [:drop_database, :build_database]
23
-
24
- task :load_connection do
25
- require File.join(PROJECT_ROOT, "test", "connections", "native_sqlserver", "connection")
26
- end
27
- end
1
+ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
+ require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
+
4
+ require 'rbconfig'
5
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
6
+ sql_cmd = "osql"
7
+ else
8
+ sql_cmd = sqsh
9
+ end
10
+
11
+ namespace :sqlserver do
12
+ desc 'Build the SQL Server test database'
13
+ task :build_database => :load_connection do
14
+ options_str = connection_string
15
+
16
+ schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions',
17
+ 'sqlserver.sql').gsub(File::SEPARATOR,
18
+ File::ALT_SEPARATOR ||
19
+ File::SEPARATOR)
20
+ sh %( #{sql_cmd} #{options_str} -i #{schema} )
21
+ end
22
+
23
+ desc 'Drop the SQL Server test database'
24
+ task :drop_database => :load_connection do
25
+ options_str = connection_string
26
+
27
+ schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions',
28
+ 'sqlserver.drop.sql').gsub(File::SEPARATOR,
29
+ File::ALT_SEPARATOR ||
30
+ File::SEPARATOR)
31
+ sh %( #{sql_cmd} #{options_str} -i #{schema} )
32
+ end
33
+
34
+ desc 'Rebuild the SQL Server test database'
35
+ task :rebuild_database => [:drop_database, :build_database]
36
+
37
+ task :load_connection do
38
+ require File.join(PROJECT_ROOT, "test", "connections", "native_sqlserver", "connection")
39
+ end
40
+ end
@@ -1,18 +1,18 @@
1
- # To run tests:
2
- # 1. Copy this file to test/connections/databases.yml.
3
- # 2. Update to match the databases you want to test against.
4
-
5
- mysql:
6
- adapter: mysql2
7
- username: root
8
- database: composite_primary_keys_unittest
9
-
10
- sqlite3:
11
- adapter: sqlite3
12
- database: db/composite_primary_keys_unittest.sqlite
13
-
14
- postgresql:
15
- adapter: postgresql
16
- database: composite_primary_keys_unittest
17
- username: postgres
18
- host: localhost
1
+ # To run tests:
2
+ # 1. Copy this file to test/connections/databases.yml.
3
+ # 2. Update to match the databases you want to test against.
4
+
5
+ mysql:
6
+ adapter: mysql2
7
+ username: root
8
+ database: composite_primary_keys_unittest
9
+
10
+ sqlite3:
11
+ adapter: sqlite3
12
+ database: db/composite_primary_keys_unittest.sqlite
13
+
14
+ postgresql:
15
+ adapter: postgresql
16
+ database: composite_primary_keys_unittest
17
+ username: postgres
18
+ host: localhost
@@ -1,11 +1,14 @@
1
- print "Using native SQL Server\n"
2
-
3
- require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
4
-
5
- def connection_string
6
- "-S #{SPEC['host']} -U #{SPEC['username']} -P\"#{SPEC['password']}\""
7
- end
8
-
9
- # Adapter config setup in locals/database_connections.rb
10
- SPEC = CompositePrimaryKeys::ConnectionSpec['sqlserver']
11
- ActiveRecord::Base.establish_connection(SPEC)
1
+ print "Using native SQL Server\n"
2
+
3
+ gem 'activerecord-sqlserver-adapter', '~>4.1.0'
4
+ require 'activerecord-sqlserver-adapter'
5
+
6
+ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
7
+
8
+ def connection_string
9
+ "-S #{SPEC['host']} -U #{SPEC['username']} -P\"#{SPEC['password']}\""
10
+ end
11
+
12
+ # Adapter config setup in locals/database_connections.rb
13
+ SPEC = CompositePrimaryKeys::ConnectionSpec['sqlserver']
14
+ ActiveRecord::Base.establish_connection(SPEC)
@@ -1,208 +1,208 @@
1
- create table topics (
2
- id int not null auto_increment,
3
- name varchar(50) default null,
4
- feed_size int default null,
5
- primary key (id)
6
- );
7
-
8
- create table topic_sources (
9
- topic_id int not null,
10
- platform varchar(50) not null,
11
- keywords varchar(50) default null,
12
- primary key (topic_id,platform)
13
- );
14
-
15
- create table reference_types (
16
- reference_type_id int not null auto_increment,
17
- type_label varchar(50) default null,
18
- abbreviation varchar(50) default null,
19
- description varchar(50) default null,
20
- primary key (reference_type_id)
21
- );
22
-
23
- create table reference_codes (
24
- reference_type_id int not null,
25
- reference_code int not null,
26
- code_label varchar(50) default null,
27
- abbreviation varchar(50) default null,
28
- description varchar(50) default null,
29
- primary key (reference_type_id, reference_code)
30
- );
31
-
32
- create table products (
33
- id int not null auto_increment,
34
- name varchar(50) default null,
35
- primary key (id)
36
- );
37
-
38
- create table tariffs (
39
- tariff_id int not null,
40
- start_date date not null,
41
- amount integer(11) default null,
42
- created_at timestamp,
43
- updated_at timestamp,
44
- primary key (tariff_id, start_date)
45
- );
46
-
47
- create table product_tariffs (
48
- product_id int not null,
49
- tariff_id int not null,
50
- tariff_start_date date not null,
51
- primary key (product_id, tariff_id, tariff_start_date)
52
- );
53
-
54
- create table suburbs (
55
- city_id int not null,
56
- suburb_id int not null,
57
- name varchar(50) not null,
58
- primary key (city_id, suburb_id)
59
- );
60
-
61
- create table streets (
62
- id int not null auto_increment,
63
- city_id int not null,
64
- suburb_id int not null,
65
- name varchar(50) not null,
66
- primary key (id)
67
- );
68
-
69
- create table users (
70
- id int not null auto_increment,
71
- name varchar(50) not null,
72
- primary key (id)
73
- );
74
-
75
- create table articles (
76
- id int not null auto_increment,
77
- name varchar(50) not null,
78
- primary key (id)
79
- );
80
-
81
- create table readings (
82
- id int not null auto_increment,
83
- user_id int not null,
84
- article_id int not null,
85
- rating int not null,
86
- primary key (id)
87
- );
88
-
89
- create table groups (
90
- id int not null auto_increment,
91
- name varchar(50) not null,
92
- primary key (id)
93
- );
94
-
95
- create table memberships (
96
- user_id int not null,
97
- group_id int not null,
98
- primary key (user_id,group_id)
99
- );
100
-
101
- create table membership_statuses (
102
- id int not null auto_increment,
103
- user_id int not null,
104
- group_id int not null,
105
- status varchar(50) not null,
106
- primary key (id)
107
- );
108
-
109
- create table departments (
110
- department_id int not null,
111
- location_id int not null,
112
- primary key (department_id, location_id)
113
- );
114
-
115
- create table employees (
116
- id int not null auto_increment,
117
- department_id int default null,
118
- location_id int default null,
119
- primary key (id)
120
- );
121
-
122
- create table comments (
123
- id int not null auto_increment,
124
- person_id int default null,
125
- shown int default null,
126
- person_type varchar(100) default null,
127
- hack_id int default null,
128
- primary key (id)
129
- );
130
-
131
- create table hacks (
132
- id int not null auto_increment,
133
- name varchar(50) not null,
134
- primary key (id)
135
- );
136
-
137
- create table restaurants (
138
- franchise_id int not null,
139
- store_id int not null,
140
- name varchar(100),
141
- lock_version int default 0,
142
- primary key (franchise_id, store_id)
143
- );
144
-
145
- create table restaurants_suburbs (
146
- franchise_id int not null,
147
- store_id int not null,
148
- city_id int not null,
149
- suburb_id int not null
150
- );
151
-
152
- create table dorms (
153
- id int not null auto_increment,
154
- primary key(id)
155
- );
156
-
157
- create table rooms (
158
- dorm_id int not null,
159
- room_id int not null,
160
- primary key (dorm_id, room_id)
161
- );
162
-
163
- create table room_attributes (
164
- id int not null auto_increment,
165
- name varchar(50),
166
- primary key(id)
167
- );
168
-
169
- create table room_attribute_assignments (
170
- dorm_id int not null,
171
- room_id int not null,
172
- room_attribute_id int not null
173
- );
174
-
175
- create table students (
176
- id int not null auto_increment,
177
- primary key(id)
178
- );
179
-
180
- create table room_assignments (
181
- student_id int not null,
182
- dorm_id int not null,
183
- room_id int not null
184
- );
185
-
186
- create table seats (
187
- flight_number int not null,
188
- seat int not null,
189
- customer int,
190
- primary key (flight_number, seat)
191
- );
192
-
193
- create table capitols (
194
- country varchar(100) default null,
195
- city varchar(100) default null,
196
- primary key (country, city)
197
- );
198
-
199
- create table products_restaurants (
200
- product_id int not null,
201
- franchise_id int not null,
202
- store_id int not null
203
- );
204
-
205
- create table employees_groups (
206
- employee_id int not null,
207
- group_id int not null
208
- );
1
+ create table topics (
2
+ id int not null auto_increment,
3
+ name varchar(50) default null,
4
+ feed_size int default null,
5
+ primary key (id)
6
+ );
7
+
8
+ create table topic_sources (
9
+ topic_id int not null,
10
+ platform varchar(50) not null,
11
+ keywords varchar(50) default null,
12
+ primary key (topic_id,platform)
13
+ );
14
+
15
+ create table reference_types (
16
+ reference_type_id int not null auto_increment,
17
+ type_label varchar(50) default null,
18
+ abbreviation varchar(50) default null,
19
+ description varchar(50) default null,
20
+ primary key (reference_type_id)
21
+ );
22
+
23
+ create table reference_codes (
24
+ reference_type_id int not null,
25
+ reference_code int not null,
26
+ code_label varchar(50) default null,
27
+ abbreviation varchar(50) default null,
28
+ description varchar(50) default null,
29
+ primary key (reference_type_id, reference_code)
30
+ );
31
+
32
+ create table products (
33
+ id int not null auto_increment,
34
+ name varchar(50) default null,
35
+ primary key (id)
36
+ );
37
+
38
+ create table tariffs (
39
+ tariff_id int not null,
40
+ start_date date not null,
41
+ amount integer(11) default null,
42
+ created_at timestamp,
43
+ updated_at timestamp,
44
+ primary key (tariff_id, start_date)
45
+ );
46
+
47
+ create table product_tariffs (
48
+ product_id int not null,
49
+ tariff_id int not null,
50
+ tariff_start_date date not null,
51
+ primary key (product_id, tariff_id, tariff_start_date)
52
+ );
53
+
54
+ create table suburbs (
55
+ city_id int not null,
56
+ suburb_id int not null,
57
+ name varchar(50) not null,
58
+ primary key (city_id, suburb_id)
59
+ );
60
+
61
+ create table streets (
62
+ id int not null auto_increment,
63
+ city_id int not null,
64
+ suburb_id int not null,
65
+ name varchar(50) not null,
66
+ primary key (id)
67
+ );
68
+
69
+ create table users (
70
+ id int not null auto_increment,
71
+ name varchar(50) not null,
72
+ primary key (id)
73
+ );
74
+
75
+ create table articles (
76
+ id int not null auto_increment,
77
+ name varchar(50) not null,
78
+ primary key (id)
79
+ );
80
+
81
+ create table readings (
82
+ id int not null auto_increment,
83
+ user_id int not null,
84
+ article_id int not null,
85
+ rating int not null,
86
+ primary key (id)
87
+ );
88
+
89
+ create table groups (
90
+ id int not null auto_increment,
91
+ name varchar(50) not null,
92
+ primary key (id)
93
+ );
94
+
95
+ create table memberships (
96
+ user_id int not null,
97
+ group_id int not null,
98
+ primary key (user_id,group_id)
99
+ );
100
+
101
+ create table membership_statuses (
102
+ id int not null auto_increment,
103
+ user_id int not null,
104
+ group_id int not null,
105
+ status varchar(50) not null,
106
+ primary key (id)
107
+ );
108
+
109
+ create table departments (
110
+ department_id int not null,
111
+ location_id int not null,
112
+ primary key (department_id, location_id)
113
+ );
114
+
115
+ create table employees (
116
+ id int not null auto_increment,
117
+ department_id int default null,
118
+ location_id int default null,
119
+ primary key (id)
120
+ );
121
+
122
+ create table comments (
123
+ id int not null auto_increment,
124
+ person_id int default null,
125
+ shown int default null,
126
+ person_type varchar(100) default null,
127
+ hack_id int default null,
128
+ primary key (id)
129
+ );
130
+
131
+ create table hacks (
132
+ id int not null auto_increment,
133
+ name varchar(50) not null,
134
+ primary key (id)
135
+ );
136
+
137
+ create table restaurants (
138
+ franchise_id int not null,
139
+ store_id int not null,
140
+ name varchar(100),
141
+ lock_version int default 0,
142
+ primary key (franchise_id, store_id)
143
+ );
144
+
145
+ create table restaurants_suburbs (
146
+ franchise_id int not null,
147
+ store_id int not null,
148
+ city_id int not null,
149
+ suburb_id int not null
150
+ );
151
+
152
+ create table dorms (
153
+ id int not null auto_increment,
154
+ primary key(id)
155
+ );
156
+
157
+ create table rooms (
158
+ dorm_id int not null,
159
+ room_id int not null,
160
+ primary key (dorm_id, room_id)
161
+ );
162
+
163
+ create table room_attributes (
164
+ id int not null auto_increment,
165
+ name varchar(50),
166
+ primary key(id)
167
+ );
168
+
169
+ create table room_attribute_assignments (
170
+ dorm_id int not null,
171
+ room_id int not null,
172
+ room_attribute_id int not null
173
+ );
174
+
175
+ create table students (
176
+ id int not null auto_increment,
177
+ primary key(id)
178
+ );
179
+
180
+ create table room_assignments (
181
+ student_id int not null,
182
+ dorm_id int not null,
183
+ room_id int not null
184
+ );
185
+
186
+ create table seats (
187
+ flight_number int not null,
188
+ seat int not null,
189
+ customer int,
190
+ primary key (flight_number, seat)
191
+ );
192
+
193
+ create table capitols (
194
+ country varchar(100) default null,
195
+ city varchar(100) default null,
196
+ primary key (country, city)
197
+ );
198
+
199
+ create table products_restaurants (
200
+ product_id int not null,
201
+ franchise_id int not null,
202
+ store_id int not null
203
+ );
204
+
205
+ create table employees_groups (
206
+ employee_id int not null,
207
+ group_id int not null
208
+ );