citier 0.1.12 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('citier', '0.1.12') do |p|
5
+ Echoe.new('citier', '0.1.13') do |p|
6
6
  p.description = "CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance.
7
7
  For full information: http://peterhamilton.github.com/citier/
8
8
  For the original version by ALTRABio see www.github.com/altrabio/"
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{citier}
5
- s.version = "0.1.12"
5
+ s.version = "0.1.13"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Peter Hamilton, Originally from Laurent Buffat, Pierre-Emmanuel Jouve"]
@@ -36,6 +36,8 @@ Gem::Specification.new do |s|
36
36
  s.rubyforge_project = %q{citier}
37
37
  s.rubygems_version = %q{1.3.7}
38
38
  s.summary = s.description
39
+
40
+ s.add_dependency('rails_sql_views') #needs the 'rails_sql_views', :git => 'git://github.com/morgz/rails_sql_views.git' fork. Set this in your apps bundle
39
41
 
40
42
  if s.respond_to? :specification_version then
41
43
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -24,4 +24,7 @@ require 'citier/child_instance_methods'
24
24
  require 'citier/sql_adapters'
25
25
 
26
26
  #Require acts_as_citier hook
27
- require 'citier/acts_as_citier'
27
+ require 'citier/acts_as_citier'
28
+
29
+ # Methods that override ActiveRecord::Relation
30
+ require 'citier/relation_methods'
@@ -1,8 +1,10 @@
1
1
  module Citier
2
- def self.included(base)
3
- # When a class includes a module the module’s self.included method will be invoked.
4
- base.send :extend, ClassMethods
2
+ module ActsAsCitier
3
+ def self.included(base)
4
+ # When a class includes a module the module’s self.included method will be invoked.
5
+ base.send :extend, Citier::ClassMethods
6
+ end
5
7
  end
6
8
  end
7
9
 
8
- ActiveRecord::Base.send :include, Citier
10
+ ActiveRecord::Base.send :include, Citier::ActsAsCitier
@@ -1,59 +1,102 @@
1
- module ChildInstanceMethods
1
+ module Citier
2
+ module ChildInstanceMethods
2
3
 
3
- def save
4
+ def save(options={})
5
+ return false if (options[:validate] != false && !self.valid?)
6
+
7
+ #citier_debug("Callback (#{self.inspect})")
8
+ citier_debug("SAVING #{self.class.to_s}")
9
+
10
+ #AIT NOTE: Will change any protected values back to original values so any models onwards won't see changes.
11
+ # Run save and create/update callbacks, just like ActiveRecord does
12
+ self.run_callbacks(:save) do
13
+ self.run_callbacks(self.new_record? ? :create : :update) do
14
+ #get the attributes of the class which are inherited from it's parent.
15
+ attributes_for_parent = self.attributes.reject { |key,value| !self.class.superclass.column_names.include?(key) }
16
+ changed_attributes_for_parent = self.changed_attributes.reject { |key,value| !self.class.superclass.column_names.include?(key) }
4
17
 
5
- #get the attributes of the class which are inherited from it's parent.
6
- attributes_for_parent = self.attributes.reject{|key,value| !self.class.superclass.column_names.include?(key) }
18
+ # Get the attributes of the class which are unique to this class and not inherited.
19
+ attributes_for_current = self.attributes.reject { |key,value| self.class.superclass.column_names.include?(key) }
20
+ changed_attributes_for_current = self.changed_attributes.reject { |key,value| self.class.superclass.column_names.include?(key) }
7
21
 
8
- # Get the attributes of the class which are unique to this class and not inherited.
9
- attributes_for_current = self.attributes.reject{|key,value| self.class.superclass.column_names.include?(key) }
22
+ citier_debug("Attributes for #{self.class.superclass.to_s}: #{attributes_for_parent.inspect}")
23
+ citier_debug("Changed attributes for #{self.class.superclass.to_s}: #{changed_attributes_for_parent.keys.inspect}")
24
+ citier_debug("Attributes for #{self.class.to_s}: #{attributes_for_current.inspect}")
25
+ citier_debug("Changed attributes for #{self.class.to_s}: #{changed_attributes_for_current.keys.inspect}")
10
26
 
