You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2011/08/10 22:45:53 UTC
svn commit: r1156360 - in /couchdb/trunk: share/www/script/test/basics.js
src/couchdb/couch_server.erl
Author: fdmanana
Date: Wed Aug 10 20:45:53 2011
New Revision: 1156360
URL: http://svn.apache.org/viewvc?rev=1156360&view=rev
Log:
Prevent data loss on db creation request
1) Create and populate a database
2) Restart the server
3) Send a PUT request to create the database - the server
will override the existing file, making all previous
documents no longer accessible nor recoverable
Modified:
couchdb/trunk/share/www/script/test/basics.js
couchdb/trunk/src/couchdb/couch_server.erl
Modified: couchdb/trunk/share/www/script/test/basics.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/basics.js?rev=1156360&r1=1156359&r2=1156360&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/basics.js (original)
+++ couchdb/trunk/share/www/script/test/basics.js Wed Aug 10 20:45:53 2011
@@ -246,4 +246,23 @@ couchTests.basics = function(debug) {
result = JSON.parse(xhr.responseText);
TEquals("bad_request", result.error);
TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
+
+ // On restart, a request for creating a database that already exists can
+ // not override the existing database file
+ db = new CouchDB("test_suite_foobar");
+ db.deleteDb();
+ xhr = CouchDB.request("PUT", "/" + db.name);
+ TEquals(201, xhr.status);
+
+ TEquals(true, db.save({"_id": "doc1"}).ok);
+ TEquals(true, db.ensureFullCommit().ok);
+
+ TEquals(1, db.info().doc_count);
+
+ restartServer();
+
+ xhr = CouchDB.request("PUT", "/" + db.name);
+ TEquals(412, xhr.status);
+
+ TEquals(1, db.info().doc_count);
};
Modified: couchdb/trunk/src/couchdb/couch_server.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_server.erl?rev=1156360&r1=1156359&r2=1156360&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_server.erl (original)
+++ couchdb/trunk/src/couchdb/couch_server.erl Wed Aug 10 20:45:53 2011
@@ -316,11 +316,13 @@ handle_call({open, DbName, Options}, {Fr
{reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
end;
handle_call({create, DbName, Options}, From, Server) ->
- case ets:lookup(couch_dbs_by_name, DbName) of
- [] ->
- open_db(DbName, Server, [create | Options], From);
- [_AlreadyRunningDb] ->
- {reply, file_exists, Server}
+ FileName = get_full_filename(Server, ?b2l(DbName)),
+ case file:open(FileName, [read]) of
+ {ok, Fd} ->
+ ok = file:close(Fd),
+ {reply, file_exists, Server};
+ Error ->
+ open_db(DbName, Server, [create | Options], From)
end;
handle_call({delete, DbName, _Options}, _From, Server) ->
DbNameList = binary_to_list(DbName),
Re: svn commit: r1156360 - in /couchdb/trunk: share/www/script/test/basics.js
src/couchdb/couch_server.erl
Posted by Paul Davis <pa...@gmail.com>.
Ah, cool, must've missed the follow up. I was a bit worried there for
a second :D
On Wed, Aug 10, 2011 at 5:05 PM, Filipe David Manana
<fd...@apache.org> wrote:
> I replied to a commit message mentioning it doesn't affect any Apache
> CouchDB release. My bad, tested with wrong branches.
>
> On Wed, Aug 10, 2011 at 3:02 PM, Paul Davis <pa...@gmail.com> wrote:
>> On Wed, Aug 10, 2011 at 3:45 PM, <fd...@apache.org> wrote:
>>> Author: fdmanana
>>> Date: Wed Aug 10 20:45:53 2011
>>> New Revision: 1156360
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1156360&view=rev
>>> Log:
>>> Prevent data loss on db creation request
>>>
>>> 1) Create and populate a database
>>> 2) Restart the server
>>> 3) Send a PUT request to create the database - the server
>>> will override the existing file, making all previous
>>> documents no longer accessible nor recoverable
>>>
>>>
>>> Modified:
>>> couchdb/trunk/share/www/script/test/basics.js
>>> couchdb/trunk/src/couchdb/couch_server.erl
>>>
>>> Modified: couchdb/trunk/share/www/script/test/basics.js
>>> URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/basics.js?rev=1156360&r1=1156359&r2=1156360&view=diff
>>> ==============================================================================
>>> --- couchdb/trunk/share/www/script/test/basics.js (original)
>>> +++ couchdb/trunk/share/www/script/test/basics.js Wed Aug 10 20:45:53 2011
>>> @@ -246,4 +246,23 @@ couchTests.basics = function(debug) {
>>> result = JSON.parse(xhr.responseText);
>>> TEquals("bad_request", result.error);
>>> TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
>>> +
>>> + // On restart, a request for creating a database that already exists can
>>> + // not override the existing database file
>>> + db = new CouchDB("test_suite_foobar");
>>> + db.deleteDb();
>>> + xhr = CouchDB.request("PUT", "/" + db.name);
>>> + TEquals(201, xhr.status);
>>> +
>>> + TEquals(true, db.save({"_id": "doc1"}).ok);
>>> + TEquals(true, db.ensureFullCommit().ok);
>>> +
>>> + TEquals(1, db.info().doc_count);
>>> +
>>> + restartServer();
>>> +
>>> + xhr = CouchDB.request("PUT", "/" + db.name);
>>> + TEquals(412, xhr.status);
>>> +
>>> + TEquals(1, db.info().doc_count);
>>> };
>>>
>>> Modified: couchdb/trunk/src/couchdb/couch_server.erl
>>> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_server.erl?rev=1156360&r1=1156359&r2=1156360&view=diff
>>> ==============================================================================
>>> --- couchdb/trunk/src/couchdb/couch_server.erl (original)
>>> +++ couchdb/trunk/src/couchdb/couch_server.erl Wed Aug 10 20:45:53 2011
>>> @@ -316,11 +316,13 @@ handle_call({open, DbName, Options}, {Fr
>>> {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
>>> end;
>>> handle_call({create, DbName, Options}, From, Server) ->
>>> - case ets:lookup(couch_dbs_by_name, DbName) of
>>> - [] ->
>>> - open_db(DbName, Server, [create | Options], From);
>>> - [_AlreadyRunningDb] ->
>>> - {reply, file_exists, Server}
>>> + FileName = get_full_filename(Server, ?b2l(DbName)),
>>> + case file:open(FileName, [read]) of
>>> + {ok, Fd} ->
>>> + ok = file:close(Fd),
>>> + {reply, file_exists, Server};
>>> + Error ->
>>> + open_db(DbName, Server, [create | Options], From)
>>> end;
>>> handle_call({delete, DbName, _Options}, _From, Server) ->
>>> DbNameList = binary_to_list(DbName),
>>>
>>>
>>>
>>
>> I can't reproduce this bug with curl, is there something I'm missing?
>>
>>
>> $ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
>> {"ok":true}
>> $ curl -XPUT -H "Content-Type: application/json"
>> http://127.0.0.1:5984/foo/bar -d '{"hi": true}'
>> {"ok":true,"id":"bar","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
>> $ curl -XPUT -H "Content-Type: application/json"
>> http://127.0.0.1:5984/foo/bar2 -d '{"hi": true}'
>> {"ok":true,"id":"bar2","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
>> $ curl -XPUT -H "Content-Type: application/json"
>> http://127.0.0.1:5984/foo/bar23 -d '{"hi": true}'
>> {"ok":true,"id":"bar23","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
>> $ curl -XPOST -H "Content-Type: application/json"
>> http://127.0.0.1:5984/foo/_ensure_full_commit
>> {"ok":true,"instance_start_time":"1313013146583992"}
>> $ curl -XPOST -H "Content-Type: application/json" http://127.0.0.1:5984/_restart
>> curl: (52) Empty reply from server
>> $ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
>> {"error":"file_exists","reason":"The database could not be created,
>> the file already exists."}
>>
>
>
>
> --
> Filipe David Manana,
> fdmanana@gmail.com, fdmanana@apache.org
>
> "Reasonable men adapt themselves to the world.
> Unreasonable men adapt the world to themselves.
> That's why all progress depends on unreasonable men."
>
Re: svn commit: r1156360 - in /couchdb/trunk: share/www/script/test/basics.js
src/couchdb/couch_server.erl
Posted by Filipe David Manana <fd...@apache.org>.
I replied to a commit message mentioning it doesn't affect any Apache
CouchDB release. My bad, tested with wrong branches.
On Wed, Aug 10, 2011 at 3:02 PM, Paul Davis <pa...@gmail.com> wrote:
> On Wed, Aug 10, 2011 at 3:45 PM, <fd...@apache.org> wrote:
>> Author: fdmanana
>> Date: Wed Aug 10 20:45:53 2011
>> New Revision: 1156360
>>
>> URL: http://svn.apache.org/viewvc?rev=1156360&view=rev
>> Log:
>> Prevent data loss on db creation request
>>
>> 1) Create and populate a database
>> 2) Restart the server
>> 3) Send a PUT request to create the database - the server
>> will override the existing file, making all previous
>> documents no longer accessible nor recoverable
>>
>>
>> Modified:
>> couchdb/trunk/share/www/script/test/basics.js
>> couchdb/trunk/src/couchdb/couch_server.erl
>>
>> Modified: couchdb/trunk/share/www/script/test/basics.js
>> URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/basics.js?rev=1156360&r1=1156359&r2=1156360&view=diff
>> ==============================================================================
>> --- couchdb/trunk/share/www/script/test/basics.js (original)
>> +++ couchdb/trunk/share/www/script/test/basics.js Wed Aug 10 20:45:53 2011
>> @@ -246,4 +246,23 @@ couchTests.basics = function(debug) {
>> result = JSON.parse(xhr.responseText);
>> TEquals("bad_request", result.error);
>> TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
>> +
>> + // On restart, a request for creating a database that already exists can
>> + // not override the existing database file
>> + db = new CouchDB("test_suite_foobar");
>> + db.deleteDb();
>> + xhr = CouchDB.request("PUT", "/" + db.name);
>> + TEquals(201, xhr.status);
>> +
>> + TEquals(true, db.save({"_id": "doc1"}).ok);
>> + TEquals(true, db.ensureFullCommit().ok);
>> +
>> + TEquals(1, db.info().doc_count);
>> +
>> + restartServer();
>> +
>> + xhr = CouchDB.request("PUT", "/" + db.name);
>> + TEquals(412, xhr.status);
>> +
>> + TEquals(1, db.info().doc_count);
>> };
>>
>> Modified: couchdb/trunk/src/couchdb/couch_server.erl
>> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_server.erl?rev=1156360&r1=1156359&r2=1156360&view=diff
>> ==============================================================================
>> --- couchdb/trunk/src/couchdb/couch_server.erl (original)
>> +++ couchdb/trunk/src/couchdb/couch_server.erl Wed Aug 10 20:45:53 2011
>> @@ -316,11 +316,13 @@ handle_call({open, DbName, Options}, {Fr
>> {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
>> end;
>> handle_call({create, DbName, Options}, From, Server) ->
>> - case ets:lookup(couch_dbs_by_name, DbName) of
>> - [] ->
>> - open_db(DbName, Server, [create | Options], From);
>> - [_AlreadyRunningDb] ->
>> - {reply, file_exists, Server}
>> + FileName = get_full_filename(Server, ?b2l(DbName)),
>> + case file:open(FileName, [read]) of
>> + {ok, Fd} ->
>> + ok = file:close(Fd),
>> + {reply, file_exists, Server};
>> + Error ->
>> + open_db(DbName, Server, [create | Options], From)
>> end;
>> handle_call({delete, DbName, _Options}, _From, Server) ->
>> DbNameList = binary_to_list(DbName),
>>
>>
>>
>
> I can't reproduce this bug with curl, is there something I'm missing?
>
>
> $ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
> {"ok":true}
> $ curl -XPUT -H "Content-Type: application/json"
> http://127.0.0.1:5984/foo/bar -d '{"hi": true}'
> {"ok":true,"id":"bar","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
> $ curl -XPUT -H "Content-Type: application/json"
> http://127.0.0.1:5984/foo/bar2 -d '{"hi": true}'
> {"ok":true,"id":"bar2","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
> $ curl -XPUT -H "Content-Type: application/json"
> http://127.0.0.1:5984/foo/bar23 -d '{"hi": true}'
> {"ok":true,"id":"bar23","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
> $ curl -XPOST -H "Content-Type: application/json"
> http://127.0.0.1:5984/foo/_ensure_full_commit
> {"ok":true,"instance_start_time":"1313013146583992"}
> $ curl -XPOST -H "Content-Type: application/json" http://127.0.0.1:5984/_restart
> curl: (52) Empty reply from server
> $ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
> {"error":"file_exists","reason":"The database could not be created,
> the file already exists."}
>
--
Filipe David Manana,
fdmanana@gmail.com, fdmanana@apache.org
"Reasonable men adapt themselves to the world.
Unreasonable men adapt the world to themselves.
That's why all progress depends on unreasonable men."
Re: svn commit: r1156360 - in /couchdb/trunk: share/www/script/test/basics.js
src/couchdb/couch_server.erl
Posted by Paul Davis <pa...@gmail.com>.
On Wed, Aug 10, 2011 at 3:45 PM, <fd...@apache.org> wrote:
> Author: fdmanana
> Date: Wed Aug 10 20:45:53 2011
> New Revision: 1156360
>
> URL: http://svn.apache.org/viewvc?rev=1156360&view=rev
> Log:
> Prevent data loss on db creation request
>
> 1) Create and populate a database
> 2) Restart the server
> 3) Send a PUT request to create the database - the server
> will override the existing file, making all previous
> documents no longer accessible nor recoverable
>
>
> Modified:
> couchdb/trunk/share/www/script/test/basics.js
> couchdb/trunk/src/couchdb/couch_server.erl
>
> Modified: couchdb/trunk/share/www/script/test/basics.js
> URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/basics.js?rev=1156360&r1=1156359&r2=1156360&view=diff
> ==============================================================================
> --- couchdb/trunk/share/www/script/test/basics.js (original)
> +++ couchdb/trunk/share/www/script/test/basics.js Wed Aug 10 20:45:53 2011
> @@ -246,4 +246,23 @@ couchTests.basics = function(debug) {
> result = JSON.parse(xhr.responseText);
> TEquals("bad_request", result.error);
> TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
> +
> + // On restart, a request for creating a database that already exists can
> + // not override the existing database file
> + db = new CouchDB("test_suite_foobar");
> + db.deleteDb();
> + xhr = CouchDB.request("PUT", "/" + db.name);
> + TEquals(201, xhr.status);
> +
> + TEquals(true, db.save({"_id": "doc1"}).ok);
> + TEquals(true, db.ensureFullCommit().ok);
> +
> + TEquals(1, db.info().doc_count);
> +
> + restartServer();
> +
> + xhr = CouchDB.request("PUT", "/" + db.name);
> + TEquals(412, xhr.status);
> +
> + TEquals(1, db.info().doc_count);
> };
>
> Modified: couchdb/trunk/src/couchdb/couch_server.erl
> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_server.erl?rev=1156360&r1=1156359&r2=1156360&view=diff
> ==============================================================================
> --- couchdb/trunk/src/couchdb/couch_server.erl (original)
> +++ couchdb/trunk/src/couchdb/couch_server.erl Wed Aug 10 20:45:53 2011
> @@ -316,11 +316,13 @@ handle_call({open, DbName, Options}, {Fr
> {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
> end;
> handle_call({create, DbName, Options}, From, Server) ->
> - case ets:lookup(couch_dbs_by_name, DbName) of
> - [] ->
> - open_db(DbName, Server, [create | Options], From);
> - [_AlreadyRunningDb] ->
> - {reply, file_exists, Server}
> + FileName = get_full_filename(Server, ?b2l(DbName)),
> + case file:open(FileName, [read]) of
> + {ok, Fd} ->
> + ok = file:close(Fd),
> + {reply, file_exists, Server};
> + Error ->
> + open_db(DbName, Server, [create | Options], From)
> end;
> handle_call({delete, DbName, _Options}, _From, Server) ->
> DbNameList = binary_to_list(DbName),
>
>
>
I can't reproduce this bug with curl, is there something I'm missing?
$ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
{"ok":true}
$ curl -XPUT -H "Content-Type: application/json"
http://127.0.0.1:5984/foo/bar -d '{"hi": true}'
{"ok":true,"id":"bar","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
$ curl -XPUT -H "Content-Type: application/json"
http://127.0.0.1:5984/foo/bar2 -d '{"hi": true}'
{"ok":true,"id":"bar2","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
$ curl -XPUT -H "Content-Type: application/json"
http://127.0.0.1:5984/foo/bar23 -d '{"hi": true}'
{"ok":true,"id":"bar23","rev":"1-e7e9148335bb3e3d0f04263e57edef01"}
$ curl -XPOST -H "Content-Type: application/json"
http://127.0.0.1:5984/foo/_ensure_full_commit
{"ok":true,"instance_start_time":"1313013146583992"}
$ curl -XPOST -H "Content-Type: application/json" http://127.0.0.1:5984/_restart
curl: (52) Empty reply from server
$ curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:5984/foo
{"error":"file_exists","reason":"The database could not be created,
the file already exists."}