Took MongoMapper out of the bundle, trying to fix querying.

This commit is contained in:
Raphael 2010-12-20 16:53:56 -08:00
parent 049670654e
commit f043c9cc7e
22 changed files with 88 additions and 181 deletions

View file

@ -15,11 +15,6 @@ gem 'devise_invitable','0.3.5'
gem 'omniauth', '0.1.6'
gem 'twitter', :git => 'git://github.com/jnunemaker/twitter.git', :ref => 'ef122bbb280e229ed343'
#Mongo
gem 'mongo_mapper', :branch => 'rails3', :git => 'git://github.com/jnunemaker/mongomapper.git'
gem 'bson_ext', '1.1'
gem 'bson', '1.1'
#Views
gem 'haml'
gem 'will_paginate', '3.0.pre2'

View file

@ -29,16 +29,6 @@ GIT
addressable (>= 2.1.1)
eventmachine (>= 0.12.9)
GIT
remote: git://github.com/jnunemaker/mongomapper.git
revision: de8f8f3171f687f8d65b87ba7c7d3b1cb6e3bbe6
branch: rails3
specs:
mongo_mapper (0.8.6)
activemodel (~> 3.0.0)
activesupport (~> 3.0.0)
plucky (~> 0.3.6)
GIT
remote: git://github.com/jnunemaker/twitter.git
revision: ef122bbb280e229ed34347c235c68aa9349d0d8e
@ -111,8 +101,6 @@ GEM
uuidtools
xml-simple
bcrypt-ruby (2.1.2)
bson (1.1)
bson_ext (1.1)
builder (2.1.2)
bunny (0.6.0)
capybara (0.3.9)
@ -214,8 +202,6 @@ GEM
mocha (0.9.10)
rake
moneta (0.6.0)
mongo (1.1)
bson (>= 1.0.5)
mongrel (1.1.5)
cgi_multipart_eof_fix (>= 2.4)
daemons (>= 1.0.3)
@ -267,8 +253,6 @@ GEM
oa-enterprise (= 0.1.6)
oa-oauth (= 0.1.6)
oa-openid (= 0.1.6)
plucky (0.3.6)
mongo (~> 1.1)
polyglot (0.3.1)
pubsubhubbub (0.1.1)
em-http-request (>= 0.1.5)
@ -373,8 +357,6 @@ DEPENDENCIES
SystemTimer
addressable
aws
bson (= 1.1)
bson_ext (= 1.1)
bundler (>= 1.0.0)
capybara (~> 0.3.9)
carrierwave!
@ -396,7 +378,6 @@ DEPENDENCIES
launchy
mini_magick
mocha
mongo_mapper!
mongrel
mysql2
nokogiri (= 1.4.3.1)

View file

