Skip to content

Commit

Permalink
Item10338: this aught to give us a much less crashy OP_ref, and may w…
Browse files Browse the repository at this point in the history
…ell fix the 'Something broke'-edness Paul found

git-svn-id: http://svn.foswiki.org/trunk/MongoDBPlugin@11039 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
SvenDowideit authored and SvenDowideit committed Mar 13, 2011
1 parent 7950de7 commit e5b46f3
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 29 deletions.
4 changes: 4 additions & 0 deletions data/System/MongoDBPlugin.txt
Expand Up @@ -17,6 +17,10 @@ This is an experimental attempt to utilise [[http://mongodb.org][MongoDB]] for a
At this point the Plugin is used to populate the MongoDB. All user topic Saves are automatically copied into the MongoDB, and you can batch load using the restHandler:
* %SCRIPTURL{rest}%/MongoDBPlugin/update?updateweb=Main

To update the javascript stored in MongoDB
* %SCRIPTURL{rest}%/MongoDBPlugin/updateDatabase


---++ Technical details
This initial version serialises the internal Meta object directly into _one_ collection, using web.name as a unique index.

Expand Down
13 changes: 13 additions & 0 deletions lib/Foswiki/Plugins/MongoDBPlugin.pm
Expand Up @@ -319,6 +319,19 @@ sub _updateDatabase {

my $foswiki_getRef_js = Foswiki::Func::expandTemplate('foswiki_getRef_js');
getMongoDB()->updateSystemJS('foswiki_getRef', $foswiki_getRef_js);

my $foswiki_getField_js = Foswiki::Func::expandTemplate('foswiki_getField_js');
getMongoDB()->updateSystemJS('foswiki_getField', $foswiki_getField_js);

my $foswiki_toLowerCase_js = Foswiki::Func::expandTemplate('foswiki_toLowerCase_js');
getMongoDB()->updateSystemJS('foswiki_toLowerCase', $foswiki_toLowerCase_js);

my $foswiki_toUpperCase_js = Foswiki::Func::expandTemplate('foswiki_toUpperCase_js');
getMongoDB()->updateSystemJS('foswiki_toUpperCase', $foswiki_toUpperCase_js);

my $foswiki_length_js = Foswiki::Func::expandTemplate('foswiki_length_js');
getMongoDB()->updateSystemJS('foswiki_length', $foswiki_length_js);

}


Expand Down
33 changes: 17 additions & 16 deletions lib/Foswiki/Plugins/MongoDBPlugin/HoistMongoDB.pm
Expand Up @@ -384,9 +384,9 @@ my %js_op_map = (
);

my %js_func_map = (
'#lc' => '.toLowerCase()',
'#uc' => '.toUpperCase()',
'#length' => '.length',
'#lc' => 'foswiki_toLowerCase',
'#uc' => 'foswiki_toUpperCase',
'#length' => 'foswiki_length',
'#d2n' => 'foswiki_d2n',
'#int' => 'parseInt',
'#match' => 'MATCHBANG',
Expand All @@ -402,10 +402,13 @@ my %js_func_map = (

sub convertFunction {
my ( $value, $key ) = @_;
if ( $key eq '#d2n' ) {
return $js_func_map{$key} . '(' . convertStringToJS($value) . ')';
}
if ( $key eq '#int' ) {
if (
( $key eq '#lc' ) or
( $key eq '#uc' ) or
( $key eq '#length' ) or
( $key eq '#d2n' ) or
( $key eq '#int' )
) {
return $js_func_map{$key} . '(' . convertStringToJS($value) . ')';
}
if ( $key eq '#match' ) {
Expand All @@ -420,12 +423,10 @@ sub convertFunction {
}
if ($key eq '#ref') {
#TODO: like all accessses, this needs alot of undef protection.
my $addr = convertStringToJS( $$value[1] );
$addr =~ s/^this//;
return
'(foswiki_getRef('
. convertStringToJS( $$value[0] ) . ')'
. $addr . ')';
my $addr = '('.convertStringToJS( $$value[1] ).')';
my $ref = 'foswiki_getRef(' . convertStringToJS( $$value[0] ) . ')';
$addr =~ s/this/$ref/;
return $addr;
}
if ( ( $key eq '#div' )
or ( $key eq '#mult' )
Expand Down Expand Up @@ -466,10 +467,10 @@ sub convertStringToJS {
#TODO: i _think_ the line below is ok, its needed to make ::test_hoistLengthLHSString work
return $string if ( $string =~ /^\'.*/ );

return $string if ( $string =~ /^this\./ );

# all registered meta type prefixes use a this. in js
return 'this.' . $string if ( $string =~ /^$fields/ );
return $string if ( $string =~ /^foswiki_/ );
return 'foswiki_getField(this, \''.$string.'\')' if ( $string =~ /^$fields/ );

return $string
if ( $string =~ /^$ops$/ ); #for ops, we only want the entirety

Expand Down
40 changes: 40 additions & 0 deletions templates/mongodb_js.tmpl
@@ -1,10 +1,50 @@
%{ foswiki_getField attempts to avoid dereferenceing an undefined element. }%
%TMPL:DEF{foswiki_getField_js}%function(this, address) {
var ptr = this;
//address is of the form 'this.TOPICINFO.version' and needs to be separated into individual return undefined if this['TOPICINFO'] == undefined etc

var addrs = address.split('.');
for (var name in addrs) {
if (ptr == undefined) {
return ptr;
}
ptr = ptr[name];
}
return ptr;
}%TMPL:END%
%TMPL:DEF{foswiki_toLowerCase_js}%function(value) {
if (value == undefined) {
return value;
}
return value.toLowerCase();
}%TMPL:END%

%TMPL:DEF{foswiki_toUpperCase_js}%function(value) {
if (value == undefined) {
return value;
}
return value.toUpperCase();
}%TMPL:END%
%TMPL:DEF{foswiki_length_js}%function(value) {
if (value == undefined) {
return value;
}
return value.length;
}%TMPL:END%



%TMPL:DEF{foswiki_getRef_js}%function(host, collection, web, topic) {
conn = new Mongo(host);
current = conn.getCollection(collection);

return current.findOne({_web:web, _topic: topic});
}%TMPL:END%
%TMPL:DEF{foswiki_d2n_js}%function(dateString) {
if (dateString == undefined) {
return dateString;
}

var parseTime = function(date, defaultLocal) {

// ala Time::Local::timegm()
Expand Down
28 changes: 15 additions & 13 deletions test/unit/HoistMongoDBsTests.pm
Expand Up @@ -724,7 +724,7 @@ sub test_hoistLcRHSName {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'this._topic == \'WebHome\'.toLowerCase()'
'$where' => "this._topic == foswiki_toLowerCase('WebHome')"
}
);
}
Expand All @@ -740,7 +740,7 @@ sub test_hoistLcLHSField {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'this.FIELD.Subject.value.toLowerCase() == \'WebHome\''
'$where' => "foswiki_toLowerCase(foswiki_getField(this, 'FIELD.Subject.value')) == 'WebHome'"
}
);
}
Expand All @@ -755,7 +755,7 @@ sub test_hoistLcLHSName {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'this._topic.toLowerCase() == \'WebHome\''
'$where' => "foswiki_toLowerCase(this._topic) == 'WebHome'"
}
);
}
Expand Down Expand Up @@ -784,7 +784,7 @@ sub test_hoistLcLHSLikeName {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => '( /^Web.*$/.test(this._topic.toLowerCase()) )'
'$where' => "( /^Web.*\$/.test(foswiki_toLowerCase(this._topic)) )"
}
);
}
Expand All @@ -799,7 +799,7 @@ sub test_hoistLengthLHSName {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'this._topic.length == 12'
'$where' => "foswiki_length(this._topic) == 12"
}
);
}
Expand All @@ -813,7 +813,7 @@ sub test_hoistLengthLHSString {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => '\'something\'.length == 9'
'$where' => "foswiki_length('something') == 9"
}
);
}
Expand All @@ -828,7 +828,7 @@ sub test_hoistLengthLHSNameGT {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'this._topic.length < 12'
'$where' => "foswiki_length(this._topic) < 12"
}
);
}
Expand All @@ -843,7 +843,7 @@ sub test_hoist_d2n_value {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => 'foswiki_d2n(this.FIELD.noatime.value)'
'$where' => "foswiki_d2n(foswiki_getField(this, 'FIELD.noatime.value'))"
}
);
}
Expand All @@ -859,7 +859,7 @@ sub test_hoist_d2n_valueAND {
$this->do_Assert( $query, $mongoDBQuery,
{
#TODO: need to figure out how to not make both into js
'$where' => ' ( (foswiki_d2n(this.FIELD.noatime.value)) ) && this.FIELD.topic.value == \'WebHome\''
'$where' => " ( (foswiki_d2n(foswiki_getField(this, 'FIELD.noatime.value'))) ) && foswiki_getField(this, 'FIELD.topic.value') == 'WebHome'"
# '$where' => 'foswiki_d2n(this.FIELD.noatime.value)',
# 'FIELD.topic.value' => 'WebHome'
}
Expand Down Expand Up @@ -892,7 +892,7 @@ sub test_hoist_Item10323_1 {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => '( /bio/.test(this.FIELD.TermGroup.value.toLowerCase()) )'
'$where' => "( /bio/.test(foswiki_toLowerCase(foswiki_getField(this, 'FIELD.TermGroup.value'))) )"
}
);
}
Expand Down Expand Up @@ -960,7 +960,7 @@ sub test_hoist_maths {

$this->do_Assert( $query, $mongoDBQuery,
{
'$where' => ' ((12)-(this.FIELD.Namespace.value) < (((24)*(60))*(60))-(5)) && ((this.FIELD.TermGroup.value)/(12) > (this.FIELD.WebScale.value)*(42.8)) '
'$where' => " ((12)-(foswiki_getField(this, 'FIELD.Namespace.value')) < (((24)*(60))*(60))-(5)) && ((foswiki_getField(this, 'FIELD.TermGroup.value'))/(12) > (foswiki_getField(this, 'FIELD.WebScale.value'))*(42.8)) "
}
);
}
Expand Down Expand Up @@ -1320,7 +1320,8 @@ sub test_hoist_dateAndRelationship {
$mongoDBQuery,
{
'FORM.name' => qr/(?-xism:^.*RelationshipForm$)/,
'$where' => '(this.FIELD.NOW.value)-(this.TOPICINFO.date) < (((60)*(60))*(24))*(7)'
'$where' => "(foswiki_getField(this, 'FIELD.NOW.value'))-(foswiki_getField(this, 'TOPICINFO.date')) < (((60)*(60))*(24))*(7)"
}
}
);
}
Expand Down Expand Up @@ -1429,7 +1430,8 @@ sub test_hoist_ref {
$query,
$mongoDBQuery,
{
'$where' => "(foswiki_getRef('AnotherTopic').FIELD.number.value) == 12",
'$where' => "(foswiki_getField(foswiki_getRef('AnotherTopic'), 'FIELD.number.value')) == 12"
#"(foswiki_getRef('AnotherTopic').FIELD.number.value) == 12",
}
);
}
Expand Down

0 comments on commit e5b46f3

Please sign in to comment.