composite_primary_keys 0.9.0 → 0.9.90

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/History.txt +8 -0
  2. data/Manifest.txt +6 -1
  3. data/lib/adapter_helper/base.rb +2 -2
  4. data/lib/adapter_helper/oracle.rb +0 -1
  5. data/lib/composite_primary_keys.rb +1 -0
  6. data/lib/composite_primary_keys/attribute_methods.rb +84 -0
  7. data/lib/composite_primary_keys/base.rb +5 -41
  8. data/lib/composite_primary_keys/calculations.rb +5 -0
  9. data/lib/composite_primary_keys/connection_adapters/sqlite3_adapter.rb +11 -0
  10. data/lib/composite_primary_keys/migration.rb +8 -1
  11. data/lib/composite_primary_keys/version.rb +1 -1
  12. data/tasks/databases.rake +2 -0
  13. data/tasks/databases/oracle.rake +14 -4
  14. data/test/abstract_unit.rb +1 -5
  15. data/test/connections/native_oracle/connection.rb +2 -1
  16. data/test/fixtures/db_definitions/db2-create-tables.sql +7 -0
  17. data/test/fixtures/db_definitions/db2-drop-tables.sql +1 -0
  18. data/test/fixtures/db_definitions/mysql.sql +12 -4
  19. data/test/fixtures/db_definitions/oracle.drop.sql +2 -1
  20. data/test/fixtures/db_definitions/oracle.sql +8 -0
  21. data/test/fixtures/db_definitions/postgresql.sql +8 -0
  22. data/test/fixtures/db_definitions/sqlite.sql +54 -46
  23. data/test/plugins/pagination.rb +405 -0
  24. data/test/plugins/pagination_helper.rb +135 -0
  25. data/test/test_associations.rb +15 -29
  26. data/test/test_attribute_methods.rb +22 -0
  27. data/test/test_attributes.rb +2 -2
  28. data/test/test_clone.rb +2 -2
  29. data/test/{composite_arrays_test.rb → test_composite_arrays.rb} +45 -45
  30. data/test/test_create.rb +2 -2
  31. data/test/test_delete.rb +3 -3
  32. data/test/test_dummy.rb +2 -2
  33. data/test/test_find.rb +1 -1
  34. data/test/test_ids.rb +1 -1
  35. data/test/test_miscellaneous.rb +1 -1
  36. data/test/test_pagination.rb +3 -2
  37. data/test/test_polymorphic.rb +1 -5
  38. data/test/test_santiago.rb +1 -3
  39. data/test/test_tutorial_examle.rb +1 -4
  40. data/test/test_update.rb +1 -1
  41. data/tmp/test.db +0 -0
  42. data/website/index.html +2 -2
  43. data/website/version-raw.js +1 -1
  44. data/website/version.js +1 -1
  45. metadata +67 -53
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.9.90 2008-01-27
2
+
3
+ * Trial release for rails/activerecord 2.0.2 supported
4
+
5
+ == 0.9.1 2007-10-28
6
+
7
+ * Migrations fix - allow :primary_key => [:name] to work [no unit test] [thx Shugo Maeda]
8
+
1
9
  == 0.9.0 2007-09-28
2
10
 
3
11
  * Added support for polymorphs [thx nerdrew]
data/Manifest.txt CHANGED
@@ -12,12 +12,14 @@ lib/adapter_helper/postgresql.rb
12
12
  lib/adapter_helper/sqlite3.rb
13
13
  lib/composite_primary_keys.rb
14
14
  lib/composite_primary_keys/associations.rb
15
+ lib/composite_primary_keys/attribute_methods.rb
15
16
  lib/composite_primary_keys/base.rb
16
17
  lib/composite_primary_keys/calculations.rb
17
18
  lib/composite_primary_keys/composite_arrays.rb
18
19
  lib/composite_primary_keys/connection_adapters/ibm_db_adapter.rb
19
20
  lib/composite_primary_keys/connection_adapters/oracle_adapter.rb
20
21
  lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb
22
+ lib/composite_primary_keys/connection_adapters/sqlite3_adapter.rb
21
23
  lib/composite_primary_keys/fixtures.rb
22
24
  lib/composite_primary_keys/migration.rb
23
25
  lib/composite_primary_keys/reflection.rb
