changeset 1388:2024d23ddd64

add restore_from_postgres
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 03 Sep 2019 22:12:53 -0600
parents bc40bc9aab3a
children eb8b35dccd99
files examples/blog/src/lib/Db.luan src/luan/LuanTable.java src/luan/modules/BasicLuan.java src/luan/modules/lucene/Lucene.luan src/luan/modules/lucene/LuceneIndex.java src/luan/modules/lucene/PostgresBackup.java src/luan/modules/parsers/LuanToString.java
diffstat 7 files changed, 128 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/examples/blog/src/lib/Db.luan	Mon Sep 02 22:23:12 2019 -0600
+++ b/examples/blog/src/lib/Db.luan	Tue Sep 03 22:12:53 2019 -0600
@@ -20,4 +20,5 @@
 
 Db.db = Db.new("site:/private/local/lucene")
 
+--Db.db.restore_from_postgres()
 return Db
--- a/src/luan/LuanTable.java	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/LuanTable.java	Tue Sep 03 22:12:53 2019 -0600
@@ -27,6 +27,7 @@
 	}
 
 	public LuanTable(Luan luan,List list){
+		this.luan = luan;
 		int n = list.size();
 		for( int i=0; i<n; i++ ) {
 			Object val = list.get(i);
--- a/src/luan/modules/BasicLuan.java	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/modules/BasicLuan.java	Tue Sep 03 22:12:53 2019 -0600
@@ -264,7 +264,9 @@
 		} else {
 			throw new LuanException("strict must be nil or 'strict'");
 		}
-		return LuanToString.toString(obj,b);
+		LuanToString lts = new LuanToString();
+		lts.strict = b;
+		return lts.toString(obj);
 	}
 
 	private void BasicLuan() {}  // never
--- a/src/luan/modules/lucene/Lucene.luan	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/modules/lucene/Lucene.luan	Tue Sep 03 22:12:53 2019 -0600
@@ -71,6 +71,7 @@
 
 	index.has_postgres_backup = java_index.hasPostgresBackup()
 	index.rebuild_postgres_backup = java_index.rebuild_postgres_backup
+	index.restore_from_postgres = java_index.restore_from_postgres
 
 	function index.search( query, from, to, options )
 		from or error "missing 'from' parameter"
--- a/src/luan/modules/lucene/LuceneIndex.java	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/modules/lucene/LuceneIndex.java	Tue Sep 03 22:12:53 2019 -0600
@@ -182,7 +182,7 @@
 			rebuild_postgres_backup(completer);
 	}
 
