Skip to content
This repository
Browse code

Added OpenBase database adapter that builds on top of the http://www.…

…spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported (closes #3528) [derrickspell@cdmplus.com]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3932 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 416385a09d61758ba8e2b2ff30dd64c8b9540883 1 parent 2402131
David Heinemeier Hansson authored March 18, 2006
2  activerecord/CHANGELOG
... ...
@@ -1,5 +1,7 @@
1 1
 *SVN*
2 2
 
  3
+* Added OpenBase database adapter that builds on top of the http://www.spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported #3528 [derrickspell@cdmplus.com]
  4
+
3 5
 * Rework table aliasing to account for truncated table aliases.  Add smarter table aliasing when doing eager loading of STI associations. This allows you to use the association name in the order/where clause. [Jonathan Viney / Rick Olson] #4108 Example (SpecialComment is using STI):
4 6
 
5 7
     Author.find(:all, :include => { :posts => :special_comments }, :order => 'special_comments.body')
2  activerecord/Rakefile
@@ -27,7 +27,7 @@ task :default => [ :test_mysql, :test_sqlite, :test_postgresql ]
27 27
 
28 28
 # Run the unit tests
29 29
 
30  
-for adapter in %w( mysql postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oracle sybase )
  30
+for adapter in %w( mysql postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oracle sybase openbase )
31 31
   Rake::TestTask.new("test_#{adapter}") { |t|
32 32
     t.libs << "test" << "test/connections/native_#{adapter}"
33 33
     t.pattern = "test/*_test{,_#{adapter}}.rb"
2  activerecord/lib/active_record.rb
@@ -68,7 +68,7 @@
68 68
 end
69 69
 
70 70
 unless defined?(RAILS_CONNECTION_ADAPTERS)
71  
-  RAILS_CONNECTION_ADAPTERS = %w(mysql postgresql sqlite firebird sqlserver db2 oracle sybase)
  71
+  RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase )
72 72
 end
73 73
 
74 74
 RAILS_CONNECTION_ADAPTERS.each do |adapter|
349  activerecord/lib/active_record/connection_adapters/openbase_adapter.rb
... ...
@@ -0,0 +1,349 @@
  1
+require 'active_record/connection_adapters/abstract_adapter'
  2
+
  3
+module ActiveRecord
  4
+  class Base
  5
+    # Establishes a connection to the database that's used by all Active Record objects
  6
+    def self.openbase_connection(config) # :nodoc:
  7
+      require_library_or_gem 'openbase' unless self.class.const_defined?(:OpenBase)
  8
+
  9
+      config = config.symbolize_keys
  10
+      host     = config[:host]
  11
+      username = config[:username].to_s
  12
+      password = config[:password].to_s
  13
+      
  14
+
  15
+      if config.has_key?(:database)
  16
+        database = config[:database]
  17
+      else
  18
+        raise ArgumentError, "No database specified. Missing argument: database."
  19
+      end
  20
+
  21
+      oba = ConnectionAdapters::OpenBaseAdapter.new(
  22
+        OpenBase.new(database, host, username, password), logger
  23
+      )
  24
+      
  25
+      oba
  26
+    end
  27
+    
  28
+  end
  29
+
  30
+  module ConnectionAdapters
  31
+    class OpenBaseColumn < Column #:nodoc:
  32
+      private
  33
+        def simplified_type(field_type)
  34
+          return :integer if field_type.downcase =~ /long/
  35
+          return :float   if field_type.downcase == "money"
  36
+          return :binary  if field_type.downcase == "object"
  37
+          super
  38
+        end
  39
+    end
  40
+    # The OpenBase adapter works with the Ruby/Openbase driver by Tetsuya Suzuki.
  41
+    # http://www.spice-of-life.net/ruby-openbase/ (needs version 0.7.3+)
  42
+    #
  43
+    # Options:
  44
+    #
  45
+    # * <tt>:host</tt> -- Defaults to localhost
  46
+    # * <tt>:username</tt> -- Defaults to nothing
  47
+    # * <tt>:password</tt> -- Defaults to nothing
  48
+    # * <tt>:database</tt> -- The name of the database. No default, must be provided.
  49
+    #
  50
+    # The OpenBase adapter will make use of OpenBase's ability to generate unique ids
  51
+    # for any column with an unique index applied.  Thus, if the value of a primary
  52
+    # key is not specified at the time an INSERT is performed, the adapter will prefetch
  53
+    # a unique id for the primary key.  This prefetching is also necessary in order 
  54
+    # to return the id after an insert.
  55
+    #
  56
+    # Caveat: Operations involving LIMIT and OFFSET do not yet work!
  57
+    #
  58
+    # Maintainer: derrickspell@cdmplus.com
  59
+    class OpenBaseAdapter < AbstractAdapter
  60
+      def adapter_name
  61
+        'OpenBase'
  62
+      end
  63
+      
  64
+      def native_database_types
  65
+        {
  66
+          :primary_key => "integer UNIQUE INDEX DEFAULT _rowid",
  67
+          :string      => { :name => "char", :limit => 4096 },
  68
+          :text        => { :name => "text" },
  69
+          :integer     => { :name => "integer" },
  70
+          :float       => { :name => "float" },
  71
+          :datetime    => { :name => "datetime" },
  72
+          :timestamp   => { :name => "timestamp" },
  73
+          :time        => { :name => "time" },
  74
+          :date        => { :name => "date" },
  75
+          :binary      => { :name => "object" },
  76
+          :boolean     => { :name => "boolean" }
  77
+        }
  78
+      end
  79
+      
  80
+      def supports_migrations?
  81
+        false
  82
+      end      
  83
+      
  84
+      def prefetch_primary_key?(table_name = nil)
  85
+        true
  86
+      end
  87
+      
  88
+      def default_sequence_name(table_name, primary_key) # :nodoc:
  89
+        "#{table_name} #{primary_key}"
  90
+      end
  91
+      
  92
+      def next_sequence_value(sequence_name)
  93
+        ary = sequence_name.split(' ')
  94
+        if (!ary[1]) then
  95
+          ary[0] =~ /(\w+)_nonstd_seq/
  96
+          ary[0] = $1
  97
+        end
  98
+        @connection.unique_row_id(ary[0], ary[1])
  99
+      end
  100
+
  101
+      
  102
+      # QUOTING ==================================================
  103
+      
  104
+      def quote(value, column = nil)
  105
+        if value.kind_of?(String) && column && column.type == :binary
  106
+          "'#{@connection.insert_binary(value)}'"
  107
+        else
  108
+          super
  109
+        end
  110
+      end
  111
+      
  112
+      def quoted_true
  113
+        "1"
  114
+      end
  115
+      
  116
+      def quoted_false
  117
+        "0"
  118
+      end
  119
+      
  120
+
  121
+
  122
+      # DATABASE STATEMENTS ======================================
  123
+
  124
+      def add_limit_offset!(sql, options) #:nodoc
  125
+        if limit = options[:limit]
  126
+          unless offset = options[:offset]
  127
+            sql << " RETURN RESULTS #{limit}"
  128
+          else
  129
+            limit = limit + offset
  130
+            sql << " RETURN RESULTS #{offset} TO #{limit}"
  131
+          end
  132
+        end
  133
+      end
  134
+      
  135
+      def select_all(sql, name = nil) #:nodoc:
  136
+        select(sql, name)
  137
+      end
  138
+
  139
+      def select_one(sql, name = nil) #:nodoc:
  140
+        add_limit_offset!(sql,{:limit => 1})
  141
+        results = select(sql, name)
  142
+        results.first if results
  143
+      end
  144
+
  145
+      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
  146
+        execute(sql, name)
  147
+        update_nulls_after_insert(sql, name, pk, id_value, sequence_name)
  148
+        id_value
  149
+      end
  150
+      
  151
+      def execute(sql, name = nil) #:nodoc:
  152
+        log(sql, name) { @connection.execute(sql) }
  153
+      end
  154
+
  155
+      def update(sql, name = nil) #:nodoc:
  156
+        execute(sql, name).rows_affected
  157
+      end
  158
+
  159
+      alias_method :delete, :update #:nodoc:
  160
+#=begin
  161
+      def begin_db_transaction #:nodoc:
  162
+        execute "START TRANSACTION"
  163
+      rescue Exception
  164
+        # Transactions aren't supported
  165
+      end
  166
+
  167
+      def commit_db_transaction #:nodoc:
  168
+        execute "COMMIT"
  169
+      rescue Exception
  170
+        # Transactions aren't supported
  171
+      end
  172
+
  173
+      def rollback_db_transaction #:nodoc:
  174
+        execute "ROLLBACK"
  175
+      rescue Exception
  176
+        # Transactions aren't supported
  177
+      end
  178
+#=end      
  179
+
  180
+      # SCHEMA STATEMENTS ========================================
  181
+
  182
+      # Return the list of all tables in the schema search path.
  183
+      def tables(name = nil) #:nodoc:
  184
+        tables = @connection.tables
  185
+        tables.reject! { |t| /\A_SYS_/ === t }
  186
+        tables
  187
+      end
  188
+
  189
+      def columns(table_name, name = nil) #:nodoc:
  190
+        sql = "SELECT * FROM _sys_tables "
  191
+        sql << "WHERE tablename='#{table_name}' AND INDEXOF(fieldname,'_')<>0 "
  192
+        sql << "ORDER BY columnNumber"
  193
+        columns = []
  194
+        select_all(sql, name).each do |row|
  195
+          columns << OpenBaseColumn.new(row["fieldname"],
  196
+                                default_value(row["defaultvalue"]),
  197
+                                sql_type_name(row["typename"],row["length"]),
  198
+                                row["notnull"]
  199
+                                )
  200
+    #      breakpoint() if row["fieldname"] == "content"
  201
+        end
  202
+        columns
  203
+      end
  204
+
  205
+      def indexes(table_name, name = nil)#:nodoc:
  206
+        sql = "SELECT fieldname, notnull, searchindex, uniqueindex, clusteredindex FROM _sys_tables "
  207
+        sql << "WHERE tablename='#{table_name}' AND INDEXOF(fieldname,'_')<>0 "
  208
+        sql << "AND primarykey=0 "
  209
+        sql << "AND (searchindex=1 OR uniqueindex=1 OR clusteredindex=1) "
  210
+        sql << "ORDER BY columnNumber"
  211
+        indexes = []
  212
+        execute(sql, name).each do |row|
  213
+          indexes << IndexDefinition.new(table_name,index_name(row),row[3]==1,[row[0]])
  214
+        end
  215
+        indexes
  216
+      end
  217
+
  218
+
  219
+      private
  220
+        def select(sql, name = nil)
  221
+          sql = translate_sql(sql)
  222
+          results = execute(sql, name)
  223
+
  224
+          date_cols = []
  225
+          col_names = []
  226
+          results.column_infos.each do |info|
  227
+            col_names << info.name
  228
+            date_cols << info.name if info.type == "date"
  229
+          end
  230
+          
  231
+          rows = []
  232
+          if ( results.rows_affected )
  233
+            results.each do |row|  # loop through result rows
  234
+              hashed_row = {}
  235
+              row.each_index do |index| 
  236
+                hashed_row["#{col_names[index]}"] = row[index] unless col_names[index] == "_rowid"
  237
+              end
  238
+              date_cols.each do |name|
  239
+                unless hashed_row["#{name}"].nil? or hashed_row["#{name}"].empty?
  240
+                  hashed_row["#{name}"] = Date.parse(hashed_row["#{name}"],false).to_s
  241
+                end
  242
+              end
  243
+              rows << hashed_row
  244
+            end
  245
+          end
  246
+          rows
  247
+        end
  248
+        
  249
+        def default_value(value)
  250
+          # Boolean type values
  251
+          return true if value =~ /true/
  252
+          return false if value =~ /false/
  253
+ 
  254
+          # Date / Time magic values
  255
+          return Time.now.to_s if value =~ /^now\(\)/i
  256
+ 
  257
+          # Empty strings should be set to null
  258
+          return nil if value.empty?
  259
+          
  260
+          # Otherwise return what we got from OpenBase
  261
+          # and hope for the best...
  262
+          return value
  263
+        end 
  264
+        
  265
+        def sql_type_name(type_name, length)
  266
+          return "#{type_name}(#{length})" if ( type_name =~ /char/ )
  267
+          type_name
  268
+        end
  269
+                
  270
+        def index_name(row = [])
  271
+          name = ""
  272
+          name << "UNIQUE " if row[3]
  273
+          name << "CLUSTERED " if row[4]
  274
+          name << "INDEX"
  275
+          name
  276
+        end
  277
+        
  278
+        def translate_sql(sql)
  279
+          
  280
+          # Change table.* to list of columns in table
  281
+          while (sql =~ /SELECT.*\s(\w+)\.\*/)
  282
+            table = $1
  283
+            cols = columns(table)
  284
+            if ( cols.size == 0 ) then
  285
+              # Maybe this is a table alias
  286
+              sql =~ /FROM(.+?)(?:LEFT|OUTER|JOIN|WHERE|GROUP|HAVING|ORDER|RETURN|$)/  
  287
+              $1 =~ /[\s|,](\w+)\s+#{table}[\s|,]/ # get the tablename for this alias
  288
+              cols = columns($1)
  289
+            end
  290
+            select_columns = []
  291
+            cols.each do |col|
  292
+              select_columns << table + '.' + col.name
  293
+            end
  294
+            sql.gsub!(table + '.*',select_columns.join(", ")) if select_columns
  295
+          end
  296
+   
  297
+          # Change JOIN clause to table list and WHERE condition
  298
+          while (sql =~ /JOIN/)
  299
+            sql =~ /((LEFT )?(OUTER )?JOIN (\w+) ON )(.+?)(?:LEFT|OUTER|JOIN|WHERE|GROUP|HAVING|ORDER|RETURN|$)/
  300
+            join_clause = $1 + $5
  301
+            is_outer_join = $3
  302
+            join_table = $4
  303
+            join_condition = $5
  304
+            join_condition.gsub!(/=/,"*") if is_outer_join
  305
+            if (sql =~ /WHERE/)
  306
+              sql.gsub!(/WHERE/,"WHERE (#{join_condition}) AND")
  307
+            else
  308
+              sql.gsub!(join_clause,"#{join_clause} WHERE #{join_condition}")
  309
+            end
  310
+            sql =~ /(FROM .+?)(?:LEFT|OUTER|JOIN|WHERE|$)/
  311
+            from_clause = $1
  312
+            sql.gsub!(from_clause,"#{from_clause}, #{join_table} ")
  313
+            sql.gsub!(join_clause,"")
  314
+          end
  315
+    
  316
+          # ORDER BY _rowid if no explicit ORDER BY
  317
+          # This will ensure that find(:first) returns the first inserted row
  318
+          if (sql !~ /(ORDER BY)|(GROUP BY)/)
  319
+            if (sql =~ /RETURN RESULTS/)
  320
+              sql.sub!(/RETURN RESULTS/,"ORDER BY _rowid RETURN RESULTS")
  321
+            else
  322
+              sql << " ORDER BY _rowid"
  323
+            end
  324
+          end
  325
+          
  326
+          sql
  327
+        end
  328
+        
  329
+        def update_nulls_after_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
  330
+          sql =~ /INSERT INTO (\w+) \((.*)\) VALUES\s*\((.*)\)/m
  331
+          table = $1
  332
+          cols = $2
  333
+          values = $3
  334
+          cols = cols.split(',')
  335
+          values.gsub!(/'[^']*'/,"''")
  336
+          values.gsub!(/"[^"]*"/,"\"\"")
  337