@@ -40,7 +42,6 @@ tasks/local_setup.rake
40
42
  tasks/website.rake
41
43
  test/README_tests.txt
42
44
  test/abstract_unit.rb
43
- test/composite_arrays_test.rb
44
45
  test/connections/native_ibm_db/connection.rb
45
46
  test/connections/native_mysql/connection.rb
46
47
  test/connections/native_oracle/connection.rb
@@ -88,9 +89,13 @@ test/fixtures/tariffs.yml
88
89
  test/fixtures/user.rb
89
90
  test/fixtures/users.yml
90
91
  test/hash_tricks.rb
92
+ test/plugins/pagination.rb
93
+ test/plugins/pagination_helper.rb
91
94
  test/test_associations.rb
95
+ test/test_attribute_methods.rb
92
96
  test/test_attributes.rb
93
97
  test/test_clone.rb
98
+ test/test_composite_arrays.rb
94
99
  test/test_create.rb
95
100
  test/test_delete.rb
96
101
  test/test_dummy.rb
@@ -10,8 +10,8 @@ module AdapterHelper
10
10
  exit
11
11
  end
12
12
 
13
- all_specs = YAML.load(ENV['cpk_adapters'])
14
- unless spec = all_specs[adapter]
13
+ ActiveRecord::Base.configurations = YAML.load(ENV['cpk_adapters'])
14
+ unless spec = ActiveRecord::Base.configurations[adapter]
15
15
  puts error_msg_adapter_helper
16
16
  exit
17
17
  end
@@ -5,7 +5,6 @@ module AdapterHelper
5
5
  class << self
6
6
  def load_connection_from_env
7
7
  spec = super('oracle')
8
- spec[:database] ||= 'composite_primary_keys_unittest'
9
8
  spec
10
9
  end
11
10
  end
@@ -40,6 +40,7 @@ require 'composite_primary_keys/reflection'
40
40
  require 'composite_primary_keys/base'
41
41
  require 'composite_primary_keys/calculations'
42
42
  require 'composite_primary_keys/migration'
43
+ require 'composite_primary_keys/attribute_methods'
43
44
 
44
45
  ActiveRecord::Base.class_eval do
45
46
  include CompositePrimaryKeys::ActiveRecord::Base
@@ -0,0 +1,84 @@
1
+ module CompositePrimaryKeys
2
+ module ActiveRecord
3
+ module AttributeMethods #:nodoc:
4
+ def self.append_features(base)
5
+ super
6
+ base.send(:extend, ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ # Define an attribute reader method. Cope with nil column.
11
+ def define_read_method(symbol, attr_name, column)
12
+ cast_code = column.type_cast_code('v') if column
13
+ cast_code = "::#{cast_code}" if cast_code && cast_code.match('ActiveRecord::.*')
14
+ access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
15
+
16
+ unless self.primary_keys.include?(attr_name.to_sym)
17
+ access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
18
+ end
19
+
20
+ if cache_attribute?(attr_name)
21
+ access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})"
22
+ end
23
+
24
+ evaluate_attribute_method attr_name, "def #{symbol}; #{access_code}; end"
25
+ end
26
+
27
+ # Evaluate the definition for an attribute related method
28
+ def evaluate_attribute_method(attr_name, method_definition, method_name=attr_name)
29
+ unless primary_keys.include?(method_name.to_sym)
30
+ generated_methods << method_name
31
+ end
32
+
33
+ begin
34
+ class_eval(method_definition, __FILE__, __LINE__)
35
+ rescue SyntaxError => err
36
+ generated_methods.delete(attr_name)
37
+ if logger
38
+ logger.warn "Exception occurred during reader method compilation."
39
+ logger.warn "Maybe #{attr_name} is not a valid Ruby identifier?"
40
+ logger.warn "#{err.message}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ # Allows access to the object attributes, which are held in the @attributes hash, as though they
47
+ # were first-class methods. So a Person class with a name attribute can use Person#name and
48
+ # Person#name= and never directly use the attributes hash -- except for multiple assigns with
49
+ # ActiveRecord#attributes=. A Milestone class can also ask Milestone#completed? to test that
50
+ # the completed attribute is not nil or 0.
51
+ #
52
+ # It's also possible to instantiate related objects, so a Client class belonging to the clients
53
+ # table with a master_id foreign key can instantiate master through Client#master.
54
+ def method_missing(method_id, *args, &block)
55
+ method_name = method_id.to_s
56
+
57
+ # If we haven't generated any methods yet, generate them, then
58
+ # see if we've created the method we're looking for.
59
+ if !self.class.generated_methods?
60
+ self.class.define_attribute_methods
61
+
62
+ if self.class.generated_methods.include?(method_name)
63
+ return self.send(method_id, *args, &block)
64
+ end
65
+ end
66
+
67
+ if self.class.primary_keys.include?(method_name.to_sym)
68
+ ids[self.class.primary_keys.index(method_name.to_sym)]
69
+ elsif md = self.class.match_attribute_method?(method_name)
70
+ attribute_name, method_type = md.pre_match, md.to_s
71
+ if @attributes.include?(attribute_name)
72
+ __send__("attribute#{method_type}", attribute_name, *args, &block)
73
+ else
74
+ super
75
+ end
76
+ elsif @attributes.include?(method_name)
77
+ read_attribute(method_name)
78
+ else
79
+ super
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -22,10 +22,12 @@ module CompositePrimaryKeys
22
22
  self.primary_keys = keys.to_composite_keys
