From b707a67d13060ef9723cd685280b4e47f71c2ac6 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Tue, 27 Sep 2011 23:11:24 +0000 Subject: Fixes COUCHDB-1152 - Update ICU on Windows. Thanks to Dave Cottlehuber for the patch. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1176651 13f79535-47bb-0310-9956-ffa450edef68 --- INSTALL.Windows | 6 +++--- src/couchdb/priv/Makefile.am | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/INSTALL.Windows b/INSTALL.Windows index d2082734..d661f1da 100644 --- a/INSTALL.Windows +++ b/INSTALL.Windows @@ -8,8 +8,8 @@ Dependencies You will need the following installed: - * Erlang OTP (=14B01) (http://erlang.org/) - * ICU (http://icu.sourceforge.net/) + * Erlang OTP (>=14B03) (http://erlang.org/) + * ICU (=4.4.*) (http://icu.sourceforge.net/) * OpenSSL (http://www.openssl.org/) * Mozilla SpiderMonkey (1.8) (http://www.mozilla.org/js/spidermonkey/) * libcurl (http://curl.haxx.se/libcurl/) @@ -21,7 +21,7 @@ General Notes * When installing Erlang, you must build it from source. - The CouchDB build makes use of a number of the Erlang build scripts. +The CouchDB build requires a number of the Erlang build scripts. * When installing ICU, select the binaries built with Visual Studio 2008. diff --git a/src/couchdb/priv/Makefile.am b/src/couchdb/priv/Makefile.am index 3d11e663..4a32c0a2 100644 --- a/src/couchdb/priv/Makefile.am +++ b/src/couchdb/priv/Makefile.am @@ -84,9 +84,9 @@ install-data-hook: $(LN_S) couch_icu_driver couch_icu_driver.so; \ fi if WINDOWS - $(INSTALL) $(ICU_LOCAL_BIN)/icuuc42.dll $(bindir) - $(INSTALL) $(ICU_LOCAL_BIN)/icudt42.dll $(bindir) - $(INSTALL) $(ICU_LOCAL_BIN)/icuin42.dll $(bindir) + $(INSTALL) $(ICU_LOCAL_BIN)/icuuc44.dll $(bindir) + $(INSTALL) $(ICU_LOCAL_BIN)/icudt44.dll $(bindir) + $(INSTALL) $(ICU_LOCAL_BIN)/icuin44.dll $(bindir) $(INSTALL) $(JS_LIB_BINARY) $(bindir) $(INSTALL) .libs/couchspawnkillable.exe \ "$(DESTDIR)$(couchprivdir)/couchspawnkillable.exe" -- cgit v1.2.3 From 61f10e7590bd352b367ad426a56587cbef3700b6 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Tue, 27 Sep 2011 23:59:11 +0000 Subject: Fix function evaluation by newer SpiderMonkey's. Found this error using the Debian package for SM 1.8.5 and have since had reports of users seeing it as well. The basic error is that some versions of SpiderMonkey appear to dislike this call to eval: eval("function(){}"); The fix is simply to wrap the function source in parenthesis so that SM is convinced that it knows how to evaluate a function. Backport of r1176666 from trunk. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1176667 13f79535-47bb-0310-9956-ffa450edef68 --- share/server/util.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/share/server/util.js b/share/server/util.js index e4386701..6afb38b6 100644 --- a/share/server/util.js +++ b/share/server/util.js @@ -63,6 +63,11 @@ var Couch = { }, compileFunction : function(source, ddoc) { if (!source) throw(["error","not_found","missing function"]); + // Some newer SpiderMonkey's appear to not like evaluating + // an anonymous function at global scope. Simple fix just + // wraps the source with parens so the function object is + // returned correctly. + source = "(" + source + ")"; try { if (sandbox) { if (ddoc) { -- cgit v1.2.3 From 86f113f9a0f3fdca02dfada0fa9854923b133a67 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Wed, 28 Sep 2011 01:14:56 +0000 Subject: Allow CommonJS modules to be an empty string. We were making a typical JavaScript mistake testing a module for truthiness instead of checking that it was undefined. Fixes COUCHDB-1223 Backport of r1176677 from trunk git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1176679 13f79535-47bb-0310-9956-ffa450edef68 --- share/server/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/server/util.js b/share/server/util.js index 6afb38b6..f6fa60bb 100644 --- a/share/server/util.js +++ b/share/server/util.js @@ -46,7 +46,7 @@ var resolveModule = function(names, mod, root) { } else if (root) { mod = {current : root}; } - if (!mod.current[n]) { + if (mod.current[n] === undefined) { throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(mod.current)]; } return resolveModule(names, { -- cgit v1.2.3 From 89a5c28775f24f2706f443c76afa3edf9df78ce4 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Wed, 28 Sep 2011 03:44:25 +0000 Subject: Rest of the fix for COUCHDB-1265 As a follow up to COUCHDB-1265 I was missing the fact that after the insertion of a new update_seq into an internal node it is quite possible that a compaction runs before the doc is updated again. This is important because compaction removes information of the largest update seq from the tree itself. The fix is simple to include the update_seq from the #full_doc_info{} record when calculating #doc_info.high_seq. The way to think of this is that it's the maximum value from all known values for the update sequence which can be defined as all values known in the tree or in the full_doc_info record. Backport of r1176701 from trunk git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1176704 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/recreate_doc.js | 88 ++++++++++++++++++++++------------- src/couchdb/couch_doc.erl | 8 ++-- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/share/www/script/test/recreate_doc.js b/share/www/script/test/recreate_doc.js index a1cfb8f8..f9723793 100644 --- a/share/www/script/test/recreate_doc.js +++ b/share/www/script/test/recreate_doc.js @@ -81,41 +81,65 @@ couchTests.recreate_doc = function(debug) { db.deleteDb(); db.createDb(); - // COUCHDB-1265 - // Resuscitate an unavailable old revision and make sure that it - // doesn't introduce duplicates into the _changes feed. - - var doc = {_id: "bar", count: 0}; - T(db.save(doc).ok); - var ghost = {_id: "bar", _rev: doc._rev, count: doc.count}; - for(var i = 0; i < 2; i++) { - doc.count += 1; - T(db.save(doc).ok); + // Helper function to create a doc with multiple revisions + // that are compacted away to ?REV_MISSING. + + var createDoc = function(docid) { + var ret = [{_id: docid, count: 0}]; + T(db.save(ret[0]).ok); + for(var i = 0; i < 2; i++) { + ret[ret.length] = { + _id: docid, + _rev: ret[ret.length-1]._rev, + count: ret[ret.length-1].count+1 + }; + T(db.save(ret[ret.length-1]).ok); + } + db.compact(); + while(db.info().compact_running) {} + return ret; } - // Compact so that the old revision to be resuscitated will be - // in the rev_tree as ?REV_MISSING + // Helper function to check that there are no duplicates + // in the changes feed and that it has proper update + // sequence ordering. + + var checkChanges = function() { + // Assert that there are no duplicates in _changes. + var req = CouchDB.request("GET", "/test_suite_db/_changes"); + var resp = JSON.parse(req.responseText); + var docids = {}; + var prev_seq = -1; + for(var i = 0; i < resp.results.length; i++) { + row = resp.results[i]; + T(row.seq > prev_seq, "Unordered _changes feed."); + T(docids[row.id] === undefined, "Duplicates in _changes feed."); + prev_seq = row.seq; + docids[row.id] = true; + } + }; + + // COUCHDB-1265 - Check that the changes feed remains proper + // after we try and break the update_seq tree. + + // This first case is the one originally reported and "fixed" + // in COUCHDB-1265. Reinserting an old revision into the + // revision tree causes duplicates in the update_seq tree. + + var revs = createDoc("a"); + T(db.save(revs[1], {new_edits: false}).ok); + T(db.save(revs[revs.length-1]).ok); + checkChanges(); + + // The original fix for COUCHDB-1265 is not entirely correct + // as it didn't consider the possibility that a compaction + // might run after the original tree screw up. + + revs = createDoc("b"); + T(db.save(revs[1], {new_edits: false}).ok); db.compact(); while(db.info().compact_running) {} + T(db.save(revs[revs.length-1]).ok); + checkChanges(); - // Saving the ghost here puts it back in the rev_tree in such - // a way as to create a new update_seq but without changing a - // leaf revision. This would cause the #full_doc_info{} and - // #doc_info{} records to diverge in their idea of what the - // doc's update_seq is and end up introducing a duplicate in - // the _changes feed the next time this doc is updated. - T(db.save(ghost, {new_edits: false}).ok); - - // The duplicate would have been introduce here becuase the #doc_info{} - // would not have been removed correctly. - T(db.save(doc).ok); - - // And finally assert that there are no duplicates in _changes. - var req = CouchDB.request("GET", "/test_suite_db/_changes"); - var resp = JSON.parse(req.responseText); - var docids = {}; - for(var i = 0; i < resp.results.length; i++) { - T(docids[resp.results[i].id] === undefined, "Duplicates in _changes feed."); - docids[resp.results[i].id] = true; - } }; diff --git a/src/couchdb/couch_doc.erl b/src/couchdb/couch_doc.erl index a6700d59..01e92836 100644 --- a/src/couchdb/couch_doc.erl +++ b/src/couchdb/couch_doc.erl @@ -302,7 +302,7 @@ to_doc_info(FullDocInfo) -> {DocInfo, _Path} = to_doc_info_path(FullDocInfo), DocInfo. -max_seq(Tree) -> +max_seq(Tree, UpdateSeq) -> FoldFun = fun({_Pos, _Key}, Value, _Type, MaxOldSeq) -> case Value of {_Deleted, _DiskPos, OldTreeSeq} -> @@ -311,9 +311,9 @@ max_seq(Tree) -> MaxOldSeq end end, - couch_key_tree:fold(FoldFun, 0, Tree). + couch_key_tree:fold(FoldFun, UpdateSeq, Tree). -to_doc_info_path(#full_doc_info{id=Id,rev_tree=Tree}) -> +to_doc_info_path(#full_doc_info{id=Id,rev_tree=Tree,update_seq=Seq}) -> RevInfosAndPath = [{#rev_info{deleted=Del,body_sp=Bp,seq=Seq,rev={Pos,RevId}}, Path} || {{Del, Bp, Seq},{Pos, [RevId|_]}=Path} <- @@ -326,7 +326,7 @@ to_doc_info_path(#full_doc_info{id=Id,rev_tree=Tree}) -> end, RevInfosAndPath), [{_RevInfo, WinPath}|_] = SortedRevInfosAndPath, RevInfos = [RevInfo || {RevInfo, _Path} <- SortedRevInfosAndPath], - {#doc_info{id=Id, high_seq=max_seq(Tree), revs=RevInfos}, WinPath}. + {#doc_info{id=Id, high_seq=max_seq(Tree, Seq), revs=RevInfos}, WinPath}. -- cgit v1.2.3