wunderbread-ar-extensions 0.8.3

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 (42) hide show
  1. data/ChangeLog +131 -0
  2. data/README +156 -0
  3. data/Rakefile +99 -0
  4. data/config/database.yml +7 -0
  5. data/config/database.yml.template +7 -0
  6. data/config/mysql.schema +72 -0
  7. data/config/postgresql.schema +39 -0
  8. data/db/migrate/generic_schema.rb +87 -0
  9. data/db/migrate/mysql_schema.rb +31 -0
  10. data/db/migrate/oracle_schema.rb +5 -0
  11. data/db/migrate/version.rb +4 -0
  12. data/init.rb +29 -0
  13. data/lib/ar-extensions.rb +5 -0
  14. data/lib/ar-extensions/adapters/abstract_adapter.rb +146 -0
  15. data/lib/ar-extensions/adapters/jdbcmysql.rb +10 -0
  16. data/lib/ar-extensions/adapters/mysql.rb +10 -0
  17. data/lib/ar-extensions/adapters/oracle.rb +14 -0
  18. data/lib/ar-extensions/adapters/postgresql.rb +9 -0
  19. data/lib/ar-extensions/adapters/sqlite.rb +7 -0
  20. data/lib/ar-extensions/csv.rb +309 -0
  21. data/lib/ar-extensions/extensions.rb +506 -0
  22. data/lib/ar-extensions/finder_options.rb +208 -0
  23. data/lib/ar-extensions/finder_options/mysql.rb +6 -0
  24. data/lib/ar-extensions/finders.rb +95 -0
  25. data/lib/ar-extensions/foreign_keys.rb +70 -0
  26. data/lib/ar-extensions/fulltext.rb +62 -0
  27. data/lib/ar-extensions/fulltext/mysql.rb +44 -0
  28. data/lib/ar-extensions/import.rb +348 -0
  29. data/lib/ar-extensions/import/jdbcmysql.rb +5 -0
  30. data/lib/ar-extensions/import/mysql.rb +5 -0
  31. data/lib/ar-extensions/import/mysql_generic.rb +41 -0
  32. data/lib/ar-extensions/import/postgresql.rb +0 -0
  33. data/lib/ar-extensions/import/sqlite.rb +22 -0
  34. data/lib/ar-extensions/insert_select.rb +184 -0
  35. data/lib/ar-extensions/insert_select/mysql.rb +6 -0
  36. data/lib/ar-extensions/synchronize.rb +30 -0
  37. data/lib/ar-extensions/temporary_table.rb +124 -0
  38. data/lib/ar-extensions/temporary_table/mysql.rb +3 -0
  39. data/lib/ar-extensions/util/sql_generation.rb +27 -0
  40. data/lib/ar-extensions/util/support_methods.rb +43 -0
  41. data/lib/ar-extensions/version.rb +9 -0
  42. metadata +107 -0