23
23
 
24
24
  class_eval <<-EOV
25
- extend CompositePrimaryKeys::ActiveRecord::Base::CompositeClassMethods
26
- include CompositePrimaryKeys::ActiveRecord::Base::CompositeInstanceMethods
25
+ extend CompositeClassMethods
26
+ include CompositeInstanceMethods
27
+
27
28
  include CompositePrimaryKeys::ActiveRecord::Associations
28
- extend CompositePrimaryKeys::ActiveRecord::Calculations::ClassMethods
29
+ include CompositePrimaryKeys::ActiveRecord::Calculations
30
+ include CompositePrimaryKeys::ActiveRecord::AttributeMethods
29
31
  EOV
30
32
  end
31
33
 
@@ -89,44 +91,6 @@ module CompositePrimaryKeys
89
91
  end
90
92
  end
91
93
 
92
- # Define an attribute reader method. Cope with nil column.
93
- def define_read_method(symbol, attr_name, column)
94
- cast_code = column.type_cast_code('v') if column
95
- access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
96
-
97
- unless self.class.primary_keys.include? attr_name.to_sym
98
- access_code = access_code.insert(0, "raise NoMethodError, 'missing attribute: #{attr_name}', caller unless @attributes.has_key?('#{attr_name}'); ")
99
- self.class.read_methods << attr_name
100
- end
101
-
102
- evaluate_read_method attr_name, "def #{symbol}; #{access_code}; end"
103
- end
104
-
105
- def method_missing(method_id, *args, &block)
106
- method_name = method_id.to_s
107
- if @attributes.include?(method_name) or
108
- (md = /\?$/.match(method_name) and
109
- @attributes.include?(method_name = md.pre_match))
110
- define_read_methods if self.class.read_methods.empty? && self.class.generate_read_methods
111
- md ? query_attribute(method_name) : read_attribute(method_name)
112
- elsif self.class.primary_keys.include? method_name.to_sym
113
- get_attr(method_name.to_sym)
114
- elsif md = /(=|_before_type_cast)$/.match(method_name)
115
- attribute_name, method_type = md.pre_match, md.to_s
116
- if @attributes.include?(attribute_name)
117
- case method_type
118
- when '='
119
- write_attribute(attribute_name, args.first)
120
- when '_before_type_cast'
121
- read_attribute_before_type_cast(attribute_name)
122
- end
123
- else
124
- super
125
- end
126
- else
127
- super
128
- end
129
- end
130
94
 
131
95
  private
132
96
  # The xx_without_callbacks methods are overwritten as that is the end of the alias chain
@@ -1,6 +1,11 @@
1
1
  module CompositePrimaryKeys
2
2
  module ActiveRecord
3
3
  module Calculations
4
+ def self.append_features(base)
5
+ super
6
+ base.send(:extend, ClassMethods)
7
+ end
8
+
4
9
  module ClassMethods
5
10
  def construct_calculation_sql(operation, column_name, options) #:nodoc:
6
11
  operation = operation.to_s.downcase