+          values = values.split(',')
  338
+          update_cols = []
  339
+          values.each_index { |index| update_cols << cols[index] if values[index] =~ /\s*NULL\s*/ }
  340
+          update_sql = "UPDATE #{table} SET"
  341
+          update_cols.each { |col| update_sql << " #{col}=NULL," unless col.empty? }
  342
+          update_sql.chop!()
  343
+          update_sql << " WHERE #{pk}=#{quote(id_value)}"
  344
+          execute(update_sql, name + " NULL Correction") if update_cols.size > 0
  345
+        end
  346
+        
  347
+      end
  348
+  end
  349
+end
22  activerecord/test/aaa_create_tables_test.rb
@@ -32,11 +32,23 @@ def recreate(base, suffix = nil)
32 32
     end
33 33
 
34 34
     def execute_sql_file(path, connection)
35  
-      File.read(path).split(';').each_with_index do |sql, i|
36  
-        begin
37  
-          connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank?
38  
-        rescue ActiveRecord::StatementInvalid
39  
-          #$stderr.puts "warning: #{$!}"
  35
+      # OpenBase has a different format for sql files
  36
+      if current_adapter?(:OpenBaseAdapter) then
  37
+          File.read(path).split("go").each_with_index do |sql, i|
  38
+            begin
  39