@@ -0,0 +1,6 @@
1
+ #insert select functionality is dependent on finder options
2
+ require 'ar-extensions/finder_options/mysql'
3
+
4
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
5
+ include ActiveRecord::Extensions::InsertSelectSupport
6
+ end
@@ -0,0 +1,30 @@
1
+ module ActiveRecord # :nodoc:
2
+ class Base # :nodoc:
3
+
4
+ # Synchronizes the passed in ActiveRecord instances with data
5
+ # from the database. This is like calling reload
6
+ # on an individual ActiveRecord instance but it is intended for use on
7
+ # multiple instances.
8
+ #
9
+ # This uses one query for all instance updates and then updates existing
10
+ # instances rather sending one query for each instance
11
+ def self.synchronize(instances, key=self.primary_key)
12
+ return if instances.empty?
13
+
14
+ keys = instances.map(&"#{key}".to_sym)
15
+ klass = instances.first.class
16
+ fresh_instances = klass.find( :all, :conditions=>{ key=>keys }, :order=>"#{key} ASC" )
17
+
18
+ instances.each_with_index do |instance, index|
19
+ instance.clear_aggregation_cache
20
+ instance.clear_association_cache
21
+ instance.instance_variable_set '@attributes', fresh_instances[index].attributes
22
+ end
23
+ end
24
+
25
+ # See ActiveRecord::ConnectionAdapters::AbstractAdapter.synchronize
26
+ def synchronize(instances, key=ActiveRecord::Base.primary_key)
27
+ self.class.synchronize(instances, key)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,124 @@
1
+
2
+ module ActiveRecord::Extensions::TemporaryTableSupport # :nodoc:
3
+ def supports_temporary_tables? #:nodoc:
4
+ true
5
+ end
6
+ end
7
+
8
+
9
+ class ActiveRecord::Base
10
+ @@temporary_table_hsh ||= {}
11
+
12
+ # Returns true if the underlying database connection supports temporary tables
13
+ def self.supports_temporary_tables?
14
+ connection.supports_temporary_tables?
15
+ rescue NoMethodError
16
+ false
17
+ end
18
+
19
+ ######################################################################
20
+ # Creates a temporary table given the passed in options hash. The
21
+ # temporary table is created based off from another table the
22
+ # current model class. This method returns the constant for the new
23
+ # new model. This can also be used with block form (see below).
24
+ #
25
+ # == Parameters
26
+ # * options - the options hash used to define the temporary table.
27
+ #
28
+ # ==== Options
29
+ # * :table_name - the desired name of the temporary table. If not supplied \
30
+ # then a name of "temp_" + the current table_name of the current model \
31
+ # will be used.
32
+ # * :like - the table model you want to base the temporary tables \
33
+ # structure off from. If this is not supplied then the table_name of the \
34
+ # current model will be used.
35
+ # * :model_name - the name of the model you want to use for the temporary \
36
+ # table. This must be compliant with Ruby's naming conventions for \
37
+ # constants. If this is not supplied a rails-generated table name will \
38
+ # be created which is based off from the table_name of the temporary table. \
39
+ # IE: Account.create_temporary_table creates the TempAccount model class
40
+ #
41
+ # ==== Example 1, using defaults
42
+ # class Project < ActiveRecord::Base ; end
43
+ #
44
+ # Project.create_temporary_table
45
+ #
46
+ # This creates a temporary table named 'temp_projects' and creates a constant
47
+ # name TempProject. The table structure is copied from the _projects_ table.
48
+ #
49
+ # ==== Example 2, using :table_name and :model options
50
+ # Project.create_temporary_table :table_name=>'my_projects', :model=>'MyProject'
51
+ #
52
+ # This creates a temporary table named 'my_projects' and creates a constant named
53
+ # MyProject. The table structure is copied from the _projects_ table.
54
+ #
55
+ # ==== Example 3, using :like
56
+ # ActiveRecord::Base.create_temporary_table :like=>Project
57
+ #
58
+ # This is the same as calling Project.create_temporary_table.
59
+ #
60
+ # ==== Example 4, using block form
61
+ # Project.create_temporary_table do |t|
62
+ # # ...
63
+ # end
64
+ #
65
+ # Using the block form will automatically drop the temporary table
66
+ # when the block exits. _t_ which is passed into the block is the temporary
67
+ # table class. In the above example _t_ equals TempProject. The block form
68
+ # can be used with all of the available options.
69
+ #
70
+ # === See
71
+ # * drop
72
+ ######################################################################
73
+ def self.create_temporary_table( options={} )
74
+ options[:table_name] = "temp_#{self.table_name}" unless options[:table_name]
75
+ options[:like] = self unless options[:like]
76
+ options[:temporary] = true if not options[:permanent] and not options.has_key?( :temporary )
77
+ table_name = options[:table_name]
78
+ model_name = options[:model_name] || ActiveSupport::Inflector.classify( table_name )
79
+ raise Exception.new( "Model #{model_name} already exists! \n" ) if Object.const_defined? model_name
80
+
81
+ like_table_name = options[:like].table_name || self.table_name
82
+ sql = "CREATE #{options[:temporary] ? 'TEMPORARY' : ''} TABLE #{table_name} LIKE #{like_table_name}"
83
+ connection.execute( sql )
84
+
85
+ eval "class ::#{model_name} < #{ActiveRecord::TemporaryTable.name}
86
+ set_table_name :#{table_name}
87
+ end"
88
+
89
+ @@temporary_table_hsh[ model = Object.const_get( model_name ) ] = true
90
+ if block_given?
91
+ yield model
92
+ model.drop
93
+ nil
94
+ else
95
+ model
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ class ActiveRecord::TemporaryTable < ActiveRecord::Base
102
+
103
+ # Drops a temporary table from the database and removes
104
+ # the temporary table constant.
105
+ #
106
+ # ==== Example
107
+ # Project.create_temporary_table
108
+ # Object.const_defined?( :TempProject ) # => true
109
+ # TempProject.drop
110
+ # Object.const_defined?( :TempProject ) # => false
111
+ #
112
+ def self.drop
113
+ if @@temporary_table_hsh[ self ]
114
+ sql = 'DROP TABLE ' + self.table_name + ';'
115
+ connection.execute( sql )
116
+ Object.send( :remove_const, self.name.to_sym )
117
+ @@temporary_table_hsh.delete( self )
118
+ else
119
+ raise StandardError.new( "Trying to drop nonexistance temporary table: #{self.name}" )
120
+ end
121
+ end
122
+
123
+ end
124
+
@@ -0,0 +1,3 @@
1
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
2
+ include ActiveRecord::Extensions::TemporaryTableSupport
3
+ end
@@ -0,0 +1,27 @@
1
+
2
+ #Extend this module on ActiveRecord to access global functions
3
+ module ActiveRecord
4
+ module Extensions
5
+ module SqlGeneration#:nodoc:
6
+
7
+ protected
8
+
9
+ def post_sql_statements(options)#:nodoc:
10
+ connection.post_sql_statements(quoted_table_name, options).join(' ')
11
+ end
12
+
13
+ def pre_sql_statements(options)#:nodoc:
14
+ connection.pre_sql_statements({:command => 'SELECT'}.merge(options)).join(' ').strip + " "
15
+ end
16
+
17
+ def construct_ar_extension_sql(options={}, valid_options = [], &block)#:nodoc:
18
+ options.assert_valid_keys(valid_options)if valid_options.any?
19
+
20
+ sql = pre_sql_statements(options)
21
+ yield sql, options
22
+ sql << post_sql_statements(options)
23
+ sql
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ #Extend this module on ActiveRecord to access global functions
2
+ class ExtensionNotSupported < Exception; end;
3
+
4
+ module ActiveRecord
5
+ module Extensions
6
+ module SupportMethods#:nodoc:
7
+ def supports_extension(name)
8
+ class_eval(<<-EOS, __FILE__, __LINE__)
9
+ def self.supports_#{name}?#:nodoc:
10
+ connection.supports_#{name}?
11
+ rescue NoMethodError
12
+ false
13
+ end
14
+
15
+ def supports_#{name}?#:nodoc:
16
+ self.class.supports_#{name}?
17
+ end
18
+
19
+ def self.supports_#{name}!#:nodoc:
20
+ supports_#{name}? or raise ExtensionNotSupported.new("#{name} extension is not supported. Please require the adapter file.")
21
+ end
22
+
23
+ def supports_#{name}!#:nodoc:
24
+ self.class.supports_#{name}!
25
+ end
26
+ EOS
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ ActiveRecord::Base.send :extend, ActiveRecord::Extensions::SupportMethods
33
+
34
+ module ActiveRecord
35
+ module Extensions
36
+ module SupportTrue#:nodoc:
37
+ def self.define(base, name)
38
+ puts name
39
+ base.class_eval "def supports_#{name}?; true; end"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+
2
+ module ActiveRecord # :nodoc:
3
+ module Extensions # :nodoc:
4
+ module VERSION
5
+ MAJOR, MINOR, REVISION = %W( 0 8 2 )
6
+ STRING = [ MAJOR, MINOR, REVISION ].join( '.' )
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wunderbread-ar-extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.3
5
+ platform: ruby
6
+ authors:
7
+ - Zach Dennis
8
+ - Mark Van Holstyn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-03-25 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activerecord
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 2.1.2
25
+ version:
26
+ description: Extends ActiveRecord functionality by adding better finder/query support, as well as supporting mass data import, foreign key, CSV and temporary tables
27
+ email: zach.dennis@gmail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - README
34
+ files:
35
+ - init.rb
36
+ - db/migrate
37
+ - db/migrate/generic_schema.rb
38
+ - db/migrate/mysql_schema.rb
39
+ - db/migrate/oracle_schema.rb
40
+ - db/migrate/version.rb
41
+ - Rakefile
42
+ - ChangeLog
43
+ - README
44
+ - config/database.yml
45
+ - config/database.yml.template
46
+ - config/mysql.schema
47
+ - config/postgresql.schema
48
+ - lib/ar-extensions/adapters/abstract_adapter.rb
49
+ - lib/ar-extensions/adapters/jdbcmysql.rb
50
+ - lib/ar-extensions/adapters/mysql.rb
51
+ - lib/ar-extensions/adapters/oracle.rb
52
+ - lib/ar-extensions/adapters/postgresql.rb
53
+ - lib/ar-extensions/adapters/sqlite.rb
54
+ - lib/ar-extensions/csv.rb
55
+ - lib/ar-extensions/extensions.rb
56
+ - lib/ar-extensions/finder_options/mysql.rb
57
+ - lib/ar-extensions/finder_options.rb
58
+ - lib/ar-extensions/finders.rb
59
+ - lib/ar-extensions/foreign_keys.rb
60
+ - lib/ar-extensions/fulltext/mysql.rb
61
+ - lib/ar-extensions/fulltext.rb
62
+ - lib/ar-extensions/import/jdbcmysql.rb
63
+ - lib/ar-extensions/import/mysql.rb
64
+ - lib/ar-extensions/import/mysql_generic.rb
65
+ - lib/ar-extensions/import/postgresql.rb
66
+ - lib/ar-extensions/import/sqlite.rb
67
+ - lib/ar-extensions/import.rb
68
+ - lib/ar-extensions/insert_select/mysql.rb
69
+ - lib/ar-extensions/insert_select.rb
70
+ - lib/ar-extensions/synchronize.rb
71
+ - lib/ar-extensions/temporary_table/mysql.rb
72
+ - lib/ar-extensions/temporary_table.rb
73
+ - lib/ar-extensions/util/sql_generation.rb
74
+ - lib/ar-extensions/util/support_methods.rb
75
+ - lib/ar-extensions/version.rb
76
+ - lib/ar-extensions.rb
77
+ has_rdoc: true
78
+ homepage: http://www.continuousthinking.com/tags/arext
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --main
82
+ - README
83
+ - --inline-source
84
+ - --charset=UTF-8
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ version:
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ requirements: []
100
+
101
+ rubyforge_project:
102
+ rubygems_version: 1.2.0
103
+ signing_key:
104
+ specification_version: 2
105
+ summary: Extends ActiveRecord functionality.
106
+ test_files: []
107
+