-	public void reopen() throws LuanException, IOException {
+	public void reopen() throws IOException {
 		IndexWriterConfig conf = new IndexWriterConfig(version,analyzer);
 		snapshotDeletionPolicy = new SnapshotDeletionPolicy(conf.getIndexDeletionPolicy());
 		conf.setIndexDeletionPolicy(snapshotDeletionPolicy);
@@ -345,7 +345,7 @@
 	private long idLim;
 	private final int idBatch = 10;
 
-	private void initId() throws LuanException, IOException {
+	private void initId() throws IOException {
 		TopDocs td = searcher.search(new TermQuery(new Term("type","next_id")),1);
 		switch(td.totalHits) {
 		case 0:
@@ -361,13 +361,17 @@
 		}
 	}
 
+	private void saveNextId(long nextId) throws LuanException, IOException {
+		Map doc = new HashMap();
+		doc.put( "type", "next_id" );
+		doc.put( FLD_NEXT_ID, idLim );
+		writer.updateDocument(new Term("type","next_id"),toLucene(doc.entrySet(),null));
+	}
+
 	public synchronized long nextId() throws LuanException, IOException {
 		if( ++id > idLim ) {
 			idLim += idBatch;
-			Map doc = new HashMap();
-			doc.put( "type", "next_id" );
-			doc.put( FLD_NEXT_ID, idLim );
-			writer.updateDocument(new Term("type","next_id"),toLucene(doc.entrySet(),null));
+			saveNextId(idLim);
 			wrote();
 		}
 		return id;
@@ -824,4 +828,36 @@
 		}
 	}
 
+	public void restore_from_postgres()
+		throws IOException, LuanException
+	{
+		if( postgresBackup==null )
+			throw new NullPointerException();
+		if( writeLock.isHeldByCurrentThread() )
+			throw new RuntimeException();
+		writeLock.lock();
+		boolean ok = false;
+		try {
+			writer.deleteAll();
+			long nextId = postgresBackup.maxId() + 1;
+			postgresBackup.restoreLucene(this);
+			id = idLim = nextId;
+			ok = true;
+			writer.commit();
+		} finally {
+			if( !ok ) {
+				writer.rollback();
+				reopen();
+			}
+			wrote();
+			writeLock.unlock();
+		}
+	}
+
+	void restore(LuanTable doc)
+		throws LuanException, IOException
+	{
+		writer.addDocument(toLucene(doc,null));
+	}
+
 }
--- a/src/luan/modules/lucene/PostgresBackup.java	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/modules/lucene/PostgresBackup.java	Tue Sep 03 22:12:53 2019 -0600
@@ -1,12 +1,16 @@
 package luan.modules.lucene;
 
+import java.io.IOException;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.Statement;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import java.sql.ResultSet;
 import java.util.Properties;
+import luan.Luan;
 import luan.LuanTable;
+import luan.LuanFunction;
 import luan.LuanException;
 import luan.modules.parsers.LuanToString;
 import luan.lib.logging.Logger;
@@ -34,6 +38,8 @@
 	private final PreparedStatement updateStmt;
 	private final PreparedStatement deleteStmt;
 	private int trans = 0;
+	private final LuanToString luanToString = new LuanToString();
+	private final LuanTable env = new LuanTable(new Luan());
 
 	private PostgresBackup()
 		throws ClassNotFoundException, SQLException
@@ -71,6 +77,10 @@
 		deleteStmt = con.prepareStatement(
 			"delete from lucene where id=?"
 		);
+
+		luanToString.strict = true;
+		luanToString.numberTypes = true;
+		LuanToString.addNumberTypes(env);
 	}
 
 	void close() {
@@ -95,7 +105,7 @@
 	void add(long id,LuanTable doc) throws LuanException {
 		try {
 //logger.info("getAutoCommit="+con.getAutoCommit());
-			String data = LuanToString.toString(doc,true);
+			String data = luanToString.toString(doc);
 			insertStmt.setLong(1,id);
 			insertStmt.setString(2,data);
 			insertStmt.executeUpdate();
@@ -106,7 +116,7 @@
 
 	void update(long id,LuanTable doc) throws LuanException {
 		try {
-			String data = LuanToString.toString(doc,true);
+			String data = luanToString.toString(doc);
 			updateStmt.setString(1,data);
 			updateStmt.setLong(2,id);
 			int n = updateStmt.executeUpdate();
@@ -177,4 +187,45 @@
 		}
 	}
 
+	private final Luan luanEval = new Luan();
+
+	private Object eval(String s) throws LuanException {
+		LuanFunction fn = env.luan().load( "return "+s, "PostgresBackup", env );
+		return fn.call();
+	}
+
+	void restoreLucene(LuceneIndex li)
+		throws LuanException, IOException
+	{
+		try {
+			Statement stmt = con.createStatement();
+			ResultSet rs = stmt.executeQuery("select data from lucene");
+			while( rs.next() ) {
+				String data = rs.getString("data");
+				LuanTable doc = (LuanTable)eval(data);
+				li.restore(doc);
+			}
+			stmt.close();
+		} catch(SQLException e) {
+			logger.error("restoreLucene failed",e);
+			throw new RuntimeException(e);
+		}
+	}
+
+	long maxId()
+		throws LuanException, IOException
+	{
+		try {
+			Statement stmt = con.createStatement();
+			ResultSet rs = stmt.executeQuery("select max(id) as m from lucene");
+			rs.next();
+			long m = rs.getLong("m");
+			stmt.close();
+			return m;
+		} catch(SQLException e) {
+			logger.error("maxId failed",e);
+			throw new RuntimeException(e);
+		}
+	}
+
 }
--- a/src/luan/modules/parsers/LuanToString.java	Mon Sep 02 22:23:12 2019 -0600
+++ b/src/luan/modules/parsers/LuanToString.java	Tue Sep 03 22:12:53 2019 -0600
@@ -5,22 +5,19 @@
 import luan.Luan;
 import luan.LuanTable;
 import luan.LuanException;
+import luan.LuanRuntimeException;
 
 
 public final class LuanToString {
+	public boolean strict = false;
+	public boolean numberTypes = false;
 
-	public static String toString(Object obj,boolean strict) throws LuanException {
+	public String toString(Object obj) throws LuanException {
 		StringBuilder sb = new StringBuilder();
-		new LuanToString(strict).toString(obj,sb,0);
+		toString(obj,sb,0);
 		return sb.toString();
 	}
 
-	private final boolean strict;
-
-	private LuanToString(boolean strict) {
-		this.strict = strict;
-	}
-
 	private void toString(Object obj,StringBuilder sb,int indented) throws LuanException {
 		if( obj == null ) {
 			sb.append( "nil" );
@@ -31,7 +28,7 @@
 			return;
 		}
 		if( obj instanceof Number ) {
-			sb.append( Luan.toString((Number)obj) );
+			toString((Number)obj,sb);
 			return;
 		}
 		if( obj instanceof String ) {
@@ -93,4 +90,25 @@
 		}
 	}
 
+	private void toString(Number n,StringBuilder sb) throws LuanException {
+		if( numberTypes ) {
+			sb.append( n.getClass().getSimpleName().toLowerCase() );
+			sb.append( '(' );
+		}
+		sb.append( Luan.toString(n) );
+		if( numberTypes )
+			sb.append( ')' );
+	}
+
+	public static void addNumberTypes(LuanTable env) {
+		try {
+			LuanTable module = (LuanTable)env.luan().require("luan:Number.luan");
+			env.put( "double", module.fn("double") );
+			env.put( "float", module.fn("float") );
+			env.put( "integer", module.fn("integer") );
+			env.put( "long", module.fn("long") );
+		} catch(LuanException e) {
+			throw new LuanRuntimeException(e);
+		}
+	}
 }