+              # OpenBase does not support comments embedded in sql
  40
+              connection.execute(sql,"SQL statement ##{i}") unless sql.blank?
  41
+            rescue ActiveRecord::StatementInvalid
  42
+              #$stderr.puts "warning: #{$!}"
  43
+            end
  44
+          end
  45
+      else
  46
+        File.read(path).split(';').each_with_index do |sql, i|
  47
+          begin
  48
+            connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank?
  49
+          rescue ActiveRecord::StatementInvalid
  50
+            #$stderr.puts "warning: #{$!}"
  51
+          end
40 52
         end
41 53
       end
42 54
     end
5  activerecord/test/adapter_test.rb
@@ -27,7 +27,9 @@ def test_indexes
27 27
       @connection.add_index :accounts, :firm_id, :name => idx_name
28 28
       indexes = @connection.indexes("accounts")
29 29
       assert_equal "accounts", indexes.first.table
30  
-      assert_equal idx_name, indexes.first.name
  30
+      # OpenBase does not have the concept of a named index
  31
+      # Indexes are merely properties of columns.
  32
+      assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
31 33
       assert !indexes.first.unique
32 34
       assert_equal ["firm_id"], indexes.first.columns
33 35
     else
@@ -80,4 +82,5 @@ def test_reset_table_with_non_integer_pk
80 82
       assert_nothing_raised { sub.save! }
