better-ripple 1.0.0
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/LICENSE +17 -0
- data/README.md +182 -0
- data/RELEASE_NOTES.md +284 -0
- data/better-ripple.gemspec +55 -0
- data/lib/rails/generators/ripple/configuration/configuration_generator.rb +13 -0
- data/lib/rails/generators/ripple/configuration/templates/ripple.yml +25 -0
- data/lib/rails/generators/ripple/js/js_generator.rb +13 -0
- data/lib/rails/generators/ripple/js/templates/js/contrib.js +63 -0
- data/lib/rails/generators/ripple/js/templates/js/iso8601.js +76 -0
- data/lib/rails/generators/ripple/js/templates/js/ripple.js +132 -0
- data/lib/rails/generators/ripple/model/model_generator.rb +20 -0
- data/lib/rails/generators/ripple/model/templates/model.rb.erb +10 -0
- data/lib/rails/generators/ripple/observer/observer_generator.rb +16 -0
- data/lib/rails/generators/ripple/observer/templates/observer.rb.erb +2 -0
- data/lib/rails/generators/ripple/test/templates/cucumber.rb.erb +7 -0
- data/lib/rails/generators/ripple/test/test_generator.rb +44 -0
- data/lib/rails/generators/ripple_generator.rb +79 -0
- data/lib/ripple.rb +86 -0
- data/lib/ripple/associations.rb +380 -0
- data/lib/ripple/associations/embedded.rb +35 -0
- data/lib/ripple/associations/instantiators.rb +26 -0
- data/lib/ripple/associations/linked.rb +65 -0
- data/lib/ripple/associations/many.rb +38 -0
- data/lib/ripple/associations/many_embedded_proxy.rb +39 -0
- data/lib/ripple/associations/many_linked_proxy.rb +66 -0
- data/lib/ripple/associations/many_reference_proxy.rb +95 -0
- data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
- data/lib/ripple/associations/one.rb +20 -0
- data/lib/ripple/associations/one_embedded_proxy.rb +35 -0
- data/lib/ripple/associations/one_key_proxy.rb +58 -0
- data/lib/ripple/associations/one_linked_proxy.rb +26 -0
- data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
- data/lib/ripple/associations/proxy.rb +118 -0
- data/lib/ripple/attribute_methods.rb +132 -0
- data/lib/ripple/attribute_methods/dirty.rb +59 -0
- data/lib/ripple/attribute_methods/query.rb +34 -0
- data/lib/ripple/attribute_methods/read.rb +28 -0
- data/lib/ripple/attribute_methods/write.rb +25 -0
- data/lib/ripple/callbacks.rb +71 -0
- data/lib/ripple/conflict/basic_resolver.rb +86 -0
- data/lib/ripple/conflict/document_hooks.rb +46 -0
- data/lib/ripple/conflict/resolver.rb +79 -0
- data/lib/ripple/conflict/test_helper.rb +34 -0
- data/lib/ripple/conversion.rb +29 -0
- data/lib/ripple/core_ext.rb +3 -0
- data/lib/ripple/core_ext/casting.rb +151 -0
- data/lib/ripple/core_ext/indexes.rb +89 -0
- data/lib/ripple/core_ext/object.rb +8 -0
- data/lib/ripple/document.rb +105 -0
- data/lib/ripple/document/bucket_access.rb +25 -0
- data/lib/ripple/document/finders.rb +131 -0
- data/lib/ripple/document/key.rb +35 -0
- data/lib/ripple/document/link.rb +30 -0
- data/lib/ripple/document/persistence.rb +130 -0
- data/lib/ripple/embedded_document.rb +63 -0
- data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
- data/lib/ripple/embedded_document/finders.rb +26 -0
- data/lib/ripple/embedded_document/persistence.rb +75 -0
- data/lib/ripple/i18n.rb +5 -0
- data/lib/ripple/indexes.rb +151 -0
- data/lib/ripple/inspection.rb +32 -0
- data/lib/ripple/locale/en.yml +26 -0
- data/lib/ripple/locale/fr.yml +24 -0
- data/lib/ripple/nested_attributes.rb +275 -0
- data/lib/ripple/observable.rb +28 -0
- data/lib/ripple/properties.rb +74 -0
- data/lib/ripple/property_type_mismatch.rb +12 -0
- data/lib/ripple/railtie.rb +26 -0
- data/lib/ripple/railties/ripple.rake +103 -0
- data/lib/ripple/serialization.rb +82 -0
- data/lib/ripple/test_server.rb +35 -0
- data/lib/ripple/timestamps.rb +25 -0
- data/lib/ripple/translation.rb +18 -0
- data/lib/ripple/validations.rb +65 -0
- data/lib/ripple/validations/associated_validator.rb +43 -0
- data/lib/ripple/version.rb +3 -0
- metadata +310 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
# This file is auto-generated!
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY!
|
3
|
+
# Instead, edit the Rakefile and run 'rake gemspec:generate'.# -*- encoding: utf-8 -*-
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "better-ripple"
|
7
|
+
s.version = "1.0.0"
|
8
|
+
|
9
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
|
+
s.authors = ["Jon Frisby", "Sean Cribbs"]
|
11
|
+
s.date = "2012-10-10"
|
12
|
+
s.description = "better-ripple is an improved version of ripple, an object-mapper library for Riak. It uses ActiveModel to provide an experience that integrates well with Rails 3 applications."
|
13
|
+
s.email = ["jon@cloudability.com", "sean@basho.com"]
|
14
|
+
s.files = ["LICENSE", "README.md", "RELEASE_NOTES.md", "better-ripple.gemspec", "lib/rails/generators/ripple/configuration/configuration_generator.rb", "lib/rails/generators/ripple/configuration/templates/ripple.yml", "lib/rails/generators/ripple/js/js_generator.rb", "lib/rails/generators/ripple/js/templates/js/contrib.js", "lib/rails/generators/ripple/js/templates/js/iso8601.js", "lib/rails/generators/ripple/js/templates/js/ripple.js", "lib/rails/generators/ripple/model/model_generator.rb", "lib/rails/generators/ripple/model/templates/model.rb.erb", "lib/rails/generators/ripple/observer/observer_generator.rb", "lib/rails/generators/ripple/observer/templates/observer.rb.erb", "lib/rails/generators/ripple/test/templates/cucumber.rb.erb", "lib/rails/generators/ripple/test/test_generator.rb", "lib/rails/generators/ripple_generator.rb", "lib/ripple.rb", "lib/ripple/associations.rb", "lib/ripple/associations/embedded.rb", "lib/ripple/associations/instantiators.rb", "lib/ripple/associations/linked.rb", "lib/ripple/associations/many.rb", "lib/ripple/associations/many_embedded_proxy.rb", "lib/ripple/associations/many_linked_proxy.rb", "lib/ripple/associations/many_reference_proxy.rb", "lib/ripple/associations/many_stored_key_proxy.rb", "lib/ripple/associations/one.rb", "lib/ripple/associations/one_embedded_proxy.rb", "lib/ripple/associations/one_key_proxy.rb", "lib/ripple/associations/one_linked_proxy.rb", "lib/ripple/associations/one_stored_key_proxy.rb", "lib/ripple/associations/proxy.rb", "lib/ripple/attribute_methods.rb", "lib/ripple/attribute_methods/dirty.rb", "lib/ripple/attribute_methods/query.rb", "lib/ripple/attribute_methods/read.rb", "lib/ripple/attribute_methods/write.rb", "lib/ripple/callbacks.rb", "lib/ripple/conflict/basic_resolver.rb", "lib/ripple/conflict/document_hooks.rb", "lib/ripple/conflict/resolver.rb", "lib/ripple/conflict/test_helper.rb", "lib/ripple/conversion.rb", "lib/ripple/core_ext.rb", "lib/ripple/core_ext/casting.rb", "lib/ripple/core_ext/indexes.rb", "lib/ripple/core_ext/object.rb", "lib/ripple/document.rb", "lib/ripple/document/bucket_access.rb", "lib/ripple/document/finders.rb", "lib/ripple/document/key.rb", "lib/ripple/document/link.rb", "lib/ripple/document/persistence.rb", "lib/ripple/embedded_document.rb", "lib/ripple/embedded_document/around_callbacks.rb", "lib/ripple/embedded_document/finders.rb", "lib/ripple/embedded_document/persistence.rb", "lib/ripple/i18n.rb", "lib/ripple/indexes.rb", "lib/ripple/inspection.rb", "lib/ripple/locale/en.yml", "lib/ripple/locale/fr.yml", "lib/ripple/nested_attributes.rb", "lib/ripple/observable.rb", "lib/ripple/properties.rb", "lib/ripple/property_type_mismatch.rb", "lib/ripple/railtie.rb", "lib/ripple/railties/ripple.rake", "lib/ripple/serialization.rb", "lib/ripple/test_server.rb", "lib/ripple/timestamps.rb", "lib/ripple/translation.rb", "lib/ripple/validations.rb", "lib/ripple/validations/associated_validator.rb", "lib/ripple/version.rb"]
|
15
|
+
s.homepage = "http://github.com/cloudability/better-ripple"
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubygems_version = "1.8.24"
|
18
|
+
s.summary = "better-ripple is an improved version of ripple, an object-mapper library for Riak."
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
s.specification_version = 3
|
22
|
+
|
23
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
24
|
+
s.add_runtime_dependency(%q<better-riak-client>, ["~> 1.0.0"])
|
25
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
|
26
|
+
s.add_development_dependency(%q<activesupport>, [">= 3.0.0"])
|
27
|
+
s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0"])
|
28
|
+
s.add_development_dependency(%q<activemodel>, [">= 3.0.0"])
|
29
|
+
s.add_runtime_dependency(%q<tzinfo>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
31
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
32
|
+
s.add_development_dependency(%q<ammeter>, ["~> 0.2.2"])
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<better-riak-client>, ["~> 1.0.0"])
|
35
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
36
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
37
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
38
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
39
|
+
s.add_dependency(%q<tzinfo>, [">= 0"])
|
40
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
41
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
42
|
+
s.add_dependency(%q<ammeter>, ["~> 0.2.2"])
|
43
|
+
end
|
44
|
+
else
|
45
|
+
s.add_dependency(%q<better-riak-client>, ["~> 1.0.0"])
|
46
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
47
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
48
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
49
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
50
|
+
s.add_dependency(%q<tzinfo>, [">= 0"])
|
51
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
52
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
53
|
+
s.add_dependency(%q<ammeter>, ["~> 0.2.2"])
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/ripple_generator'
|
2
|
+
|
3
|
+
module Ripple
|
4
|
+
module Generators
|
5
|
+
class ConfigurationGenerator < Base
|
6
|
+
desc 'Generates a configuration file for Ripple.'
|
7
|
+
|
8
|
+
def create_configuration_file
|
9
|
+
template 'ripple.yml', 'config/ripple.yml'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Configure Riak connections for the Ripple library.
|
2
|
+
development:
|
3
|
+
http_port: 8098
|
4
|
+
pb_port: 8087
|
5
|
+
host: 127.0.0.1
|
6
|
+
source: /usr/local/bin #Default for Homebrew.
|
7
|
+
|
8
|
+
# The test environment has additional keys for configuring the
|
9
|
+
# Riak::TestServer for your test/spec suite:
|
10
|
+
#
|
11
|
+
# * bin_dir specifies the path to the "riak" script that you use to
|
12
|
+
# start Riak (just the directory)
|
13
|
+
# * js_source_dir specifies where your custom Javascript functions for
|
14
|
+
# MapReduce should be loaded from. Usually app/mapreduce.
|
15
|
+
test:
|
16
|
+
http_port: 9000
|
17
|
+
pb_port: 9002
|
18
|
+
host: 127.0.0.1
|
19
|
+
source: /usr/local/bin # Default for Homebrew.
|
20
|
+
js_source_dir: <%%= Rails.root + "app/mapreduce" %>
|
21
|
+
|
22
|
+
production:
|
23
|
+
http_port: 8098
|
24
|
+
pb_port: 8087
|
25
|
+
host: 127.0.0.1
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/ripple_generator'
|
2
|
+
|
3
|
+
module Ripple
|
4
|
+
module Generators
|
5
|
+
class JsGenerator < Base
|
6
|
+
desc 'Generates Javascript built-ins for use in your queries.'
|
7
|
+
|
8
|
+
def create_js_files
|
9
|
+
directory 'js', 'app/mapreduce'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
// -------------------------------------------------------------------
|
2
|
+
//
|
3
|
+
// This file contains Javascript MapReduce functions copied from the
|
4
|
+
// "Riak Function Contrib" project.
|
5
|
+
//
|
6
|
+
Riak.Contrib = {
|
7
|
+
// Count keys in a group of results.
|
8
|
+
// http://contrib.basho.com/count_keys.html
|
9
|
+
mapCount: function(){
|
10
|
+
return [1];
|
11
|
+
},
|
12
|
+
|
13
|
+
// Generate commonly used statistics from an array of numbers.
|
14
|
+
// Supports count, sum, min, max, percentiles, mean, variance, and
|
15
|
+
// stddev.
|
16
|
+
// http://contrib.basho.com/stats.html
|
17
|
+
reduceStats: function(data) {
|
18
|
+
var result = {};
|
19
|
+
|
20
|
+
data.sort(function(a,b){return a-b;});
|
21
|
+
result.count = data.length;
|
22
|
+
|
23
|
+
// Since the data is sorted, the minimum value
|
24
|
+
// is at the beginning of the array, the median
|
25
|
+
// value is in the middle of the array, and the
|
26
|
+
// maximum value is at the end of the array.
|
27
|
+
result.min = data[0];
|
28
|
+
result.max = data[data.length - 1];
|
29
|
+
|
30
|
+
var ntileFunc = function(percentile){
|
31
|
+
if (data.length == 1) return data[0];
|
32
|
+
var ntileRank = ((percentile/100) * (data.length - 1)) + 1;
|
33
|
+
var integralRank = Math.floor(ntileRank);
|
34
|
+
var fractionalRank = ntileRank - integralRank;
|
35
|
+
var lowerValue = data[integralRank-1];
|
36
|
+
var upperValue = data[integralRank];
|
37
|
+
return (fractionalRank * (upperValue - lowerValue)) + lowerValue;
|
38
|
+
};
|
39
|
+
|
40
|
+
result.percentile25 = ntileFunc(25);
|
41
|
+
result.median = ntileFunc(50);
|
42
|
+
result.percentile75 = ntileFunc(75);
|
43
|
+
result.percentile99 = ntileFunc(99);
|
44
|
+
|
45
|
+
// Compute the mean and variance using a
|
46
|
+
// numerically stable algorithm.
|
47
|
+
var sqsum = 0;
|
48
|
+
result.mean = data[0];
|
49
|
+
result.sum = result.mean * result.count;
|
50
|
+
for (var i = 1; i < data.length; ++i) {
|
51
|
+
var x = data[i];
|
52
|
+
var delta = x - result.mean;
|
53
|
+
var sweep = i + 1.0;
|
54
|
+
result.mean += delta / sweep;
|
55
|
+
sqsum += delta * delta * (i / sweep);
|
56
|
+
result.sum += x;
|
57
|
+
}
|
58
|
+
result.variance = sqsum / result.count;
|
59
|
+
result.sdev = Math.sqrt(result.variance);
|
60
|
+
|
61
|
+
return result;
|
62
|
+
}
|
63
|
+
};
|
@@ -0,0 +1,76 @@
|
|
1
|
+
// Written by Paul Sowden, 2005
|
2
|
+
// http://delete.me.uk/2005/03/iso8601.html
|
3
|
+
// Released under the Academic Free License
|
4
|
+
|
5
|
+
Date.prototype.setISO8601 = function (string) {
|
6
|
+
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
|
7
|
+
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
|
8
|
+
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
|
9
|
+
var d = string.match(new RegExp(regexp));
|
10
|
+
|
11
|
+
var offset = 0;
|
12
|
+
var date = new Date(d[1], 0, 1);
|
13
|
+
|
14
|
+
if (d[3]) { date.setMonth(d[3] - 1); }
|
15
|
+
if (d[5]) { date.setDate(d[5]); }
|
16
|
+
if (d[7]) { date.setHours(d[7]); }
|
17
|
+
if (d[8]) { date.setMinutes(d[8]); }
|
18
|
+
if (d[10]) { date.setSeconds(d[10]); }
|
19
|
+
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
|
20
|
+
if (d[14]) {
|
21
|
+
offset = (Number(d[16]) * 60) + Number(d[17]);
|
22
|
+
offset *= ((d[15] == '-') ? 1 : -1);
|
23
|
+
}
|
24
|
+
|
25
|
+
offset -= date.getTimezoneOffset();
|
26
|
+
time = (Number(date) + (offset * 60 * 1000));
|
27
|
+
this.setTime(Number(time));
|
28
|
+
}
|
29
|
+
|
30
|
+
Date.prototype.iso8601 = function (format, offset) {
|
31
|
+
/* accepted values for the format [1-6]:
|
32
|
+
1 Year:
|
33
|
+
YYYY (eg 1997)
|
34
|
+
2 Year and month:
|
35
|
+
YYYY-MM (eg 1997-07)
|
36
|
+
3 Complete date:
|
37
|
+
YYYY-MM-DD (eg 1997-07-16)
|
38
|
+
4 Complete date plus hours and minutes:
|
39
|
+
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
|
40
|
+
5 Complete date plus hours, minutes and seconds:
|
41
|
+
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
|
42
|
+
6 Complete date plus hours, minutes, seconds and a decimal
|
43
|
+
fraction of a second
|
44
|
+
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
|
45
|
+
*/
|
46
|
+
if (!format) { var format = 6; }
|
47
|
+
if (!offset) {
|
48
|
+
var offset = 'Z';
|
49
|
+
var date = this;
|
50
|
+
} else {
|
51
|
+
var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
|
52
|
+
var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
|
53
|
+
offsetnum *= ((d[1] == '-') ? -1 : 1);
|
54
|
+
var date = new Date(Number(Number(this) + (offsetnum * 60000)));
|
55
|
+
}
|
56
|
+
|
57
|
+
var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }
|
58
|
+
|
59
|
+
var str = "";
|
60
|
+
str += date.getUTCFullYear();
|
61
|
+
if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
|
62
|
+
if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
|
63
|
+
if (format > 3) {
|
64
|
+
str += "T" + zeropad(date.getUTCHours()) +
|
65
|
+
":" + zeropad(date.getUTCMinutes());
|
66
|
+
}
|
67
|
+
if (format > 5) {
|
68
|
+
var secs = Number(date.getUTCSeconds() + "." +
|
69
|
+
((date.getUTCMilliseconds() < 100) ? '0' : '') +
|
70
|
+
zeropad(date.getUTCMilliseconds()));
|
71
|
+
str += ":" + zeropad(secs);
|
72
|
+
} else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }
|
73
|
+
|
74
|
+
if (format > 3) { str += offset; }
|
75
|
+
return str;
|
76
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
* Namespace for Ripple's built-in MapReduce functions.
|
4
|
+
*/
|
5
|
+
var Ripple = {
|
6
|
+
/*
|
7
|
+
* Filter input values by simple equality test on passed "fields"
|
8
|
+
* argument. Returns bucket/key pairs for use in later map phases.
|
9
|
+
*
|
10
|
+
* Raw Phase Example:
|
11
|
+
* {"map":{
|
12
|
+
* "language":"javascript",
|
13
|
+
* "name":"Ripple.filterByFields",
|
14
|
+
* "arg":{"manufactured":true, "name":"widget"}
|
15
|
+
* }}
|
16
|
+
*
|
17
|
+
* Ruby invocation example:
|
18
|
+
* mr.map("Ripple.filterByFields",
|
19
|
+
* :arg => {:manufactured => true, :name => "widget"})
|
20
|
+
*
|
21
|
+
*/
|
22
|
+
filterByFields: function(value, keyData, fields){
|
23
|
+
var object = Riak.mapValuesJson(value)[0];
|
24
|
+
for(field in fields){
|
25
|
+
if(object[field] != fields[field])
|
26
|
+
return [];
|
27
|
+
}
|
28
|
+
return [[value.bucket, value.key]];
|
29
|
+
},
|
30
|
+
/*
|
31
|
+
* Filter input values by various conditions passed as the
|
32
|
+
* "conditions" argument. Returns bucket/key pairs for use in
|
33
|
+
* later map phases.
|
34
|
+
*
|
35
|
+
* Valid operators:
|
36
|
+
* ==, eq (equality)
|
37
|
+
* !=, neq (inequality)
|
38
|
+
* <, lt (less than)
|
39
|
+
* =<, <=, lte (less than or equal)
|
40
|
+
* >, gt (greater than)
|
41
|
+
* >=, =>, gte (greater than or equal)
|
42
|
+
* ~=, match (regular expression match)
|
43
|
+
* between (inclusive numeric range)
|
44
|
+
* includes (String or Array inclusion)
|
45
|
+
*
|
46
|
+
* Example:
|
47
|
+
* {"map":{
|
48
|
+
* "language":"javascript",
|
49
|
+
* "name":"Ripple.filterByConditions",
|
50
|
+
* "arg":{"tags":{"includes":"riak"}, "title":{"~=":"schema"}}
|
51
|
+
* }}
|
52
|
+
*
|
53
|
+
* Ruby invocation example:
|
54
|
+
* mr.map("Ripple.filterByConditions",
|
55
|
+
* :arg => {:tags => {:includes => "riak"},
|
56
|
+
* :title => {"~=" => "schema"}})
|
57
|
+
*/
|
58
|
+
filterByConditions: function(value, keyData, conditions){
|
59
|
+
var object = Riak.mapValuesJson(value)[0];
|
60
|
+
for(condition in conditions){
|
61
|
+
if(!Ripple.conditionMatch(condition, conditions[condition], object))
|
62
|
+
return [];
|
63
|
+
}
|
64
|
+
return [[value.bucket, value.key]];
|
65
|
+
},
|
66
|
+
/*
|
67
|
+
* Given a specific field and test, returns whether the object
|
68
|
+
* matches the condition specified by the test. Used internally by
|
69
|
+
* Ripple.filterByConditions map phases.
|
70
|
+
*/
|
71
|
+
conditionMatch: function(field, test, object){
|
72
|
+
for(t in test){
|
73
|
+
switch(t){
|
74
|
+
case "==": case "eq":
|
75
|
+
if(object[field] != test[t])
|
76
|
+
return false;
|
77
|
+
break;
|
78
|
+
case "!=": case "neq":
|
79
|
+
if(object[field] == test[t])
|
80
|
+
return false;
|
81
|
+
break;
|
82
|
+
case "<": case "lt":
|
83
|
+
if(object[field] >= test[t])
|
84
|
+
return false;
|
85
|
+
break;
|
86
|
+
case "=<": case "<=": case "lte":
|
87
|
+
if(object[field] > test[t])
|
88
|
+
return false;
|
89
|
+
break;
|
90
|
+
case ">": case "gt":
|
91
|
+
if(object[field] <= test[t])
|
92
|
+
return false;
|
93
|
+
break;
|
94
|
+
case ">=": case "=>": case "gte":
|
95
|
+
if(object[field] < test[t])
|
96
|
+
return false;
|
97
|
+
break;
|
98
|
+
case "~=": case "match":
|
99
|
+
if(new RegExp(object[field],"i").test(test[t]))
|
100
|
+
return false;
|
101
|
+
break;
|
102
|
+
case "between": // Inclusive on both ends
|
103
|
+
if(object[field] < test[t][0] || object[field] > test[t][1])
|
104
|
+
return false;
|
105
|
+
break;
|
106
|
+
case "includes": // Only works with String, Array
|
107
|
+
if(object[field].indexOf(test[t]) == -1)
|
108
|
+
return false;
|
109
|
+
break;
|
110
|
+
default:
|
111
|
+
ejsLog("Invalid condition for field " + field + ": " + t + " " + test[t], "ripple-error.log");
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
return true;
|
116
|
+
},
|
117
|
+
/*
|
118
|
+
* Returns the mapped object without modification. Useful when
|
119
|
+
* preceded by map phases that do filtering or link phases.
|
120
|
+
*/
|
121
|
+
mapIdentity: function(value, kd, arg){
|
122
|
+
return [value];
|
123
|
+
},
|
124
|
+
/*
|
125
|
+
* Returns the passed values without modification. Useful as an
|
126
|
+
* intermediary before reduce phases that require the entire
|
127
|
+
* result set to be present (limits).
|
128
|
+
*/
|
129
|
+
reduceIdentity: function(values, arg){
|
130
|
+
return values;
|
131
|
+
}
|
132
|
+
};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rails/generators/ripple_generator'
|
2
|
+
|
3
|
+
module Ripple
|
4
|
+
module Generators
|
5
|
+
class ModelGenerator < NamedBase
|
6
|
+
desc 'Creates a ripple model'
|
7
|
+
argument :attributes, :type => :array, :default => [], :banner => 'field:type field:type'
|
8
|
+
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
|
9
|
+
class_option :embedded, :type => :boolean, :desc => "Make an embedded document model.", :default => false
|
10
|
+
class_option :embedded_in, :type => :string, :desc => "Specify the enclosing model for the embedded document. Implies --embedded."
|
11
|
+
check_class_collision
|
12
|
+
|
13
|
+
def create_model_file
|
14
|
+
template 'model.rb.erb', "app/models/#{file_path}.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
hook_for :test_framework
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class <%= class_name %><%= " < #{options[:parent].classify}" if options[:parent] %>
|
2
|
+
<% unless options[:parent] -%>
|
3
|
+
include Ripple::<%= "Embedded" if options[:embedded] || options[:embedded_in] %>Document
|
4
|
+
<% if options[:embedded_in] -%>embedded_in :<%= options[:embedded_in].underscore %><% end -%>
|
5
|
+
<% end -%>
|
6
|
+
|
7
|
+
<% attributes.reject{|attr| attr.reference?}.each do |attribute| -%>
|
8
|
+
property :<%= attribute.name %>, <%= attribute.type_class %>
|
9
|
+
<% end -%>
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators/ripple_generator'
|
2
|
+
|
3
|
+
module Ripple
|
4
|
+
module Generators
|
5
|
+
class ObserverGenerator < NamedBase
|
6
|
+
desc 'Creates an observer for Ripple documents'
|
7
|
+
check_class_collision :suffix => "Observer"
|
8
|
+
|
9
|
+
def create_observer_file
|
10
|
+
template 'observer.rb.erb', File.join("app/models", class_path, "#{file_name}_observer.rb")
|
11
|
+
end
|
12
|
+
|
13
|
+
hook_for :test_framework
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|