From cd9a34e17e9edfd71518a164337e1fcca457ff2a Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Tue, 5 Jun 2012 17:59:59 +0000 Subject: [PATCH] SOLR-3508: allow _version_ on JSON delete cmd git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1346494 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 8 +-- .../solr/handler/loader/JsonLoader.java | 49 ++++++++++--------- .../apache/solr/handler/JsonLoaderTest.java | 28 +++++++++-- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3c31ea00872..663c360e705 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -344,9 +344,11 @@ New Features are combined and collations can contain a mix of corrections from both spellcheckers. (James Dyer) -* SOLR-3508: Improve JSON update format for deletes, allowing syntax of the form - {"delete":"myid"} AND - {"delete":["id1","id2"]} +* SOLR-3508: Simplify JSON update format for deletes as well as allow + version specification for optimistic locking. Examples: + {"delete":"myid"} + {"delete":["id1","id2","id3"]} + {"delete":{"id":"myid", "_version_":123456789}) (yonik) diff --git a/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java b/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java index 2cb1cfd2484..fe936c4383b 100644 --- a/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java +++ b/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java @@ -191,36 +191,41 @@ public class JsonLoader extends ContentStreamLoader { } } - void handleSingleDelete(int ev) throws IOException { - DeleteUpdateCommand cmd = new DeleteUpdateCommand(req); - cmd.commitWithin = commitWithin; - - String id = null; + // returns the string value for a primitive value, or null for the null value + String getString(int ev) throws IOException { switch (ev) { case JSONParser.STRING: - id = parser.getString(); - break; + return parser.getString(); case JSONParser.BIGNUMBER: case JSONParser.NUMBER: case JSONParser.LONG: - id = parser.getNumberChars().toString(); - break; - case JSONParser.OBJECT_START: - handleDeleteMap(ev); - return; + return parser.getNumberChars().toString(); + case JSONParser.BOOLEAN: + return Boolean.toString(parser.getBoolean()); + case JSONParser.NULL: + return null; default: throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, - "Got: "+JSONParser.getEventString( ev ) + "Expected primitive JSON value but got: "+JSONParser.getEventString( ev ) +" at ["+parser.getPosition()+"]" ); } + } - cmd.setId(id); - processor.processDelete(cmd); + + void handleSingleDelete(int ev) throws IOException { + if (ev == JSONParser.OBJECT_START) { + handleDeleteMap(ev); + } else { + DeleteUpdateCommand cmd = new DeleteUpdateCommand(req); + cmd.commitWithin = commitWithin; + String id = getString(ev); + cmd.setId(id); + processor.processDelete(cmd); + } } void handleDeleteArray(int ev) throws IOException { assert ev == JSONParser.ARRAY_START; - for (;;) { ev = parser.nextEvent(); if (ev == JSONParser.ARRAY_END) return; @@ -240,13 +245,13 @@ public class JsonLoader extends ContentStreamLoader { String key = parser.getString(); if( parser.wasKey() ) { if( "id".equals( key ) ) { - cmd.setId(parser.getString()); - } - else if( "query".equals(key) ) { + cmd.setId(getString(parser.nextEvent())); + } else if( "query".equals(key) ) { cmd.setQuery(parser.getString()); - } - else if( "commitWithin".equals(key) ) { - cmd.commitWithin = Integer.parseInt(parser.getString()); + } else if( "commitWithin".equals(key) ) { + cmd.commitWithin = (int)parser.getLong(); + } else if( "_version_".equals(key) ) { + cmd.setVersion(parser.getLong()); } else { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown key: "+key+" ["+parser.getPosition()+"]" ); } diff --git a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java index d923ef9a0a9..3af54bffdb9 100644 --- a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java +++ b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java @@ -71,9 +71,9 @@ public class JsonLoaderTest extends SolrTestCaseJ4 { "'optimize': { 'waitSearcher':false, 'openSearcher':false },\n" + "\n" + "'delete': { 'id':'ID' },\n" + - "'delete': { 'id':'ID', 'commitWithin':'500' },\n" + + "'delete': { 'id':'ID', 'commitWithin':500 },\n" + "'delete': { 'query':'QUERY' },\n" + - "'delete': { 'query':'QUERY', 'commitWithin':'500' },\n" + + "'delete': { 'query':'QUERY', 'commitWithin':500 },\n" + "'rollback': {}\n" + "\n" + "}\n" + @@ -243,6 +243,8 @@ public class JsonLoaderTest extends SolrTestCaseJ4 { String str = "{'delete':10" +"\n ,'delete':'20'" +"\n ,'delete':['30','40']" + +"\n ,'delete':{'id':50, '_version_':12345}" + +"\n ,'delete':[{'id':60, '_version_':67890}, {'id':70, '_version_':77777}, {'query':'id:80', '_version_':88888}]" + "\n}\n"; str = str.replace('\'', '"'); SolrQueryRequest req = req(); @@ -252,7 +254,7 @@ public class JsonLoaderTest extends SolrTestCaseJ4 { loader.load(req, rsp, new ContentStreamBase.StringStream(str), p); // DELETE COMMANDS - assertEquals( 4, p.deleteCommands.size() ); + assertEquals( 8, p.deleteCommands.size() ); DeleteUpdateCommand delete = p.deleteCommands.get( 0 ); assertEquals( delete.id, "10" ); assertEquals( delete.query, null ); @@ -273,6 +275,26 @@ public class JsonLoaderTest extends SolrTestCaseJ4 { assertEquals( delete.query, null ); assertEquals( delete.commitWithin, -1); + delete = p.deleteCommands.get( 4 ); + assertEquals( delete.id, "50" ); + assertEquals( delete.query, null ); + assertEquals( delete.getVersion(), 12345L); + + delete = p.deleteCommands.get( 5 ); + assertEquals( delete.id, "60" ); + assertEquals( delete.query, null ); + assertEquals( delete.getVersion(), 67890L); + + delete = p.deleteCommands.get( 6 ); + assertEquals( delete.id, "70" ); + assertEquals( delete.query, null ); + assertEquals( delete.getVersion(), 77777L); + + delete = p.deleteCommands.get( 7 ); + assertEquals( delete.id, null ); + assertEquals( delete.query, "id:80" ); + assertEquals( delete.getVersion(), 88888L); + req.close(); }