81 83
     end
82 84
   end
  85
+
83 86
 end
22  activerecord/test/connections/native_openbase/connection.rb
... ...
@@ -0,0 +1,22 @@
  1
+print "Using native OpenBase\n"
  2
+require_dependency 'fixtures/course'
  3
+require 'logger'
  4
+
  5
+ActiveRecord::Base.logger = Logger.new("debug.log")
  6
+
  7
+db1 = 'activerecord_unittest'
  8
+db2 = 'activerecord_unittest2'
  9
+
  10
+ActiveRecord::Base.establish_connection(
  11
+  :adapter  => "openbase",
  12
+  :username => "admin",
  13
+  :password => "", 
  14
+  :database => db1
  15
+)
  16
+
  17
+Course.establish_connection(
  18
+  :adapter  => "openbase",
  19
+  :username => "admin",
  20
+  :password => "", 
  21
+  :database => db2
  22
+)
2  activerecord/test/fixtures/db_definitions/openbase.drop.sql
... ...
@@ -0,0 +1,2 @@
  1
+DROP ALL
  2
+go
282  activerecord/test/fixtures/db_definitions/openbase.sql
... ...
@@ -0,0 +1,282 @@
  1
+CREATE TABLE accounts (
  2
+    id integer UNIQUE INDEX DEFAULT _rowid,
  3
+    firm_id integer,
  4
+    credit_limit integer
  5
+)
  6
