citier 0.1.12 → 0.1.13

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.
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/"