Mercurial Hosting > luan
comparison lucene/src/luan/modules/lucene/LuceneIndex.java @ 646:cdc70de628b5
simplify LuanException
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 29 Mar 2016 19:58:39 -0600 |
parents | 8281a248c47e |
children | b21d82ee5756 |
comparison
equal
deleted
inserted
replaced
645:859c0dedc8b6 | 646:cdc70de628b5 |
---|---|
113 writer = new IndexWriter(dir,conf); | 113 writer = new IndexWriter(dir,conf); |
114 writer.commit(); // commit index creation | 114 writer.commit(); // commit index creation |
115 reader = DirectoryReader.open(dir); | 115 reader = DirectoryReader.open(dir); |
116 luan.onClose(this); | 116 luan.onClose(this); |
117 searcher = new IndexSearcher(reader); | 117 searcher = new IndexSearcher(reader); |
118 initId(luan); | 118 initId(); |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 | 122 |
123 public void delete_all() throws IOException { | 123 public void delete_all() throws IOException { |
153 | 153 |
154 public void save(LuanState luan,LuanTable doc) throws LuanException, IOException { | 154 public void save(LuanState luan,LuanTable doc) throws LuanException, IOException { |
155 Set indexedOnlySet = new HashSet(); | 155 Set indexedOnlySet = new HashSet(); |
156 Object typeObj = doc.get(luan,"type"); | 156 Object typeObj = doc.get(luan,"type"); |
157 if( typeObj==null ) | 157 if( typeObj==null ) |
158 throw new LuanException(luan,"missing 'type' field"); | 158 throw new LuanException("missing 'type' field"); |
159 if( !(typeObj instanceof String) ) | 159 if( !(typeObj instanceof String) ) |
160 throw new LuanException(luan,"type must be string"); | 160 throw new LuanException("type must be string"); |
161 String type = (String)typeObj; | 161 String type = (String)typeObj; |
162 Object indexedOnlyObj = indexed_only_fields.get(luan,type); | 162 Object indexedOnlyObj = indexed_only_fields.get(luan,type); |
163 if( indexedOnlyObj != null ) { | 163 if( indexedOnlyObj != null ) { |
164 if( !(indexedOnlyObj instanceof LuanTable) ) | 164 if( !(indexedOnlyObj instanceof LuanTable) ) |
165 throw new LuanException(luan,"indexed_only_fields elements must be tables"); | 165 throw new LuanException("indexed_only_fields elements must be tables"); |
166 LuanTable indexedOnly = (LuanTable)indexedOnlyObj; | 166 LuanTable indexedOnly = (LuanTable)indexedOnlyObj; |
167 for( Map.Entry<Object,Object> entry : indexedOnly.iterable(luan) ) { | 167 for( Map.Entry<Object,Object> entry : indexedOnly.iterable(luan) ) { |
168 Object key = entry.getKey(); | 168 Object key = entry.getKey(); |
169 if( !(key instanceof String) ) | 169 if( !(key instanceof String) ) |
170 throw new LuanException(luan,"indexed_only_fields."+type+" entries must be strings"); | 170 throw new LuanException("indexed_only_fields."+type+" entries must be strings"); |
171 String name = (String)key; | 171 String name = (String)key; |
172 Object value = entry.getValue(); | 172 Object value = entry.getValue(); |
173 if( !(value instanceof LuanFunction) ) | 173 if( !(value instanceof LuanFunction) ) |
174 throw new LuanException(luan,"indexed_only_fields."+type+" values must be functions"); | 174 throw new LuanException("indexed_only_fields."+type+" values must be functions"); |
175 LuanFunction fn = (LuanFunction)value; | 175 LuanFunction fn = (LuanFunction)value; |
176 value = Luan.first(fn.call(luan,new Object[]{doc})); | 176 value = Luan.first(fn.call(luan,new Object[]{doc})); |
177 doc.put(luan, name, value ); | 177 doc.put(luan, name, value ); |
178 indexedOnlySet.add(name); | 178 indexedOnlySet.add(name); |
179 } | 179 } |
181 Object obj = doc.get(luan,"id"); | 181 Object obj = doc.get(luan,"id"); |
182 Long id; | 182 Long id; |
183 try { | 183 try { |
184 id = (Long)obj; | 184 id = (Long)obj; |
185 } catch(ClassCastException e) { | 185 } catch(ClassCastException e) { |
186 throw new LuanException(luan,"id should be Long but is "+obj.getClass().getSimpleName()); | 186 throw new LuanException("id should be Long but is "+obj.getClass().getSimpleName()); |
187 } | 187 } |
188 | 188 |
189 boolean commit = !writeLock.isHeldByCurrentThread(); | 189 boolean commit = !writeLock.isHeldByCurrentThread(); |
190 writeLock.lock(); | 190 writeLock.lock(); |
191 try { | 191 try { |
216 | 216 |
217 private long id = 0; | 217 private long id = 0; |
218 private long idLim = 0; | 218 private long idLim = 0; |
219 private final int idBatch = 10; | 219 private final int idBatch = 10; |
220 | 220 |
221 private void initId(LuanState luan) throws LuanException, IOException { | 221 private void initId() throws LuanException, IOException { |
222 TopDocs td = searcher.search(new TermQuery(new Term("type","next_id")),1); | 222 TopDocs td = searcher.search(new TermQuery(new Term("type","next_id")),1); |
223 /* | 223 /* |
224 // tmp hack | 224 // tmp hack |
225 if( td.totalHits == 0 ) { | 225 if( td.totalHits == 0 ) { |
226 td = searcher.search(new TermQuery(new Term("type index","next_id")),1); | 226 td = searcher.search(new TermQuery(new Term("type index","next_id")),1); |
256 } | 256 } |
257 return id; | 257 return id; |
258 } | 258 } |
259 | 259 |
260 | 260 |
261 public void backup(LuanState luan,String zipFile) throws LuanException, IOException { | 261 public void backup(String zipFile) throws LuanException, IOException { |
262 if( !zipFile.endsWith(".zip") ) | 262 if( !zipFile.endsWith(".zip") ) |
263 throw new LuanException(luan,"file "+zipFile+" doesn't end with '.zip'"); | 263 throw new LuanException("file "+zipFile+" doesn't end with '.zip'"); |
264 IndexCommit ic = snapshotDeletionPolicy.snapshot(); | 264 IndexCommit ic = snapshotDeletionPolicy.snapshot(); |
265 try { | 265 try { |
266 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile)); | 266 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile)); |
267 for( String fileName : ic.getFileNames() ) { | 267 for( String fileName : ic.getFileNames() ) { |
268 out.putNextEntry(new ZipEntry(fileName)); | 268 out.putNextEntry(new ZipEntry(fileName)); |
309 this.searcher = searcher; | 309 this.searcher = searcher; |
310 } | 310 } |
311 | 311 |
312 @Override public Object call(LuanState luan,Object[] args) throws LuanException { | 312 @Override public Object call(LuanState luan,Object[] args) throws LuanException { |
313 try { | 313 try { |
314 return toTable(luan,searcher.doc(docID)); | 314 return toTable(searcher.doc(docID)); |
315 } catch(IOException e) { | 315 } catch(IOException e) { |
316 throw new LuanException(luan,e); | 316 throw new LuanException(e); |
317 } | 317 } |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 private static abstract class MyCollector extends Collector { | 321 private static abstract class MyCollector extends Collector { |
350 public void ensure_open() throws IOException { | 350 public void ensure_open() throws IOException { |
351 close(openSearcher()); | 351 close(openSearcher()); |
352 } | 352 } |
353 | 353 |
354 public int advanced_search( final LuanState luan, String queryStr, LuanFunction fn, Integer n, String sortStr ) throws LuanException, IOException, ParseException { | 354 public int advanced_search( final LuanState luan, String queryStr, LuanFunction fn, Integer n, String sortStr ) throws LuanException, IOException, ParseException { |
355 Utils.checkNotNull(luan,queryStr); | 355 Utils.checkNotNull(queryStr); |
356 Query query = SaneQueryParser.parseQuery(mfp,queryStr); | 356 Query query = SaneQueryParser.parseQuery(mfp,queryStr); |
357 IndexSearcher searcher = threadLocalSearcher.get(); | 357 IndexSearcher searcher = threadLocalSearcher.get(); |
358 boolean inTransaction = searcher != null; | 358 boolean inTransaction = searcher != null; |
359 if( !inTransaction ) | 359 if( !inTransaction ) |
360 searcher = openSearcher(); | 360 searcher = openSearcher(); |
361 try { | 361 try { |
362 if( fn!=null && n==null ) { | 362 if( fn!=null && n==null ) { |
363 if( sortStr != null ) | 363 if( sortStr != null ) |
364 throw new LuanException(luan,"sort must be nil when n is nil"); | 364 throw new LuanException("sort must be nil when n is nil"); |
365 final DocFn docFn = new DocFn(searcher); | 365 final DocFn docFn = new DocFn(searcher); |
366 MyCollector col = new MyCollector() { | 366 MyCollector col = new MyCollector() { |
367 @Override public void collect(int doc) { | 367 @Override public void collect(int doc) { |
368 try { | 368 try { |
369 docFn.docID = docBase + doc; | 369 docFn.docID = docBase + doc; |
400 } | 400 } |
401 } | 401 } |
402 | 402 |
403 public Object search_in_transaction(LuanState luan,LuanFunction fn) throws LuanException, IOException { | 403 public Object search_in_transaction(LuanState luan,LuanFunction fn) throws LuanException, IOException { |
404 if( threadLocalSearcher.get() != null ) | 404 if( threadLocalSearcher.get() != null ) |
405 throw new LuanException(luan,"can't nest search_in_transaction calls"); | 405 throw new LuanException("can't nest search_in_transaction calls"); |
406 IndexSearcher searcher = openSearcher(); | 406 IndexSearcher searcher = openSearcher(); |
407 threadLocalSearcher.set(searcher); | 407 threadLocalSearcher.set(searcher); |
408 try { | 408 try { |
409 return fn.call(luan); | 409 return fn.call(luan); |
410 } finally { | 410 } finally { |
425 return mfp.fields.get(key); | 425 return mfp.fields.get(key); |
426 } | 426 } |
427 | 427 |
428 @Override public void __new_index(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException { | 428 @Override public void __new_index(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException { |
429 if( !(key instanceof String) ) | 429 if( !(key instanceof String) ) |
430 throw new LuanException(luan,"key must be string"); | 430 throw new LuanException("key must be string"); |
431 String field = (String)key; | 431 String field = (String)key; |
432 if( value==null ) { // delete | 432 if( value==null ) { // delete |
433 mfp.fields.remove(field); | 433 mfp.fields.remove(field); |
434 return; | 434 return; |
435 } | 435 } |
436 if( !(value instanceof FieldParser) ) | 436 if( !(value instanceof FieldParser) ) |
437 throw new LuanException(luan,"value must be FieldParser like the values of Lucene.type"); | 437 throw new LuanException("value must be FieldParser like the values of Lucene.type"); |
438 FieldParser parser = (FieldParser)value; | 438 FieldParser parser = (FieldParser)value; |
439 mfp.fields.put( field, parser ); | 439 mfp.fields.put( field, parser ); |
440 } | 440 } |
441 | 441 |
442 @Override public final Iterator keys(LuanTable tbl) { | 442 @Override public final Iterator keys(LuanTable tbl) { |
449 | 449 |
450 }; | 450 }; |
451 | 451 |
452 | 452 |
453 | 453 |
454 private IndexableField newField(LuanState luan,String name,Object value,Field.Store store,Set<String> indexed) | 454 private IndexableField newField(String name,Object value,Field.Store store,Set<String> indexed) |
455 throws LuanException | 455 throws LuanException |
456 { | 456 { |
457 if( value instanceof String ) { | 457 if( value instanceof String ) { |
458 String s = (String)value; | 458 String s = (String)value; |
459 FieldParser fp = mfp.fields.get(name); | 459 FieldParser fp = mfp.fields.get(name); |
489 } | 489 } |
490 } else if( value instanceof byte[] ) { | 490 } else if( value instanceof byte[] ) { |
491 byte[] b = (byte[])value; | 491 byte[] b = (byte[])value; |
492 return new StoredField(name, b); | 492 return new StoredField(name, b); |
493 } else | 493 } else |
494 throw new LuanException(luan,"invalid value type "+value.getClass()+"' for '"+name+"'"); | 494 throw new LuanException("invalid value type "+value.getClass()+"' for '"+name+"'"); |
495 } | 495 } |
496 | 496 |
497 private Document toLucene(LuanState luan,LuanTable table,Set indexOnly) throws LuanException { | 497 private Document toLucene(LuanState luan,LuanTable table,Set indexOnly) throws LuanException { |
498 Set<String> indexed = mfp.fields.keySet(); | 498 Set<String> indexed = mfp.fields.keySet(); |
499 Document doc = new Document(); | 499 Document doc = new Document(); |
500 for( Map.Entry<Object,Object> entry : table.iterable(luan) ) { | 500 for( Map.Entry<Object,Object> entry : table.iterable(luan) ) { |
501 Object key = entry.getKey(); | 501 Object key = entry.getKey(); |
502 if( !(key instanceof String) ) | 502 if( !(key instanceof String) ) |
503 throw new LuanException(luan,"key must be string"); | 503 throw new LuanException("key must be string"); |
504 String name = (String)key; | 504 String name = (String)key; |
505 Object value = entry.getValue(); | 505 Object value = entry.getValue(); |
506 Field.Store store = indexOnly.contains(name) ? Field.Store.NO : Field.Store.YES; | 506 Field.Store store = indexOnly.contains(name) ? Field.Store.NO : Field.Store.YES; |
507 if( !(value instanceof LuanTable) ) { | 507 if( !(value instanceof LuanTable) ) { |
508 doc.add(newField(luan, name, value, store, indexed)); | 508 doc.add(newField(name, value, store, indexed)); |
509 } else { // list | 509 } else { // list |
510 LuanTable list = (LuanTable)value; | 510 LuanTable list = (LuanTable)value; |
511 for( Object el : list.asList() ) { | 511 for( Object el : list.asList() ) { |
512 doc.add(newField(luan, name, el, store, indexed)); | 512 doc.add(newField(name, el, store, indexed)); |
513 } | 513 } |
514 } | 514 } |
515 } | 515 } |
516 return doc; | 516 return doc; |
517 } | 517 } |
518 | 518 |
519 private static Object getValue(LuanState luan,IndexableField ifld) throws LuanException { | 519 private static Object getValue(IndexableField ifld) throws LuanException { |
520 BytesRef br = ifld.binaryValue(); | 520 BytesRef br = ifld.binaryValue(); |
521 if( br != null ) | 521 if( br != null ) |
522 return br.bytes; | 522 return br.bytes; |
523 Number n = ifld.numericValue(); | 523 Number n = ifld.numericValue(); |
524 if( n != null ) | 524 if( n != null ) |
525 return n; | 525 return n; |
526 String s = ifld.stringValue(); | 526 String s = ifld.stringValue(); |
527 if( s != null ) | 527 if( s != null ) |
528 return s; | 528 return s; |
529 throw new LuanException(luan,"invalid field type for "+ifld); | 529 throw new LuanException("invalid field type for "+ifld); |
530 } | 530 } |
531 | 531 |
532 private static LuanTable toTable(LuanState luan,Document doc) throws LuanException { | 532 private static LuanTable toTable(Document doc) throws LuanException { |
533 if( doc==null ) | 533 if( doc==null ) |
534 return null; | 534 return null; |
535 LuanTable table = new LuanTable(); | 535 LuanTable table = new LuanTable(); |
536 for( IndexableField ifld : doc ) { | 536 for( IndexableField ifld : doc ) { |
537 String name = ifld.name(); | 537 String name = ifld.name(); |
538 Object value = getValue(luan,ifld); | 538 Object value = getValue(ifld); |
539 Object old = table.rawGet(name); | 539 Object old = table.rawGet(name); |
540 if( old == null ) { | 540 if( old == null ) { |
541 table.rawPut(name,value); | 541 table.rawPut(name,value); |
542 } else { | 542 } else { |
543 LuanTable list; | 543 LuanTable list; |