+go
  7
+CREATE PRIMARY KEY accounts (id) 
  8
+go
  9
+
  10
+CREATE TABLE funny_jokes (
  11
+  id integer UNIQUE INDEX DEFAULT _rowid,
  12
+  name char(50) DEFAULT NULL
  13
+)
  14
+go
  15
+CREATE PRIMARY KEY funny_jokes (id)
  16
+go
  17
+
  18
+CREATE TABLE companies (
  19
+    id integer UNIQUE INDEX DEFAULT _rowid,
  20
+    type char(50),
  21
+    ruby_type char(50),
  22
+    firm_id integer,
  23
+    name char(50),
  24
+    client_of integer,
  25
+    rating integer default 1
  26
+) 
  27
+go
  28
+CREATE PRIMARY KEY companies (id) 
  29
+go
  30
+
  31
+CREATE TABLE developers_projects (
  32
+    developer_id integer NOT NULL,
  33
+    project_id integer NOT NULL,
  34
+    joined_on date,
  35
+    access_level integer default 1
  36
+) 
  37
+go
  38
+
  39
+CREATE TABLE developers (
  40
+    id integer UNIQUE INDEX DEFAULT _rowid,
  41
+    name char(100),
  42
+    salary integer DEFAULT 70000,
  43
+    created_at datetime,
  44
+    updated_at datetime
  45
+) 
  46
+go
  47
+CREATE PRIMARY KEY developers (id) 
  48