11
- citier_debug("Attributes for #{self.class.to_s}: #{attributes_for_current.inspect.to_s}")
12
-
13
- #create a new instance of the superclass, passing the inherited attributes.
14
- parent = self.class.superclass.new(attributes_for_parent)
15
- parent.id = self.id
27
+ ########
28
+ #
29
+ # Parent saving
30
+
31
+ #create a new instance of the superclass, passing the inherited attributes.
32
+ parent = self.class.superclass.new
33
+
34
+ parent.force_attributes(attributes_for_parent, :merge => true)
35
+ changed_attributes_for_parent["id"] = 0 # We need to change at least something to force a timestamps update.
36
+ parent.force_changed_attributes(changed_attributes_for_parent)
37
+
38
+ parent.id = self.id if id
39
+ parent.type = self.type
40
+
41
+ parent.is_new_record(new_record?)
42
+
43
+ # If we're root (AR subclass) this will just be saved as normal through AR. If we're a child it will call this method again.
44
+ # It will try and save it's parent and then save itself through the Writable constant.
45
+ parent_saved = parent.save
46
+ self.id = parent.id
16
47
 
17
- parent.is_new_record(new_record?)
48
+ if !parent_saved
49
+ # Couldn't save parent class
50
+ citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
51
+ citier_debug("Errors = #{parent.errors.to_s}")
52
+ return false # Return false and exit run_callbacks :save and :create/:update, so the after_ callback won't run.
53
+ end
54
+
55
+ #End of parent saving
56
+
57
+ ######
58
+ ##
59
+ ## Self Saving
60
+ ##
18
61
 
19
- parent_saved = parent.save
20
- self.id = parent.id
62
+ # If there are attributes for the current class (unique & not inherited), save current model
63
+ if !attributes_for_current.empty?
64
+ current = self.class::Writable.new
65
+
66
+ current.force_attributes(attributes_for_current, :merge => true)
67
+ current.force_changed_attributes(changed_attributes_for_current)
68
+
69
+ current.id = self.id
70
+ current.is_new_record(new_record?)
71
+
72
+ current_saved = current.save
73
+
74
+ current.after_save_change_request if current.respond_to?('after_save_change_request') #Specific to an app I'm building
21
75
 
22
- if(parent_saved==false)
23
- # Couldn't save parent class
24
- # TODO: Handle situation where parent class could not be saved
25
- citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
26
- end
76
+ if !current_saved
77
+ citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
78
+ citier_debug("Errors = #{current.errors.to_s}")
79
+ return false # Return false and exit run_callbacks :save and :create/:update, so the after callback won't run.
80
+ end
81
+ end
27
82
 
28
- # If there are attributes for the current class (unique & not inherited)
29
- # and parent(s) saved successfully, save current model
30
- if(!attributes_for_current.empty? && parent_saved)
31
- current = self.class::Writable.new(attributes_for_current)
32
- current.id = self.id
33
- current.is_new_record(new_record?)
34
- current_saved = current.save
35
-
36
- # This is no longer a new record
37
- is_new_record(false)
83
+ # at this point, parent_saved && current_saved
84
+
85
+ is_new_record(false) # This is no longer a new record
38
86
 
39
- if(!current_saved)
40
- citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
87
+ self.force_changed_attributes({}) # Reset changed_attributes so future changes will be tracked correctly
88
+
89
+ # No return, because we want the after callback to run.
90
+ end
41
91
  end
92
+ return true
42
93
  end
43
-
44
- # Update root class with this 'type'
45
- if parent_saved && current_saved
46
- sql = "UPDATE #{self.class.root_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
47
- citier_debug("SQL : #{sql}")
48
- self.connection.execute(sql)
49
- end
50
- return parent_saved && current_saved
51
- end
52
94
 
53
- def save!
54
- raise ActiveRecord::RecordInvalid.new(self) unless self.valid?
55
- self.save
56
- end
95
+ def save!(options={})
96
+ raise ActiveRecord::RecordInvalid.new(self) if (options[:validate] != false && !self.valid?)
97
+ self.save || raise(ActiveRecord::RecordNotSaved)
98
+ end
57
99
 
58
- include InstanceMethods
100
+ include InstanceMethods
101
+ end
59
102
  end