@@ -0,0 +1,11 @@
1
+ require 'active_record/connection_adapters/sqlite_adapter'
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters #:nodoc:
5
+ class SQLite3Adapter < SQLiteAdapter # :nodoc:
6
+ def supports_count_distinct? #:nodoc:
7
+ false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -10,4 +10,11 @@ ActiveRecord::ConnectionAdapters::ColumnDefinition.class_eval <<-'EOF'
10
10
  end
11
11
  EOF
12
12
 
13
-
13
+ ActiveRecord::ConnectionAdapters::TableDefinition.class_eval <<-'EOF'
14
+ def [](name)
15
+ @columns.find { |column|
16
+ !column.name.is_a?(Array) && column.name.to_s == name.to_s
17
+ }
18
+ end
19
+ EOF
20
+
@@ -2,7 +2,7 @@ module CompositePrimaryKeys
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 0
5
+ TINY = 90
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/tasks/databases.rake CHANGED
@@ -1,3 +1,5 @@
1
+ require 'active_record'
2
+
1
3
  # UNTESTED - firebird sqlserver sqlserver_odbc db2 sybase openbase
2
4
  for adapter in %w( mysql sqlite oracle postgresql ibm_db )
3
5
  Rake::TestTask.new("test_#{adapter}") { |t|
@@ -1,15 +1,25 @@
1
1
  namespace :oracle do
2
2
  desc 'Build the Oracle test databases'
3
- task :build_databases do
3
+ task :build_databases => :load_connection do
4
4
  puts File.join(SCHEMA_PATH, 'oracle.sql')
5
- sh %( sqlplus holstdl/holstdl@test < #{File.join(SCHEMA_PATH, 'oracle.sql')} )
5
+ options_str = ENV['cpk_adapter_options_str']
6
+ sh %( sqlplus #{options_str} < #{File.join(SCHEMA_PATH, 'oracle.sql')} )
6
7
  end
7
8
 
8
9
  desc 'Drop the Oracle test databases'
9
- task :drop_databases do
10
- sh %( sqlplus holstdl/holstdl@test < #{File.join(SCHEMA_PATH, 'oracle.drop.sql')} )
10
+ task :drop_databases => :load_connection do
11
+ puts File.join(SCHEMA_PATH, 'oracle.drop.sql')
12
+ options_str = ENV['cpk_adapter_options_str']
13
+ sh %( sqlplus #{options_str} < #{File.join(SCHEMA_PATH, 'oracle.drop.sql')} )
11
14
  end
12
15
 
13
16
  desc 'Rebuild the Oracle test databases'
14
17
  task :rebuild_databases => [:drop_databases, :build_databases]
18
+
19
+ task :load_connection do
20
+ require File.join(PROJECT_ROOT, %w[lib adapter_helper oracle])
21
+ spec = AdapterHelper::Oracle.load_connection_from_env
22
+ ENV['cpk_adapter_options_str'] = "#{spec[:username]}/#{spec[:password]}@#{spec[:host]}"
23
+ end
24
+
15
25
  end
@@ -18,12 +18,8 @@ QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Obj
18
18
  class Test::Unit::TestCase #:nodoc:
19
19
  self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
20
20
  self.use_instantiated_fixtures = false
21
- self.use_transactional_fixtures = true #(ENV['AR_NO_TX_FIXTURES'] != "yes")
21
+ self.use_transactional_fixtures = true
22
22
 
23
- def create_fixtures(*table_names, &block)
24
- Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, {}, &block)
25
- end
26
-
27
23
  def assert_date_from_db(expected, actual, message = nil)
28
24
  # SQL Server doesn't have a separate column type just for dates,
29
25
  # so the time is in the string and incorrectly formatted
@@ -9,5 +9,6 @@ puts "Logging to #{log_path}/debug.log"
9
9
  ActiveRecord::Base.logger = Logger.new("#{log_path}/debug.log")
10
10
 
11
11
  # Adapter config setup in locals/database_connections.rb
12
- connection_options = AdapterHelper::MySQL.load_connection_from_env
12
+ connection_options = AdapterHelper::Oracle.load_connection_from_env
13
+ puts connection_options.inspect
13
14
  ActiveRecord::Base.establish_connection(connection_options)
@@ -90,3 +90,10 @@ CREATE TABLE membership_statuses (
90
90
  PRIMARY KEY (id)
91
91
  );
92
92
 
93
+ create table kitchen_sinks (
94
+ id_1 integer not null,
95
+ id_2 integer not null,
96
+ a_date date,
97
+ a_string varchar(100),
98
+ primary key (id_1, id_2)
99
+ );
@@ -11,3 +11,4 @@ drop table PRODUCTS;
11
11
  drop table USERS;
12
12
  drop table SUBURBS;
13
13
  drop table PRODUCT_TARIFFS;
14
+ drop table KITCHEN_SINK;
@@ -94,23 +94,31 @@ CREATE TABLE departments (
94
94
  department_id int(11) NOT NULL,
95
95
  location_id int(11) NOT NULL,
96
96
  PRIMARY KEY (department_id, location_id)
97
- );
97
+ ) TYPE=InnoDB;
98
98
 
99
99
  CREATE TABLE employees (
100
100
  id int(11) NOT NULL auto_increment,
101
101
  department_id int(11) DEFAULT NULL,
102
102
  location_id int(11) DEFAULT NULL,
103
103
  PRIMARY KEY (id)
104
- );
104
+ ) TYPE=InnoDB;
105
105
 
106
106
  CREATE TABLE comments (
107
107
  id int(11) NOT NULL auto_increment,
108
108
  person_id varchar(100) DEFAULT NULL,
109
109
  person_type varchar(100) DEFAULT NULL,
110
110
  PRIMARY KEY (id)
111
- );
111
+ ) TYPE=InnoDB;
112
112
 
113
113
  CREATE TABLE hacks (
114
114
  name varchar(50) NOT NULL,
115
115
  PRIMARY KEY (name)
116
- );
116
+ ) TYPE=InnoDB;
117
+
118
+ create table kitchen_sinks (
119
+ id_1 int(11) not null,
120
+ id_2 int(11) not null,
121
+ a_date date,
122
+ a_string varchar(100),
123
+ primary key (id_1, id_2)
124
+ ) TYPE=InnoDB
@@ -24,4 +24,5 @@ drop table employees;
24
24
  drop sequence employees_seq;