+go
  49
+
  50
+CREATE TABLE projects (
  51
+    id integer UNIQUE INDEX DEFAULT _rowid,
  52
+    name char(100),
  53
+    type char(255)
  54
+) 
  55
+go
  56
+CREATE PRIMARY KEY projects (id) 
  57
+go
  58
+
  59
+CREATE TABLE topics (
  60
+    id integer UNIQUE INDEX DEFAULT _rowid,
  61
+    title char(255),
  62
+    author_name char(255),
  63
+    author_email_address char(255),
  64
+    written_on datetime,
  65
+    bonus_time time,
  66
+    last_read date,
  67
+    content char(4096),
  68
+    approved boolean default true,
  69
+    replies_count integer default 0,
  70
+    parent_id integer,
  71
+    type char(50)
  72
+) 
  73
+go
  74
+CREATE PRIMARY KEY topics (id) 
  75
+go
  76
+
  77
+CREATE TABLE customers (
  78
+    id integer UNIQUE INDEX DEFAULT _rowid,
  79
+    name char,
  80
+    balance integer default 0,
  81
+    address_street char,
  82
+    address_city char,
  83
+    address_country char,
  84
+    gps_location char
  85
+) 
  86
+go
  87
+CREATE PRIMARY KEY customers (id) 
  88
+go
  89
+
  90
+CREATE TABLE orders (
  91
+    id integer UNIQUE INDEX DEFAULT _rowid,
  92
+    name char,
  93
+    billing_customer_id integer,
  94
+    shipping_customer_id integer
  95
+) 
  96
+go
  97
+CREATE PRIMARY KEY orders (id) 
  98
+go
  99
+
  100
+CREATE TABLE movies (
  101
+    movieid integer UNIQUE INDEX DEFAULT _rowid,
  102
+    name text
  103
+) 
  104
+go
  105
+CREATE PRIMARY KEY movies (movieid) 
  106
+go
  107
+
  108
+CREATE TABLE subscribers (
  109
+    nick CHAR(100) NOT NULL DEFAULT _rowid,
  110
+    name CHAR(100)
  111
+) 
  112
+go
  113
+CREATE PRIMARY KEY subscribers (nick) 
  114
+go
  115
+
  116
+CREATE TABLE booleantests (
  117
+    id integer UNIQUE INDEX DEFAULT _rowid,
  118
+    value boolean
  119
+) 
  120
+go
  121
+CREATE PRIMARY KEY booleantests (id) 
  122
+go
  123
+
  124
+CREATE TABLE defaults (
  125
+    id integer UNIQUE INDEX ,
  126
+    modified_date date default CURDATE(),
  127
+    modified_date_function date default NOW(),
  128
+    fixed_date date default '2004-01-01',
  129
+    modified_time timestamp default NOW(),
  130
+    modified_time_function timestamp default NOW(),
  131
+    fixed_time timestamp default '2004-01-01 00:00:00.000000-00',
  132
+    char1 char(1) default 'Y',
  133
+    char2 char(50) default 'a char field',
  134
+    char3 text default 'a text field'
  135
+) 
  136
+go
  137
+
  138
+CREATE TABLE auto_id_tests (
  139
+    auto_id integer UNIQUE INDEX DEFAULT _rowid,
  140
+    value integer
  141
+) 
  142
+go
  143
+CREATE PRIMARY KEY auto_id_tests (auto_id) 
  144
+go
  145
+
  146
+CREATE TABLE entrants (
  147
+  id integer UNIQUE INDEX ,
  148
+  name text,
  149
+  course_id integer
  150
+) 
  151
+go
  152
+
  153
+CREATE TABLE colnametests (
  154
+  id integer UNIQUE INDEX ,
  155
+  references integer NOT NULL
  156
+) 
  157
+go
  158
+
  159
+CREATE TABLE mixins (
  160
+  id integer UNIQUE INDEX DEFAULT _rowid,
  161
+  parent_id integer,
  162
+  type char,  
  163
+  pos integer,
  164
+  lft integer,
  165
+  rgt integer,
  166
+  root_id integer,  
  167
+  created_at timestamp,
  168
+  updated_at timestamp
  169
+) 
  170
+go
  171
+CREATE PRIMARY KEY mixins (id) 
  172
+go
  173
+
  174