@ -16,7 +16,7 @@ module SocketsHelper
old_locale = I18n.locale
I18n.locale = user.language.to_s
end
if object.is_a? StatusMessage
post_hash = {:post => object,
:person => object.person,
@ -32,11 +32,11 @@ module SocketsHelper
v = render_to_string(:partial => 'shared/stream_element', :locals => post_hash)
elsif object.is_a? Person
person_hash = {
:single_aspect_form => opts["single_aspect_form"],
:single_aspect_form => opts["single_aspect_form"],
:person => object,
:aspects => user.aspects,
:contact => user.contact_for(object),
:request => user.request_for(object),
:request => user.request_from(object),
:current_user => user}
v = render_to_string(:partial => 'people/person', :locals => person_hash)
elsif object.is_a? Comment
@ -64,9 +64,9 @@ module SocketsHelper
end
action_hash[:mine?] = object.person && (object.person.owner.id == uid) if object.respond_to?(:person)
I18n.locale = old_locale unless user.nil?
action_hash.to_json
end

View file

@ -47,7 +47,7 @@ class Notifier < ActionMailer::Base
private
def log_mail recipient_id, sender_id, type
log_string = "event=mail mail_type=#{type} db_name=#{MongoMapper.database.name} recipient_id=#{recipient_id} sender_id=#{sender_id}"
log_string = "event=mail mail_type=#{type} recipient_id=#{recipient_id} sender_id=#{sender_id}"
if @receiver && @sender
log_string << "models_found=true sender_handle=#{@sender.diaspora_handle} recipient_handle=#{@receiver.diaspora_handle}"
else

View file

@ -22,16 +22,5 @@ class Aspect < ActiveRecord::Base
def to_s
name
end
def as_json(opts = {})
{
:aspect => {
:name => self.name,
:people => self.people.each{|person| person.as_json},
:posts => self.posts.each {|post| post.as_json },
}
}
end
end

View file

@ -33,8 +33,8 @@ class Post < ActiveRecord::Base
params[:aspect_ids].each do |aspect_id|
new_post.aspects << Aspect.find_by_id(aspect_id)
end if params[:aspect_ids]
new_post.public = params[:public]
new_post.pending = params[:pending]
new_post.public = params[:public] if params[:public]
new_post.pending = params[:pending] if params[:pending]
new_post.diaspora_handle = new_post.person.diaspora_handle
new_post
end

View file

@ -21,21 +21,21 @@ class Retraction
retraction.post_id = object.id
retraction.type = object.class.to_s
end
retraction.diaspora_handle = object.diaspora_handle
retraction.diaspora_handle = object.diaspora_handle
retraction
end
def perform receiving_user_id
Rails.logger.debug "Performing retraction for #{post_id}"
if self.type.constantize.find_by_id(post_id)
unless Post.first(:diaspora_handle => person.diaspora_handle, :id => post_id)
if self.type.constantize.find_by_id(post_id)
unless Post.where(:diaspora_handle => person.diaspora_handle, :id => post_id).first
Rails.logger.info("event=retraction status=abort reason='no post found authored by retractor' sender=#{person.diaspora_handle} post_id=#{post_id}")
return
return
end
begin
Rails.logger.debug("Retracting #{self.type} id: #{self.post_id}")
target = self.type.constantize.first(:id => self.post_id)
target = self.type.constantize.where(:id => self.post_id).first
target.unsocket_from_uid receiving_user_id if target.respond_to? :unsocket_from_uid
target.delete
rescue NameError

View file

@ -7,7 +7,7 @@ class StatusMessage < Post
include YoutubeTitles
require File.join(Rails.root, 'lib/youtube_titles')
include ActionView::Helpers::TextHelper
validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
xml_name :status_message
xml_accessor :message

View file

@ -97,9 +97,7 @@ class User < ActiveRecord::Base
contact = contact_for Person.find(person_id)
if opts[:force] || contact.aspect_ids.count > 1
contact.aspect_ids.delete aspect.id
contact.save!
aspect.save!
contact.aspects.delete(aspect)
else
raise "Can not delete a person from last aspect"
end

View file

@ -9,7 +9,6 @@ require 'rails/all'
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)
require File.expand_path('../../lib/mongo_mapper/bson_id', __FILE__)
require File.expand_path('../../lib/log_overrider', __FILE__)
require File.expand_path('../../lib/message_handler', __FILE__)
module Diaspora

View file

@ -2,7 +2,6 @@
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require File.expand_path('../../../lib/mongo_mapper/clear_dev_memory', __FILE__)
Diaspora::Application.configure do
# Settings specified here will take precedence over those in config/environment.rb
@ -22,6 +21,5 @@ Diaspora::Application.configure do
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.middleware.use MongoMapper::ClearDevMemory
#config.threadsafe!
end

View file

@ -36,11 +36,11 @@ Diaspora::Application.configure do
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongo_mapper"
rescue LoadError => ignore_if_database_cleaner_not_present
puts "Error on cleaner"
end
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.orm = "active_record"
rescue LoadError => ignore_if_database_cleaner_not_present
puts "Error on cleaner"
end
end

View file

