lib/vines/storage/sql.rb in vines-0.1.1 vs lib/vines/storage/sql.rb in vines-0.2.0

- old
+ new

@@ -6,13 +6,17 @@ register :sql class Contact < ActiveRecord::Base belongs_to :user end + class Fragment < ActiveRecord::Base + belongs_to :user + end class Group < ActiveRecord::Base; end class User < ActiveRecord::Base has_many :contacts + has_many :fragments end %w[adapter host port database username password pool].each do |name| define_method(name) do |*args| if args.first @@ -36,11 +40,11 @@ def find_user(jid) ActiveRecord::Base.clear_reloadable_connections! jid = JID.new(jid || '').bare.to_s return if jid.empty? - xuser = by_jid(jid) + xuser = user_by_jid(jid) return Vines::User.new(:jid => jid).tap do |user| user.name, user.password = xuser.name, xuser.password xuser.contacts.each do |contact| groups = contact.groups.map {|group| group.name } user.roster << Vines::Contact.new( @@ -55,11 +59,11 @@ defer :find_user def save_user(user) ActiveRecord::Base.clear_reloadable_connections! - xuser = by_jid(user.jid) || Sql::User.new(:jid => user.jid.bare.to_s) + xuser = user_by_jid(user.jid) || Sql::User.new(:jid => user.jid.bare.to_s) xuser.name = user.name xuser.password = user.password # remove deleted contacts from roster xuser.contacts.delete(xuser.contacts.select do |contact| @@ -95,27 +99,52 @@ def find_vcard(jid) ActiveRecord::Base.clear_reloadable_connections! jid = JID.new(jid || '').bare.to_s return if jid.empty? - if xuser = by_jid(jid) + if xuser = user_by_jid(jid) Nokogiri::XML(xuser.vcard).root rescue nil end end defer :find_vcard def save_vcard(jid, card) ActiveRecord::Base.clear_reloadable_connections! - xuser = by_jid(jid) + xuser = user_by_jid(jid) if xuser xuser.vcard = card.to_xml xuser.save end end defer :save_vcard + def find_fragment(jid, node) + ActiveRecord::Base.clear_reloadable_connections! + + jid = JID.new(jid || '').bare.to_s + return if jid.empty? + if fragment = fragment_by_jid(jid, node) + Nokogiri::XML(fragment.xml).root rescue nil + end + end + defer :find_fragment + + def save_fragment(jid, node) + ActiveRecord::Base.clear_reloadable_connections! + + jid = JID.new(jid).bare.to_s + fragment = fragment_by_jid(jid, node) || + Sql::Fragment.new( + :user => user_by_jid(jid), + :root => node.name, + :namespace => node.namespace.href) + fragment.xml = node.to_xml + fragment.save + end + defer :save_fragment + # Create the tables and indexes used by this storage engine. def create_schema(args={}) ActiveRecord::Base.clear_reloadable_connections! args[:force] ||= false @@ -146,10 +175,18 @@ create_table :contacts_groups, :id => false, :force => args[:force] do |t| t.integer :contact_id, :null => false t.integer :group_id, :null => false end add_index :contacts_groups, [:contact_id, :group_id], :unique => true + + create_table :fragments, :force => args[:force] do |t| + t.integer :user_id, :null => false + t.string :root, :limit => 1000, :null => false + t.string :namespace, :limit => 1000, :null => false + t.text :xml, :null => false + end + add_index :fragments, [:user_id, :root, :namespace], :unique => true end end private @@ -159,12 +196,18 @@ # associations here rather than in the class definitions above. Sql::Contact.has_and_belongs_to_many :groups Sql::Group.has_and_belongs_to_many :contacts end - def by_jid(jid) + def user_by_jid(jid) jid = JID.new(jid).bare.to_s Sql::User.find_by_jid(jid, :include => {:contacts => :groups}) + end + + def fragment_by_jid(jid, node) + jid = JID.new(jid).bare.to_s + clause = 'user_id=(select id from users where jid=?) and root=? and namespace=?' + Sql::Fragment.where(clause, jid, node.name, node.namespace.href).first end def groups(contact) contact.groups.map {|name| Sql::Group.find_or_create_by_name(name.strip) } end