+CREATE TABLE people (
  175
+  id integer UNIQUE INDEX DEFAULT _rowid,
  176
+  first_name text,
  177
+  lock_version integer default 0
  178
+) 
  179
+go
  180
+CREATE PRIMARY KEY people (id) 
  181
+go
  182
+
  183
+CREATE TABLE readers (
  184
+    id integer UNIQUE INDEX DEFAULT _rowid,
  185
+    post_id integer NOT NULL,
  186
+    person_id integer NOT NULL
  187
+)
  188
+go
  189
+CREATE PRIMARY KEY readers (id)
  190
+go
  191
+
  192
+CREATE TABLE binaries ( 
  193
+  id integer UNIQUE INDEX DEFAULT _rowid,
  194
+  data object
  195
+) 
  196
+go
  197
+CREATE PRIMARY KEY binaries (id) 
  198
+go
  199
+
  200
+CREATE TABLE computers (
  201
+  id integer UNIQUE INDEX ,
  202
+  developer integer NOT NULL,
  203
+  extendedWarranty integer NOT NULL
  204
+) 
  205
+go
  206
+
  207
+CREATE TABLE posts (
  208
+  id integer UNIQUE INDEX ,
  209
+  author_id integer,
  210
+  title char(255),
  211
+  type char(255),
  212
+  body text
  213
+) 
  214
+go
  215
+
  216
+CREATE TABLE comments (
  217
+  id integer UNIQUE INDEX ,
  218
+  post_id integer,
  219
+  type char(255),
  220
+  body text
  221
+) 
  222
+go
  223
+
  224
+CREATE TABLE authors (
  225
+  id integer UNIQUE INDEX ,
  226
+  name char(255) default NULL
  227
+) 
  228
+go
  229
+
  230
+CREATE TABLE tasks (
  231
+  id integer UNIQUE INDEX DEFAULT _rowid,
  232
+  starting datetime,
  233
+  ending datetime
  234
+) 
  235
+go
  236
+CREATE PRIMARY KEY tasks (id) 
  237
+go
  238
+
  239
+CREATE TABLE categories (
  240
+  id integer UNIQUE INDEX ,
  241
+  name char(255),
  242
+  type char(255)
  243
+) 
  244
+go
  245
+
  246
+CREATE TABLE categories_posts (
  247
+  category_id integer NOT NULL,
  248
+  post_id integer NOT NULL
  249
+) 
  250
+go
  251
+
  252
+CREATE TABLE fk_test_has_pk (
  253
+  id INTEGER NOT NULL DEFAULT _rowid
  254
+) 
  255
+go
  256
+CREATE PRIMARY KEY fk_test_has_pk (id) 
  257
+go
  258
+
  259
+CREATE TABLE fk_test_has_fk (
  260
+  id    INTEGER NOT NULL DEFAULT _rowid,
  261
+  fk_id INTEGER NOT NULL REFERENCES fk_test_has_pk.id
  262
+) 
  263
+go
  264
+CREATE PRIMARY KEY fk_test_has_fk (id) 
  265
+go
  266
+
  267
+CREATE TABLE keyboards (
  268
+  key_number integer UNIQUE INDEX DEFAULT _rowid,
  269
+  name char(50)
  270
+) 
  271
+go
  272
+CREATE PRIMARY KEY keyboards (key_number) 
  273
+go
  274
+
  275
+CREATE TABLE legacy_things (
  276
+  id INTEGER NOT NULL DEFAULT _rowid,
  277
+  tps_report_number INTEGER default NULL,
  278
+  version integer NOT NULL default 0
  279
+)
  280
+go
  281
+CREATE PRIMARY KEY legacy_things (id)
  282
+go
2  activerecord/test/fixtures/db_definitions/openbase2.drop.sql
... ...
@@ -0,0 +1,2 @@
  1
+DROP TABLE courses
  2
+go
7  activerecord/test/fixtures/db_definitions/openbase2.sql
... ...
@@ -0,0 +1,7 @@
  1
+CREATE TABLE courses (
  2
+  id integer UNIQUE INDEX DEFAULT _rowid,
  3
+  name text
  4
+)
  5
+go
  6
+CREATE PRIMARY KEY courses (id)
  7
+go

0 notes on commit 416385a

Please sign in to comment.
Something went wrong with that request. Please try again.