@ -1,16 +0,0 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
ENV['MONGODB_URL'] = ENV['MONGOHQ_URL'] || URI::Generic.build(:scheme => 'mongodb', :host => APP_CONFIG[:mongo_host], :port => APP_CONFIG[:mongo_port], :path => "/diaspora-#{Rails.env}").to_s
MongoMapper.config = {::Rails.env => {'uri' => ENV['MONGODB_URL']}}
MongoMapper.connect ::Rails.env
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
MongoMapper.connection.connect if forked
end
end
puts "Security Warning (11/29/2010): if you are using Diaspora on the internet, please make sure your mongodb is started with '--bind 127.0.0.1' or you are using a database password"

View file

@ -11,18 +11,16 @@ module Diaspora
end
def raw_visible_posts
Post.joins(:aspects).where(:aspects => {:user_id => self.id})
Post.joins(:post_visibilities => :aspect).where(:pending => false, :post_visibilities => {:aspects => {:user_id => self.id}})
end
def visible_posts( opts = {} )
order = opts.delete(:order)
order ||= 'created_at DESC'
opts[:pending] ||= false
opts[:type] ||= ["StatusMessage","Photo"]
if opts[:by_members_of] && opts[:by_members_of] != :all
aspect = opts[:by_members_of] unless opts[:by_members_of].user_id != self.id
Post.joins(:aspects).where(:aspects => {:id => aspect.id}).order(order)
if (aspect = opts[:by_members_of]) && opts[:by_members_of] != :all
raw_visible_posts.where(:aspects => {:id => aspect.id}).order(order)
else
self.raw_visible_posts.where(opts).order(order)
end
@ -36,11 +34,6 @@ module Diaspora
Contact.where(:user_id => self.id, :person_id => person_id).first if person_id
end
def contacts_not_in_aspect( aspect )
person_ids = Contact.where(:user_id => self.id, :aspect_ids.ne => aspect.id).collect{|x| x.person_id }
Person.all(:id.in => person_ids)
end
def people_in_aspects(aspects, opts={})
person_ids = contacts_in_aspects(aspects).collect{|contact| contact.person_id}
people = Person.where(:id => person_ids)
@ -67,8 +60,8 @@ module Diaspora
self.aspects.all.collect{|x| x.id}
end
def request_for(to_person)
Request.from(self.person).to(to_person).first
def request_from(person)
Request.where(:sender_id => person.id, :recipient_id => self.person.id)
end
def posts_from(person)

View file

@ -1,18 +0,0 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class String
def to_id
begin
BSON::ObjectId self
rescue
nil
end
end
end
class BSON::ObjectId
def to_id
self
end
end

View file

@ -1,23 +0,0 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
module MongoMapper
class ClearDevMemory
def initialize(app)
@app = app
end
def call(env)
if Rails.configuration.cache_classes
else
MongoMapper::Document.descendants.each do |m|
m.descendants.clear if m.respond_to? :descendants
end
MongoMapper::Document.descendants.clear
MongoMapper::EmbeddedDocument.descendants.clear
end
@app.call(env)
end
end
end

View file

