composite_primary_keys 7.0.13 → 7.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+ );