mongoid_ext 0.6.2 → 0.7.1
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/Gemfile +1 -1
- data/Gemfile.lock +20 -18
- data/VERSION +1 -1
- data/lib/mongoid_ext/criteria_ext.rb +0 -3
- data/lib/mongoid_ext/document_ext.rb +8 -10
- data/lib/mongoid_ext/file.rb +20 -4
- data/lib/mongoid_ext/file_list.rb +28 -2
- data/lib/mongoid_ext/filter/result_set.rb +3 -0
- data/lib/mongoid_ext/js/filter.js +42 -21
- data/lib/mongoid_ext/js/find_tags.js +7 -4
- data/lib/mongoid_ext/js/tag_cloud.js +17 -15
- data/lib/mongoid_ext/modifiers.rb +24 -25
- data/lib/mongoid_ext/paranoia.rb +1 -1
- data/lib/mongoid_ext/patches.rb +14 -1
- data/lib/mongoid_ext/storage.rb +23 -14
- data/lib/mongoid_ext/types/embedded_hash.rb +40 -5
- data/lib/mongoid_ext/types/open_struct.rb +13 -9
- data/lib/mongoid_ext/types/timestamp.rb +6 -4
- data/lib/mongoid_ext/types/translation.rb +4 -2
- data/lib/mongoid_ext/versioning.rb +62 -65
- data/lib/mongoid_ext/voteable.rb +8 -8
- data/mongoid_ext.gemspec +11 -13
- data/test/helper.rb +1 -2
- data/test/models.rb +1 -1
- data/test/test_storage.rb +1 -1
- data/test/types/test_open_struct.rb +1 -1
- metadata +172 -165
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,36 +1,37 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activemodel (3.
|
5
|
-
activesupport (= 3.
|
6
|
-
builder (~>
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
activemodel (3.2.1)
|
5
|
+
activesupport (= 3.2.1)
|
6
|
+
builder (~> 3.0.0)
|
7
|
+
activesupport (3.2.1)
|
8
|
+
i18n (~> 0.6)
|
9
|
+
multi_json (~> 1.0)
|
10
|
+
bson (1.5.2)
|
11
|
+
builder (3.0.0)
|
11
12
|
differ (0.1.2)
|
13
|
+
encryptor (1.1.3)
|
12
14
|
git (1.2.5)
|
13
|
-
i18n (0.
|
15
|
+
i18n (0.6.0)
|
14
16
|
jeweler (1.5.2)
|
15
17
|
bundler (~> 1.0.0)
|
16
18
|
git (>= 1.2.5)
|
17
19
|
rake
|
18
20
|
jnunemaker-matchy (0.4.0)
|
19
21
|
mocha (0.9.12)
|
20
|
-
mongo (1.
|
21
|
-
bson (
|
22
|
-
mongoid (2.
|
23
|
-
activemodel (~> 3.
|
22
|
+
mongo (1.5.2)
|
23
|
+
bson (= 1.5.2)
|
24
|
+
mongoid (2.4.4)
|
25
|
+
activemodel (~> 3.1)
|
24
26
|
mongo (~> 1.3)
|
25
27
|
tzinfo (~> 0.3.22)
|
26
|
-
|
27
|
-
rake (0.
|
28
|
+
multi_json (1.0.4)
|
29
|
+
rake (0.9.2.2)
|
28
30
|
shoulda (2.11.3)
|
29
31
|
timecop (0.3.5)
|
30
|
-
tzinfo (0.3.
|
32
|
+
tzinfo (0.3.31)
|
31
33
|
uuidtools (2.1.2)
|
32
|
-
|
33
|
-
yard (0.6.7)
|
34
|
+
yard (0.6.8)
|
34
35
|
|
35
36
|
PLATFORMS
|
36
37
|
ruby
|
@@ -38,11 +39,12 @@ PLATFORMS
|
|
38
39
|
DEPENDENCIES
|
39
40
|
bundler (~> 1.0.0)
|
40
41
|
differ (>= 0.1.2)
|
42
|
+
encryptor (~> 1.1.3)
|
41
43
|
i18n
|
42
44
|
jeweler (~> 1.5.2)
|
43
45
|
jnunemaker-matchy (~> 0.4)
|
44
46
|
mocha (~> 0.9.4)
|
45
|
-
mongoid (~> 2.
|
47
|
+
mongoid (~> 2.3)
|
46
48
|
shoulda (~> 2.11.3)
|
47
49
|
timecop
|
48
50
|
tzinfo
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.1
|
@@ -12,18 +12,16 @@ module MongoidExt
|
|
12
12
|
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
return true if !changed? && !opts.delete(:force)
|
15
|
+
def raw_save(opts = {})
|
16
|
+
return true if !changed? && !opts.delete(:force)
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
18
|
+
if (opts.delete(:validate) != false || valid?)
|
19
|
+
self.collection.save(raw_attributes, opts)
|
20
|
+
true
|
21
|
+
else
|
22
|
+
false
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
|
-
Mongoid::Document.send(:include, MongoidExt::DocumentExt)
|
27
|
+
Mongoid::Document.send(:include, MongoidExt::DocumentExt)
|
data/lib/mongoid_ext/file.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
module MongoidExt
|
2
2
|
class File < EmbeddedHash
|
3
3
|
attr_accessor :_root_document
|
4
|
+
attr_accessor :_list_name
|
4
5
|
|
5
6
|
field :name, :type => String
|
6
7
|
field :extension, :type => String
|
7
8
|
field :content_type, :type => String
|
9
|
+
field :md5, :type => String
|
8
10
|
|
9
11
|
alias :filename :name
|
10
12
|
|
11
13
|
def put(filename, io, options = {})
|
14
|
+
mark_parent!
|
15
|
+
|
12
16
|
options[:_id] = grid_filename
|
13
17
|
|
14
18
|
options[:metadata] ||= {}
|
@@ -26,7 +30,10 @@ module MongoidExt
|
|
26
30
|
if defined?(Magic) && Magic.respond_to?(:guess_string_mime_type)
|
27
31
|
data = io.read(256) # be nice with memory usage
|
28
32
|
self["content_type"] = options[:content_type] = Magic.guess_string_mime_type(data.to_s)
|
29
|
-
|
33
|
+
|
34
|
+
if self.fetch("extension", nil).nil?
|
35
|
+
self["extension"] = options[:content_type].to_s.split("/").last.split("-").last
|
36
|
+
end
|
30
37
|
|
31
38
|
if io.respond_to?(:rewind)
|
32
39
|
io.rewind
|
@@ -38,6 +45,11 @@ module MongoidExt
|
|
38
45
|
options[:filename] = grid_filename
|
39
46
|
gridfs.delete(grid_filename)
|
40
47
|
gridfs.put(io, options)
|
48
|
+
|
49
|
+
if file = self.get
|
50
|
+
file.send(:get_md5)
|
51
|
+
self['md5'] = file.server_md5
|
52
|
+
end
|
41
53
|
end
|
42
54
|
|
43
55
|
def get
|
@@ -61,11 +73,11 @@ module MongoidExt
|
|
61
73
|
end
|
62
74
|
|
63
75
|
def size
|
64
|
-
get.file_length
|
76
|
+
get.file_length rescue nil
|
65
77
|
end
|
66
78
|
|
67
79
|
def read(size = nil)
|
68
|
-
self.get.read(size)
|
80
|
+
self.get.read(size) rescue nil
|
69
81
|
end
|
70
82
|
|
71
83
|
def delete
|
@@ -74,7 +86,7 @@ module MongoidExt
|
|
74
86
|
end
|
75
87
|
|
76
88
|
def method_missing(name, *args, &block)
|
77
|
-
f = self.get
|
89
|
+
f = self.get
|
78
90
|
if f && f.respond_to?(name)
|
79
91
|
f.send(name, *args, &block)
|
80
92
|
else
|
@@ -86,5 +98,9 @@ module MongoidExt
|
|
86
98
|
def gridfs
|
87
99
|
_root_document.class.gridfs
|
88
100
|
end
|
101
|
+
|
102
|
+
def mark_parent!
|
103
|
+
_root_document.send("#{_list_name}_will_change!")
|
104
|
+
end
|
89
105
|
end
|
90
106
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
module MongoidExt
|
2
2
|
class FileList < EmbeddedHash
|
3
3
|
attr_accessor :parent_document
|
4
|
+
attr_accessor :list_name
|
4
5
|
|
5
6
|
def put(id, io, metadata = {})
|
7
|
+
mark_parent!
|
8
|
+
|
6
9
|
if !parent_document.new_record?
|
7
10
|
filename = id
|
8
11
|
if io.respond_to?(:original_filename)
|
@@ -33,20 +36,24 @@ module MongoidExt
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def get(id)
|
39
|
+
mark_parent!
|
40
|
+
|
36
41
|
if id.kind_of?(MongoidExt::File)
|
37
42
|
self[id.id] = id
|
38
43
|
return id
|
39
44
|
end
|
40
45
|
|
41
46
|
id = id.to_s.gsub(".", "_")
|
42
|
-
file = self
|
47
|
+
file = self.fetch(id, nil)
|
48
|
+
|
43
49
|
if file.nil?
|
44
50
|
file = self[id] = MongoidExt::File.new
|
45
|
-
elsif file.class == BSON::OrderedHash
|
51
|
+
elsif file.class == ::Hash || file.class == BSON::OrderedHash
|
46
52
|
file = self[id] = MongoidExt::File.new(file)
|
47
53
|
end
|
48
54
|
|
49
55
|
file._root_document = parent_document
|
56
|
+
file._list_name = self.list_name
|
50
57
|
file
|
51
58
|
end
|
52
59
|
|
@@ -60,6 +67,8 @@ module MongoidExt
|
|
60
67
|
end
|
61
68
|
|
62
69
|
def delete(id)
|
70
|
+
mark_parent!
|
71
|
+
|
63
72
|
file = self.get(id)
|
64
73
|
super(id)
|
65
74
|
file.delete
|
@@ -70,5 +79,22 @@ module MongoidExt
|
|
70
79
|
get(id).delete
|
71
80
|
end
|
72
81
|
end
|
82
|
+
|
83
|
+
def serialize(v)
|
84
|
+
v
|
85
|
+
end
|
86
|
+
|
87
|
+
def deserialize(v)
|
88
|
+
doc = self.class.new
|
89
|
+
v.each do |k,v|
|
90
|
+
doc[k] = MongoidExt::File.new(v)
|
91
|
+
end
|
92
|
+
|
93
|
+
doc
|
94
|
+
end
|
95
|
+
|
96
|
+
def mark_parent!
|
97
|
+
parent_document.send("#{list_name}_will_change!")
|
98
|
+
end
|
73
99
|
end
|
74
100
|
end
|
@@ -9,6 +9,8 @@ module MongoidExt
|
|
9
9
|
attr_reader :parsed_query
|
10
10
|
attr_reader :mongo_query
|
11
11
|
alias limit per_page
|
12
|
+
alias :total_count :total_entries
|
13
|
+
alias :limit_value :per_page
|
12
14
|
|
13
15
|
def initialize(total_entries, parsed_query, mongo_query, current_page, per_page=nil)
|
14
16
|
@total_entries = total_entries.to_i
|
@@ -21,6 +23,7 @@ module MongoidExt
|
|
21
23
|
def total_pages
|
22
24
|
(total_entries / per_page.to_f).ceil
|
23
25
|
end
|
26
|
+
alias :num_pages :total_pages
|
24
27
|
|
25
28
|
def out_of_bounds?
|
26
29
|
current_page > total_pages
|
@@ -8,28 +8,49 @@ function filter(collection, q, config) {
|
|
8
8
|
}
|
9
9
|
|
10
10
|
var time = new Date().getTime();
|
11
|
-
db[collection].find(q, fields).limit(500).forEach(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
var
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
11
|
+
db[collection].find(q, fields).limit(500).forEach(function(doc) {
|
12
|
+
var rac = db.eval(
|
13
|
+
function(doc, config) {
|
14
|
+
var r = [];
|
15
|
+
var c = 0;
|
16
|
+
|
17
|
+
var set = {};
|
18
|
+
for(var i = 0; i<doc._keywords.length; i++) {
|
19
|
+
set[doc._keywords[i]] = true;
|
20
|
+
}
|
21
|
+
|
22
|
+
var score = 0.0;
|
23
|
+
for(var i = 0; i < config.words.length; i++) {
|
24
|
+
var word = config.words[i];
|
25
|
+
if(set[word]) {
|
26
|
+
score += 15.0;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
for(var i = 0; i < config.stemmed.length; i++) {
|
31
|
+
var word = config.stemmed[i];
|
32
|
+
if(set[word]) {
|
33
|
+
score += (1.0 + word.length);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
if(score >= config.min_score || 1.0 ) {
|
38
|
+
delete doc._keywords;
|
39
|
+
r.push({'score': score, 'doc': doc});
|
40
|
+
c += 1;
|
41
|
+
}
|
42
|
+
|
43
|
+
return [r, c];
|
44
|
+
},
|
45
|
+
doc,
|
46
|
+
config
|
47
|
+
);
|
48
|
+
|
49
|
+
for(var i = 0; i<rac[0].length; i++) {
|
50
|
+
results.push(rac[0][i]);
|
31
51
|
}
|
32
|
-
|
52
|
+
counter += rac[1];
|
53
|
+
});
|
33
54
|
|
34
55
|
var sorted = results.sort(function(a,b) {
|
35
56
|
return b.score - a.score;
|
@@ -1,5 +1,6 @@
|
|
1
1
|
function find_tags(collection, regex, query, limit) {
|
2
|
-
var
|
2
|
+
var counts = db.eval(
|
3
|
+
function(collection, regex, query){
|
3
4
|
var counts = {};
|
4
5
|
db[collection].find(query, {"tags":1}).limit(500).forEach(
|
5
6
|
function(p){
|
@@ -13,9 +14,11 @@ function find_tags(collection, regex, query, limit) {
|
|
13
14
|
}
|
14
15
|
);
|
15
16
|
return counts;
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
},
|
18
|
+
collection,
|
19
|
+
regex,
|
20
|
+
query
|
21
|
+
);
|
19
22
|
|
20
23
|
var tags = [];
|
21
24
|
for ( var tag in counts ){
|
@@ -1,22 +1,24 @@
|
|
1
1
|
// TODO: port it to map reduce
|
2
2
|
function tagCloud(collection, q, limit) {
|
3
|
-
var
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
var
|
10
|
-
|
3
|
+
var counts = db.eval(
|
4
|
+
function(collection, q){
|
5
|
+
var counts = {constructor: 0};
|
6
|
+
db[collection].find(q, {"tags":1}).limit(500).forEach(
|
7
|
+
function(p){
|
8
|
+
if ( p.tags ){
|
9
|
+
for ( var i=0; i<p.tags.length; i++ ){
|
10
|
+
var name = p.tags[i];
|
11
|
+
counts[name] = 1 + ( counts[name] || 0 );
|
12
|
+
}
|
11
13
|
}
|
12
14
|
}
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
);
|
16
|
+
if(counts["constructor"] == 0) { delete counts.constructor; }
|
17
|
+
return counts;
|
18
|
+
},
|
19
|
+
collection,
|
20
|
+
q
|
21
|
+
);
|
20
22
|
|
21
23
|
// maybe sort to by nice
|
22
24
|
var sorted = [];
|
@@ -54,38 +54,37 @@ module MongoidExt
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
#InstanceMethods
|
58
|
+
def unset(update)
|
59
|
+
self.class.unset({:_id => id}, update)
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
def increment(update)
|
63
|
+
self.class.increment({:_id => id}, update)
|
64
|
+
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
def decrement(update)
|
67
|
+
self.class.decrement({:_id => id}, update)
|
68
|
+
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
def override(update)
|
71
|
+
self.class.override({:_id => id}, update)
|
72
|
+
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
def push(update)
|
75
|
+
self.class.push({:_id => id}, update)
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
def pull(update)
|
79
|
+
self.class.pull({:_id => id}, update)
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
def push_uniq(update)
|
83
|
+
self.class.push_uniq({:_id => id}, update)
|
84
|
+
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
end
|
86
|
+
def pop(update)
|
87
|
+
self.class.pop({:_id => id}, update)
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|