@ -33,15 +33,10 @@ describe Aspect do
aspect.valid?.should == false
end
it 'should not be creatable with people' do
aspect = user.aspects.create(:name => 'losers', :contacts => [connected_person, connected_person_2])
aspect.contacts.size.should == 0
end
it 'should be able to have other users' do
Contact.create(:user => user, :person => user2.person, :aspects => [aspect])
aspect.contacts.first(:person_id => user.person.id).should be_nil
aspect.contacts.first(:person_id => user2.person.id).should_not be_nil
aspect.contacts.where(:person_id => user.person.id).should be_empty
aspect.contacts.where(:person_id => user2.person.id).should_not be_empty
aspect.contacts.size.should == 1
end
@ -108,7 +103,8 @@ describe Aspect do
describe 'posting' do
it 'should add post to aspect via post method' do
aspect = user.aspects.create(:name => 'losers', :contacts => [connected_person])
aspect = user.aspects.create(:name => 'losers')
contact = aspect.contacts.create(:person => connected_person)
status_message = user.post( :status_message, :message => "hey", :to => aspect.id )
@ -140,8 +136,7 @@ describe Aspect do
fantasy_resque do
retraction = user2.retract(message)
end
aspect.reload
aspect.post_ids.include?(message.id).should be false
aspect.posts(true).include?(message).should be false
end
end
@ -173,7 +168,7 @@ describe Aspect do
user.reload
user.delete_person_from_aspect(user2.person.id, aspect1.id)
user.reload
aspect1.reload.contacts.include?(@contact).should be false
aspect1.contacts(true).include?(@contact).should be_false
end
it 'should check to make sure you have the aspect ' do
@ -227,11 +222,9 @@ describe Aspect do
describe '#move_contact' do
it 'should be able to move a contact from one of users existing aspects to another' do
user.move_contact(user2.person, aspect1, aspect)
aspect.reload
aspect1.reload
aspect.contacts.include?(@contact).should be_false
aspect1.contacts.include?(@contact).should be_true
aspect.contacts(true).include?(@contact).should be_false
aspect1.contacts(true).include?(@contact).should be_true
end
it "should not move a person who is not a contact" do
@ -241,8 +234,8 @@ describe Aspect do
aspect.reload
aspect1.reload
aspect.contacts.first(:person_id => connected_person.id).should be_nil
aspect1.contacts.first(:person_id => connected_person.id).should be_nil
aspect.contacts.where(:person_id => connected_person.id).should be_empty
aspect1.contacts.where(:person_id => connected_person.id).should be_empty
end
it 'does not try to delete if add person did not go through' do

View file

@ -76,7 +76,7 @@ describe Contact do
end
it 'persists no request' do
@contact.dispatch_request
Request.from(@user).to(@person).first.should be_nil
Request.where(:sender_id => @user.person.id, :recipient_id => @person.id).should be_empty
end
end
end

View file

@ -10,15 +10,14 @@ describe Profile do
it "strips leading and trailing whitespace" do
profile = Factory.build(:profile, :first_name => " Shelly ")
profile.should be_valid
pp profile
profile.first_name.should == "Shelly"
end
it "can be 32 characters long" do
profile = Factory.build(:profile, :first_name => "Hexagoooooooooooooooooooooooooon")
profile.should be_valid
end
it "cannot be 33 characters" do
profile = Factory.build(:profile, :first_name => "Hexagooooooooooooooooooooooooooon")
profile.should_not be_valid
@ -30,12 +29,12 @@ describe Profile do
profile.should be_valid
profile.last_name.should == "Ohba"
end
it "can be 32 characters long" do
profile = Factory.build(:profile, :last_name => "Hexagoooooooooooooooooooooooooon")
profile.should be_valid
end
it "cannot be 33 characters" do
profile = Factory.build(:profile, :last_name => "Hexagooooooooooooooooooooooooooon")
profile.should_not be_valid

View file

@ -31,7 +31,10 @@ describe StatusMessage do
end
it 'should be postable through the user' do
status = @user.post(:status_message, :message => "Users do things", :to => @aspect.id)
message = "Users do things"
status = @user.post(:status_message, :message => message, :to => @aspect.id)
db_status = StatusMessage.find(status.id)
db_status.message.should == message
end
it 'should require status messages to be less than 1000 characters' do
@ -40,7 +43,7 @@ describe StatusMessage do
status = Factory.build(:status_message, :message => message)
status.should_not be_valid
end
describe "XML" do
@ -69,7 +72,7 @@ describe StatusMessage do
[nil, 'Foobar <title>'+expected_title+'</title> hallo welt <asd><dasdd><a>dsd</a>'])
post = @user.build_post :status_message, :message => url, :to => @aspect.id
post.save!
post[:youtube_titles].should == {video_id => expected_title}
end

View file

@ -58,6 +58,10 @@ describe User do
end
describe '#build_post' do
it 'sets status_message#message' do
post = user.build_post(:status_message, :message => "hey", :to => aspect.id)
post.message.should == "hey"
end
it 'does not save a status_message' do
post = user.build_post(:status_message, :message => "hey", :to => aspect.id)
post.persisted?.should be_false

View file