@@ -1,74 +1,50 @@
1
- module ClassMethods
2
- # any method placed here will apply to classes
3
- def acts_as_citier(options = {})
1
+ module Citier
2
+ module ClassMethods
3
+ # any method placed here will apply to classes
4
+ def acts_as_citier(options = {})
5
+ set_acts_as_citier(true)
4
6
 
5
- # Option for setting the inheritance columns, default value = 'type'
6
- db_type_field = (options[:db_type_field] || :type).to_s
7
+ # Option for setting the inheritance columns, default value = 'type'
8
+ db_type_field = (options[:db_type_field] || :type).to_s
7
9
 
8
- #:table_name = option for setting the name of the current class table_name, default value = 'tableized(current class name)'
9
- table_name = (options[:table_name] || self.name.tableize.gsub(/\//,'_')).to_s
10
+ #:table_name = option for setting the name of the current class table_name, default value = 'tableized(current class name)'
11
+ table_name = (options[:table_name] || self.name.tableize.gsub(/\//,'_')).to_s
10
12
 
11
- set_inheritance_column "#{db_type_field}"
13
+ set_inheritance_column "#{db_type_field}"
12
14
 
13
- if(self.superclass!=ActiveRecord::Base)
14
- # Non root-class
15
+ if(self.superclass!=ActiveRecord::Base)
16
+ # Non root-class
15
17
 
16
- citier_debug("Non Root Class")
17
- citier_debug("table_name -> #{table_name}")
18
+ citier_debug("Non Root Class")
19
+ citier_debug("table_name -> #{table_name}")
18
20
 
19
- # Set up the table which contains ALL attributes we want for this class
20
- set_table_name "view_#{table_name}"
21
+ # Set up the table which contains ALL attributes we want for this class
22
+ set_table_name "view_#{table_name}"
21
23
 
22
- citier_debug("tablename (view) -> #{self.table_name}")
24
+ citier_debug("tablename (view) -> #{self.table_name}")
23
25
 
24
- # The the Writable. References the write-able table for the class because
25
- # save operations etc can't take place on the views
26
- self.const_set("Writable", create_class_writable(self))
27
-
28
- # Add the functions required for children only
29
- send :include, ChildInstanceMethods
30
- else
31
- # Root class
32
-
33
- after_save :updatetype
34
-
35
- citier_debug("Root Class")
36
-
37
- set_table_name "#{table_name}"
38
-
39
- citier_debug("table_name -> #{self.table_name}")
40
- #returns the root class (the highest inherited class before ActiveRecord)
41
- def self.root_class
42
- if(self.superclass!=ActiveRecord::Base)
43
- self.superclass.root_class
44
- else
45
- return self
26
+ # The the Writable. References the write-able table for the class because
27
+ # save operations etc can't take place on the views
28
+ self.const_set("Writable", create_class_writable(self))
29
+
30
+ after_initialize do
31
+ self.id = nil if self.new_record? && self.id == 0
46
32
  end
47
- end
48
33
 
49
- def self.find(*args) #overrides find to get all attributes
50
- tuples = super
34
+ # Add the functions required for children only
35
+ send :include, Citier::ChildInstanceMethods
36
+ else
37
+ # Root class
51
38
 
52
- # in case of many objects, return an array of them, reloaded to pull in inherited attributes
53
- return tuples.map{|x| x.reload} if tuples.kind_of?(Array)
39
+ citier_debug("Root Class")
54
40
 
55
- # in case of only one tuple, return it reloaded.
56
- # Can't use reload as would loop inifinitely, so do a search by id instead.
57
- # Probably a nice way of cleaning this a bit
58
- return tuples.class.where(tuples.class[:id].eq(tuples.id))[0]
59
- end
41
+ set_table_name "#{table_name}"
60
42
 
61
- # Unlike destroy_all it is useful to override this method.
62
- # In fact destroy_all will explicitly call a destroy method on each object
63
- # whereas delete_all doesn't and only calls specific SQL requests.
64
- # To be even more precise call delete_all with special conditions
65
- def self.delete_all
66
- #call delete method for each instance of the class
67
- self.all.each{|o| o.delete }
68
- end
43
+ citier_debug("table_name -> #{self.table_name}")
69
44
 
70
- # Add the functions required for root classes only
71
- send :include, RootInstanceMethods
45
+ # Add the functions required for root classes only
46
+ send :include, Citier::RootInstanceMethods
47
+ end
72
48
  end
73
49
  end
74
- end
50
+ end
@@ -1,4 +1,12 @@
1
- class ActiveRecord::Base
1
+ class ActiveRecord::Base
2
+
3
+ def self.set_acts_as_citier(citier)
4
+ @acts_as_citier = citier
5
+ end
6
+
7
+ def self.acts_as_citier?
8
+ @acts_as_citier || false
9
+ end
2
10
 
3
11
  def self.[](column_name)
4
12
  arel_table[column_name]
@@ -7,14 +15,11 @@ class ActiveRecord::Base
7
15
  def is_new_record(state)
8
16
  @new_record = state
9
17
  end
10
-
11
- def self.all(*args)
12
- # For some reason need to override this so it uses my modified find function which reloads each object to pull in all properties.
13
- return find(:all, *args)
14
- end
15
18
 
16
19
  def self.create_class_writable(class_reference) #creation of a new class which inherits from ActiveRecord::Base
17
20
  Class.new(ActiveRecord::Base) do
21
+ include Citier::InstanceMethods::ForcedWriters
22
+
18
23
  t_name = class_reference.table_name
19
24
  t_name = t_name[5..t_name.length]
20
25
 
@@ -30,6 +35,16 @@ class ActiveRecord::Base
30
35
  end
31
36
 
32
37
  def create_citier_view(theclass) #function for creating views for migrations
38
+ # flush any column info in memory
39
+ # Loops through and stops once we've cleaned up to our root class.
40
+ # We MUST user Writable as that is the place where changes might reside!
41
+ reset_class = theclass::Writable
42
+ until reset_class == ActiveRecord::Base
43
+ citier_debug("Resetting column information on #{reset_class}")
44
+ reset_class.reset_column_information
45
+ reset_class = reset_class.superclass
46
+ end
47
+
33
48
  self_columns = theclass::Writable.column_names.select{ |c| c != "id" }
34
49
  parent_columns = theclass.superclass.column_names.select{ |c| c != "id" }
35
50
  columns = parent_columns+self_columns
@@ -37,13 +52,53 @@ def create_citier_view(theclass) #function for creating views for migrations
37
52
  self_write_table = theclass::Writable.table_name
38
53
  parent_read_table = theclass.superclass.table_name
39
54
  sql = "CREATE VIEW #{self_read_table} AS SELECT #{parent_read_table}.id, #{columns.join(',')} FROM #{parent_read_table}, #{self_write_table} WHERE #{parent_read_table}.id = #{self_write_table}.id"
55
+
56
+ #Use our rails_sql_views gem to create the view so we get it outputted to schema
57
+ create_view "#{self_read_table}", "SELECT #{parent_read_table}.id, #{columns.join(',')} FROM #{parent_read_table}, #{self_write_table} WHERE #{parent_read_table}.id = #{self_write_table}.id" do |v|
58
+ v.column :id
59
+ columns.each do |c|
60
+ v.column c.to_sym
61
+ end
62
+ end
63
+
40
64
  citier_debug("Creating citier view -> #{sql}")
41
- theclass.connection.execute sql
65
+ #theclass.connection.execute sql
66
+
67
+
42
68
  end
43
69
 
44
70
  def drop_citier_view(theclass) #function for dropping views for migrations
45
71
  self_read_table = theclass.table_name
46
72
  sql = "DROP VIEW #{self_read_table}"
73
+
74
+ drop_view(self_read_table.to_sym) #drop using our rails sql views gem
75
+
47
76
  citier_debug("Dropping citier view -> #{sql}")
48
- theclass.connection.execute sql
49
- end
77
+ #theclass.connection.execute sql
78
+ end
79
+
80
+ def update_citier_view(theclass) #function for updating views for migrations
81
+
82
+ citier_debug("Updating citier view for #{theclass}")
83
+
84
+ if theclass.table_exists?
85
+ drop_citier_view(theclass)
86
+ create_citier_view(theclass)
87
+ else
88
+ citier_debug("Error: #{theclass} VIEW doesn't exist.")
89
+ end
90
+
91
+ end
92
+
93
+ def create_or_update_citier_view(theclass) #Convienience function for updating or creating views for migrations
94
+
95
+ citier_debug("Create or Update citier view for #{theclass}")
96
+
97
+ if theclass.table_exists?
98
+ update_citier_view(theclass)
99
+ else
100
+ citier_debug("VIEW DIDN'T EXIST. Now creating for #{theclass}")
101
+ create_citier_view(theclass)
102
+ end
103
+
104
+ end
@@ -1,30 +1,37 @@
1
- module InstanceMethods
2
-
3
- # Delete the model (and all parents it inherits from if applicable)
4
- def delete(id = self.id)
5
- citier_debug("Deleting #{self.class.to_s} with ID #{self.id}")
6
-
7
- # Delete information stored in the table associated to the class of the object
8
- # (if there is such a table)
9
- deleted = true
10
- c = self.class
11
- while c.superclass!=ActiveRecord::Base
12
- citier_debug("Deleting back up hierarchy #{c}")
13
- deleted &= c::Writable.delete(id)
14
- c = c.superclass
1
+ module Citier
2
+ module InstanceMethods
3
+ def self.included(base)
4
+ base.send :include, ForcedWriters
5
+ end
6
+
7
+ module ForcedWriters
8
+ def force_attributes(new_attributes, options = {})
9
+ new_attributes = @attributes.merge(new_attributes) if options[:merge]
10
+ @attributes = new_attributes
11
+
12
+ if options[:clear_caches] != false
13
+ @aggregation_cache = {}
14
+ @association_cache = {}
15
+ @attributes_cache = {}
16
+ end
17
+ end
18
+
19
+ def force_changed_attributes(new_changed_attributes, options = {})
20
+ new_changed_attributes = @attributes.merge(new_changed_attributes) if options[:merge]
21
+ @changed_attributes = new_changed_attributes
22
+ end
23
+ end
24
+
25
+ # USAGE validates :attribute, :citier_uniqueness => true
26
+ # Needed because validates :attribute, :uniqueness => true Won't work because it tries to call child_class.attribute on parents table
27
+ class CitierUniquenessValidator < ActiveModel::EachValidator
28
+ def validate_each(object, attribute, value)
29
+ existing_record = object.class.where(attribute.to_sym => value).limit(1).first
30
+ if existing_record && existing_record.as_root != object.as_root #if prev record exist and it isn't our current obj
31
+ object.errors[attribute] << (options[:message] || "has already been taken.")
32
+ end
33
+ end
15
34
  end
16
- deleted &= c.delete(id)
17
- return deleted
18
- end
19
-
20
- def updatetype
21
- sql = "UPDATE #{self.class.root_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
22
- self.connection.execute(sql)
23
- citier_debug("#{sql}")
24
- end
25
35
 
26
- def destroy
27
- return self.delete
28
36
  end
29
-
30
37
  end
@@ -1,5 +1,44 @@
1
- module RootInstanceMethods
1
+ module Citier
2
+ module RootInstanceMethods
2
3
 
3
- include InstanceMethods
4
+ include InstanceMethods
5
+
6
+ # Instantiates the instance as it's lowest root class. Used when destroying a root class to
7
+ # make sure we're not leaving children behind
8
+ def as_child
9
+ #instance_class = Object.const_get(self.type)
10
+ return bottom_class_instance = Kernel.const_get(self.type).where(:id => self.id).first
11
+ end
12
+
13
+ # Access the root class if ever you need.
14
+ def as_root
15
+ if !self.is_root?
16
+ root_class = self.class.base_class
4
17
 
18
+ #get the attributes of the class which are inherited from it's parent.
19
+ attributes_for_parent = self.attributes.reject{|key,value| !root_class.column_names.include?(key) }
20
+
21
+ #create a new instance of the superclass, passing the inherited attributes.
22
+ parent = root_class.new(attributes_for_parent)
23
+ parent.id = self.id
24
+ parent.type = self.type
25
+
26
+ parent.is_new_record(new_record?)
27
+
28
+ parent
29
+ else
30
+ self #just return self if we are the root
31
+ end
32
+ end
33
+
34
+ #For testing whther we are using the framework or not
35
+ def acts_as_citier?
36
+ true
37
+ end
38
+
39
+ def is_root?
40
+ self.class.superclass==ActiveRecord::Base
41
+ end
42
+
43
+ end
5
44
  end
@@ -6,118 +6,126 @@
6
6
  #------------------------------------------------------------------------------------------------#
7
7
 
8
8
  require 'active_record'
9
- require 'active_record/connection_adapters/sqlite_adapter'
10
- require 'active_record/connection_adapters/sqlite3_adapter'
11
- require 'active_record/connection_adapters/postgresql_adapter'
12
9
 
13
10
  # SQLite
14
- module ActiveRecord
15
- module ConnectionAdapters
16
- class SQLiteAdapter < AbstractAdapter
17
-
18
- def tables(name = nil)
19
- sql = <<-SQL
20
- SELECT name
21
- FROM sqlite_master
22
- WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
23
- SQL
24
- # Modification : the where clause was intially WHERE type = 'table' AND NOT name = 'sqlite_sequence'
25
- # now it is WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
26
- # this modification is made to consider tables AND VIEWS as tables
27
-
28
- execute(sql, name).map do |row|
29
- row['name']
11
+ begin
12
+ require 'active_record/connection_adapters/sqlite_adapter'
13
+ require 'active_record/connection_adapters/sqlite3_adapter'
14
+
15
+ module ActiveRecord
16
+ module ConnectionAdapters
17
+ class SQLiteAdapter < AbstractAdapter
18
+
19
+ def tables(name = nil)
20
+ sql = <<-SQL
21
+ SELECT name
22
+ FROM sqlite_master
23
+ WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
24
+ SQL
25
+ # Modification : the where clause was intially WHERE type = 'table' AND NOT name = 'sqlite_sequence'
26
+ # now it is WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
27
+ # this modification is made to consider tables AND VIEWS as tables
28
+
29
+ execute(sql, name).map do |row|
30
+ row['name']
31
+ end
30
32
  end
31
33
  end
32
34
  end
33
- end
34
-
35
+ end
36
+ rescue Gem::LoadError
37
+ # not installed
35
38
  end
36
39
 
37
-
38
40
  # PostGreSQL
39
- module ActiveRecord
40
- module ConnectionAdapters
41
- class PostgreSQLAdapter < AbstractAdapter
42
- def tables(name = nil)
43
- a=tablesL(name)
44
- b=viewsL(name)
45
- if(b!=[])
46
- a=a+b
41
+ begin
42
+ require 'active_record/connection_adapters/postgresql_adapter'
43
+
44
+ module ActiveRecord
45
+ module ConnectionAdapters
46
+ class PostgreSQLAdapter < AbstractAdapter
47
+ def tables(name = nil)
48
+ a=tablesL(name)
49
+ b=viewsL(name)
50
+ if(b!=[])
51
+ a=a+b
52
+ end
53
+ return a
47
54
  end
48
- return a
49
- end
50
-
51
- def tablesL(name = nil)
52
55
 
53
- query(<<-SQL, name).map { |row| row[0] }
54
- SELECT tablename
55
- FROM pg_tables
56
- WHERE schemaname = ANY (current_schemas(false))
57
- SQL
58
- end
59
- def viewsL(name = nil)
56
+ def tablesL(name = nil)
60
57
 
61
- query(<<-SQL, name).map { |row| row[0] }
62
- SELECT viewname
63
- FROM pg_views
64
- WHERE schemaname = ANY (current_schemas(false))
65
- SQL
66
- end
58
+ query(<<-SQL, name).map { |row| row[0] }
59
+ SELECT tablename
60
+ FROM pg_tables
61
+ WHERE schemaname = ANY (current_schemas(false))
62
+ SQL
63
+ end
64
+ def viewsL(name = nil)
67
65
 
68
- def table_exists?(name)
69
- a=table_existsB?(name)
70
- b=views_existsB?(name)
71
- return a||b
72
- end
66
+ query(<<-SQL, name).map { |row| row[0] }
67
+ SELECT viewname
68
+ FROM pg_views
69
+ WHERE schemaname = ANY (current_schemas(false))
70
+ SQL
71
+ end
73
72
 
73
+ def table_exists?(name)
74
+ a=table_existsB?(name)
75
+ b=views_existsB?(name)
76
+ return a||b
77
+ end
74
78
 
75
- def table_existsB?(name)
76
- name = name.to_s
77
- schema, table = name.split('.', 2)
78
79
 
79
- unless table # A table was provided without a schema
80
- table = schema
81
- schema = nil
82
- end
80
+ def table_existsB?(name)
81
+ name = name.to_s
82
+ schema, table = name.split('.', 2)
83
83
 
84
- if name =~ /^"/ # Handle quoted table names
85
- table = name
86
- schema = nil
87
- end
84
+ unless table # A table was provided without a schema
85
+ table = schema
86
+ schema = nil
87
+ end
88
88
 
89
- query(<<-SQL).first[0].to_i > 0
90
- SELECT COUNT(*)
91
- FROM pg_tables
92
- WHERE tablename = '#{table.gsub(/(^"|"$)/,'')}'
93
- #{schema ? "AND schemaname = '#{schema}'" : ''}
94
- SQL
89
+ if name =~ /^"/ # Handle quoted table names
90
+ table = name
91
+ schema = nil
92
+ end
95
93
 
96
- end
97
- def views_existsB?(name)
98
- name = name.to_s
99
- schema, table = name.split('.', 2)
94
+ query(<<-SQL).first[0].to_i > 0
95
+ SELECT COUNT(*)
96
+ FROM pg_tables
97
+ WHERE tablename = '#{table.gsub(/(^"|"$)/,'')}'
98
+ #{schema ? "AND schemaname = '#{schema}'" : ''}
99
+ SQL
100
100
 
101
- unless table # A table was provided without a schema
102
- table = schema
103
- schema = nil
104
101
  end
102
+ def views_existsB?(name)
103
+ name = name.to_s
104
+ schema, table = name.split('.', 2)
105
+
106
+ unless table # A table was provided without a schema
107
+ table = schema
108
+ schema = nil
109
+ end
110
+
111
+ if name =~ /^"/ # Handle quoted table names
112
+ table = name
113
+ schema = nil
114
+ end
115
+
116
+ query(<<-SQL).first[0].to_i > 0
117
+ SELECT COUNT(*)
118
+ FROM pg_views
119
+ WHERE viewname = '#{table.gsub(/(^"|"$)/,'')}'
120
+ #{schema ? "AND schemaname = '#{schema}'" : ''}
121
+ SQL
105
122
 
106
- if name =~ /^"/ # Handle quoted table names
107
- table = name
108
- schema = nil
109
123
  end
110
-
111
- query(<<-SQL).first[0].to_i > 0
112
- SELECT COUNT(*)
113
- FROM pg_views
114
- WHERE viewname = '#{table.gsub(/(^"|"$)/,'')}'
115
- #{schema ? "AND schemaname = '#{schema}'" : ''}
116
- SQL
117
-
118
124
  end
119
125
  end
120
- end
126
+ end
127
+ rescue Gem::LoadError
128
+ # not installed
121
129
  end
122
130
 
123
131
  # MySQL
metadata CHANGED
@@ -1,8 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citier
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.12
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 13
9
+ version: 0.1.13
6
10
  platform: ruby
7
11
  authors:
8
12
  - Peter Hamilton, Originally from Laurent Buffat, Pierre-Emmanuel Jouve
@@ -12,8 +16,19 @@ cert_chain: []
12
16
 
13
17
  date: 2011-04-29 00:00:00 +01:00
14
18
  default_executable:
15
- dependencies: []
16
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails_sql_views
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
17
32
  description: |-
18
33
  CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance.
19
34
  For full information: http://peterhamilton.github.com/citier/
@@ -59,21 +74,24 @@ rdoc_options:
59
74
  require_paths:
60
75
  - lib
61
76
  required_ruby_version: !ruby/object:Gem::Requirement
62
- none: false
63
77
  requirements:
64
78
  - - ">="
65
79
  - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
66
82
  version: "0"
67
83
  required_rubygems_version: !ruby/object:Gem::Requirement
68
- none: false
69
84
  requirements:
70
85
  - - ">="
71
86
  - !ruby/object:Gem::Version
87
+ segments:
88
+ - 1
89
+ - 2
72
90
  version: "1.2"
73
91
  requirements: []
74
92
 
75
93
  rubyforge_project: citier
76
- rubygems_version: 1.6.2
94
+ rubygems_version: 1.3.6
77
95
  signing_key:
78
96
  specification_version: 3
79
97
  summary: "CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance. For full information: http://peterhamilton.github.com/citier/ For the original version by ALTRABio see www.github.com/altrabio/"