25
25
  drop table comments;
26
26
  drop sequence comments_seq;
27
- drop table hacks;
27
+ drop table hacks;
28
+ drop table kitchen_sinks;
@@ -135,4 +135,12 @@ create sequence comments_seq
135
135
 
136
136
  CREATE TABLE hacks (
137
137
  name varchar(50) NOT NULL PRIMARY KEY
138
+ );
139
+
140
+ create table kitchen_sinks (
141
+ id_1 number(11) not null,
142
+ id_2 number(11) not null,
143
+ a_date date,
144
+ a_string varchar(100),
145
+ constraint kitchen_sinks_pk primary key(id_1, id_2)
138
146
  );
@@ -121,4 +121,12 @@ CREATE TABLE comments (
121
121
  CREATE TABLE hacks (
122
122
  name varchar(50) NOT NULL,
123
123
  PRIMARY KEY (name)
124
+ );
125
+
126
+ create table kitchen_sinks (
127
+ id_1 int not null,
128
+ id_2 int not null,
129
+ a_date date,
130
+ a_string varchar(100),
131
+ primary key (id_1, id_2)
124
132
  );
@@ -1,67 +1,67 @@
1
- CREATE TABLE `reference_types` (
2
- `reference_type_id` INTEGER PRIMARY KEY,
3
- `type_label` varchar(50) default NULL,
4
- `abbreviation` varchar(50) default NULL,
5
- `description` varchar(50) default NULL
1
+ CREATE TABLE reference_types (
2
+ reference_type_id INTEGER PRIMARY KEY,
3
+ type_label varchar(50) default NULL,
4
+ abbreviation varchar(50) default NULL,
5
+ description varchar(50) default NULL
6
6
  );
7
7
 
8
- CREATE TABLE `reference_codes` (
9
- `reference_type_id` int(11) NOT NULL,
10
- `reference_code` int(11) NOT NULL,
11
- `code_label` varchar(50) default NULL,
12
- `abbreviation` varchar(50) default NULL,
13
- `description` varchar(50) default NULL,
14
- PRIMARY KEY (`reference_type_id`,`reference_code`)
8
+ CREATE TABLE reference_codes (
9
+ reference_type_id int(11) NOT NULL,
10
+ reference_code int(11) NOT NULL,
11
+ code_label varchar(50) default NULL,
12
+ abbreviation varchar(50) default NULL,
13
+ description varchar(50) default NULL,
14
+ PRIMARY KEY (reference_type_id,reference_code)
15
15
  );
16
16
 
17
- CREATE TABLE `products` (
18
- `id` int(11) NOT NULL PRIMARY KEY,
19
- `name` varchar(50) default NULL
17
+ CREATE TABLE products (
18
+ id int(11) NOT NULL PRIMARY KEY,
19
+ name varchar(50) default NULL
20
20
  );
21
21
 
22
- CREATE TABLE `tariffs` (
23
- `tariff_id` int(11) NOT NULL,
24
- `start_date` date NOT NULL,
25
- `amount` integer(11) default NULL,
26
- PRIMARY KEY (`tariff_id`,`start_date`)
22
+ CREATE TABLE tariffs (
23
+ tariff_id int(11) NOT NULL,
24
+ start_date date NOT NULL,
25
+ amount integer(11) default NULL,
26
+ PRIMARY KEY (tariff_id,start_date)
27
27
  );
28
28
 
29
- CREATE TABLE `product_tariffs` (
30
- `product_id` int(11) NOT NULL,
31
- `tariff_id` int(11) NOT NULL,
32
- `tariff_start_date` date NOT NULL,
33
- PRIMARY KEY (`product_id`,`tariff_id`,`tariff_start_date`)
29
+ CREATE TABLE product_tariffs (
30
+ product_id int(11) NOT NULL,
31
+ tariff_id int(11) NOT NULL,
32
+ tariff_start_date date NOT NULL,
33
+ PRIMARY KEY (product_id,tariff_id,tariff_start_date)
34
34
  );
35
35
 
36
- CREATE TABLE `suburbs` (
37
- `city_id` int(11) NOT NULL,
38
- `suburb_id` int(11) NOT NULL,
39
- `name` varchar(50) NOT NULL,
40
- PRIMARY KEY (`city_id`,`suburb_id`)
36
+ CREATE TABLE suburbs (
37
+ city_id int(11) NOT NULL,
38
+ suburb_id int(11) NOT NULL,
39
+ name varchar(50) NOT NULL,
40
+ PRIMARY KEY (city_id,suburb_id)
41
41
  );
42
42
 
43
- CREATE TABLE `streets` (
44
- `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
45
- `city_id` int(11) NOT NULL,
46
- `suburb_id` int(11) NOT NULL,
47
- `name` varchar(50) NOT NULL
43
+ CREATE TABLE streets (
44
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
45
+ city_id int(11) NOT NULL,
46
+ suburb_id int(11) NOT NULL,
47
+ name varchar(50) NOT NULL
48
48
  );
49
49
 
50
- CREATE TABLE `users` (
51
- `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
52
- `name` varchar(50) NOT NULL
50
+ CREATE TABLE users (
51
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
52
+ name varchar(50) NOT NULL
53
53
  );
54
54
 
55
- CREATE TABLE `articles` (
56
- `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
57
- `name` varchar(50) NOT NULL
55
+ CREATE TABLE articles (
56
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
57
+ name varchar(50) NOT NULL
58
58
  );
59
59
 
60
- CREATE TABLE `readings` (
61
- `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
62
- `user_id` int(11) NOT NULL,
63
- `article_id` int(11) NOT NULL,
64
- `rating` int(11) NOT NULL
60
+ CREATE TABLE readings (
61
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
62
+ user_id int(11) NOT NULL,
63
+ article_id int(11) NOT NULL,
64
+ rating int(11) NOT NULL
65
65
  );
66
66
 
67
67
  CREATE TABLE groups (
@@ -102,4 +102,12 @@ CREATE TABLE comments (
102
102
 
103
103
  CREATE TABLE hacks (
104
104
  name varchar(50) NOT NULL PRIMARY KEY
105
+ );
106
+
107
+ create table kitchen_sinks (
108
+ id_1 integer not null,
109
+ id_2 integer not null,
110
+ a_date date,
111
+ a_string varchar(100),
112
+ primary key (id_1, id_2)
105
113
  );