@ -33,41 +33,60 @@ describe User do
end
context 'with two posts' do
let!(:status_message1) { @user2.post :status_message, :message => "hi", :to => @aspect2.id }
let!(:status_message2) { @user2.post :status_message, :message => "hey", :public => true , :to => @aspect2.id }
let!(:status_message4) { @user2.post :status_message, :message => "blah", :public => true , :to => @aspect2.id }
let!(:status_message3) { @user.post :status_message, :message => "hey", :public => true , :to => @aspect.id }
before do
connect_users(@user2, @aspect2, @user, @aspect)
aspect3 = @user.aspects.create(:name => "Snoozers")
@status_message1 = @user2.post :status_message, :message => "hi", :to => @aspect2.id
pp @status_message1
@status_message2 = @user2.post :status_message, :message => "hey", :public => true , :to => @aspect2.id
@status_message3 = @user.post :status_message, :message => "hey", :public => true , :to => @aspect.id
@status_message4 = @user2.post :status_message, :message => "blah", :public => true , :to => @aspect2.id
@status_message5 = @user.post :status_message, :message => "secrets", :to => aspect3.id
let!(:pending_status_message) { @user2.post :status_message, :message => "hey", :public => true , :to => @aspect2.id, :pending => true }
@pending_status_message = @user2.post :status_message, :message => "hey", :public => true , :to => @aspect2.id, :pending => true
end
describe "#visible_posts" do
it "queries by person id" do
query = @user2.visible_posts(:person_id => @user2.person.id)
query.include?(status_message1).should == true
query.include?(status_message2).should == true
query.include?(@status_message1).should == true
query.include?(@status_message2).should == true
query.include?(@status_message3).should == false
query.include?(@status_message4).should == true
query.include?(@status_message5).should == false
end
it "selects public posts" do
query = @user2.visible_posts(:public => true)
query.include?(status_message2).should == true
query.include?(status_message1).should == false
query.include?(@status_message1).should == false
query.include?(@status_message2).should == true
query.include?(@status_message3).should == true
query.include?(@status_message4).should == true
query.include?(@status_message5).should == false
end
it "selects non public posts" do
query = @user2.visible_posts(:public => false)
query.include?(status_message1).should == true
query.include?(status_message2).should == false
query.include?(@status_message1).should == true
query.include?(@status_message2).should == false
query.include?(@status_message3).should == false
query.include?(@status_message4).should == false
query.include?(@status_message5).should == false
end
it "selects by message contents" do
@user2.visible_posts(:message => "hi").include?(status_message1).should == true
query = @user2.visible_posts(:message => "hi")
pp @status_message1
pp query.to_sql
pp query
query.should == [@status_message1]
end
it "does not return pending posts" do
pending_status_message.pending.should be_true
@user2.visible_posts.should_not include pending_status_message
@pending_status_message.pending.should be_true
@user2.visible_posts.should_not include @pending_status_message
@user2.visible_posts(:by_members_of => @aspect2).should_not include pending_status_message
@user2.visible_posts(:by_members_of => @aspect2).should_not include @pending_status_message
end
context 'with two users' do
@ -100,13 +119,6 @@ describe User do
connect_users(user, second_aspect, @user2, @user2.aspects.first)
end
describe '#contacts_not_in_aspect' do
it 'finds the people who are not in the given aspect' do
people = @user.contacts_not_in_aspect(first_aspect)
people.should == [@user2.person]
end
end
describe '#people_in_aspects' do
it 'returns people objects for a users contact in each aspect' do
people = @user.people_in_aspects([first_aspect])
@ -196,13 +208,13 @@ describe User do
let!(:user5) {Factory(:user)}
it 'should not have a pending request before connecting' do
request = @user.request_for(user5.person)
request = @user.request_from(user5.person)
request.should be_nil
end
it 'should have a pending request after sending a request' do
@user.send_contact_request_to(user5.person, @user.aspects.first)
request = @user.reload.request_for(user5.person)
request = @user.reload.request_from(user5.person)
request.should_not be_nil
end
end