Mercurial Hosting > luan
changeset 1395:9dfff82dfc59
finish postgres work
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 09 Sep 2019 01:22:23 -0600 |
parents | 8fe777ba5045 |
children | a5f61890ad84 |
files | conv.txt examples/blog/src/lib/Db.luan src/luan/modules/Luan.luan src/luan/modules/lucene/Lucene.luan src/luan/modules/lucene/LuceneIndex.java src/luan/modules/lucene/Web_search.luan website/src/manual.html |
diffstat | 7 files changed, 159 insertions(+), 92 deletions(-) [+] |
line wrap: on
line diff
--- a/conv.txt Sun Sep 08 22:13:08 2019 -0600 +++ b/conv.txt Mon Sep 09 01:22:23 2019 -0600 @@ -1,3 +1,4 @@ +Lucene.index stringify (%>
--- a/examples/blog/src/lib/Db.luan Sun Sep 08 22:13:08 2019 -0600 +++ b/examples/blog/src/lib/Db.luan Mon Sep 09 01:22:23 2019 -0600 @@ -8,15 +8,19 @@ local Db = {} local postgres_spec = Hosting.postgres_spec and Hosting.postgres_spec() -if postgres_spec ~= nil then - function postgres_spec.completer(doc) - return doc - end + +local function completer(doc) + return doc end function Db.new(lucene_dir) local dir = Io.uri(lucene_dir) - local db = Lucene.index( dir, Lucene.type.english, {"subject","content"}, postgres_spec ) + local db = Lucene.index( dir, { + default_type = Lucene.type.english + default_fields = {"subject","content"} + completer = completer + postgres_spec = postgres_spec + } ) -- this is how you index a field -- db.indexed_fields.post_date = Lucene.type.long
--- a/src/luan/modules/Luan.luan Sun Sep 08 22:13:08 2019 -0600 +++ b/src/luan/modules/Luan.luan Mon Sep 09 01:22:23 2019 -0600 @@ -33,8 +33,8 @@ Luan.VERSION = Luan.do_file "classpath:luan/version.luan" -function Luan.eval(s,source_name) - return Luan.load( "return "..s, source_name or "eval" )() +function Luan.eval(s,source_name,env) + return Luan.load( "return "..s, source_name or "eval", env )() end return Luan
--- a/src/luan/modules/lucene/Lucene.luan Sun Sep 08 22:13:08 2019 -0600 +++ b/src/luan/modules/lucene/Lucene.luan Mon Sep 09 01:22:23 2019 -0600 @@ -35,16 +35,20 @@ Lucene.literal = SaneQueryParser.literal -function Lucene.index(index_dir,default_type,default_fields,postgres_spec) +-- function Lucene.index(index_dir,default_type,default_fields) + +function Lucene.index(index_dir,options) type(index_dir)=="table" or error "index_dir must be table" index_dir.to_uri_string and matches(index_dir.to_uri_string(),"^file:") or error "must be file" - postgres_spec==nil or type(postgres_spec)=="table" or error "postgres_spec must be table" + options = options or {} + options.postgres_spec==nil or type(options.postgres_spec)=="table" or error "postgres_spec must be table" + options.completer==nil or type(options.completer)=="function" or error "completer must be table" local index = {} index.dir = index_dir - local java_index, closer = LuceneIndex.getLuceneIndex(index_dir.java.file,default_type,default_fields,postgres_spec) + local java_index, closer = LuceneIndex.getLuceneIndex(index_dir.java.file,options.default_type,options.default_fields,options.completer,options.postgres_spec) index.java = java_index index.closer = closer or error() - index.completer = postgres_spec and postgres_spec.completer + index.completer = options.completer index.indexed_fields = {} local mt = {}
--- a/src/luan/modules/lucene/LuceneIndex.java Sun Sep 08 22:13:08 2019 -0600 +++ b/src/luan/modules/lucene/LuceneIndex.java Mon Sep 09 01:22:23 2019 -0600 @@ -118,14 +118,14 @@ private static Map<String,LuceneIndex> indexes = new HashMap<String,LuceneIndex>(); - public static Object[] getLuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,LuanTable postgresSpec) + public static Object[] getLuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,LuanFunction completer,LuanTable postgresSpec) throws LuanException, IOException, ClassNotFoundException, SQLException { String key = indexDir.getCanonicalPath(); synchronized(indexes) { LuceneIndex li = indexes.get(key); if( li == null ) { - li = new LuceneIndex(luan,indexDir,defaultFieldParser,defaultFields,key,postgresSpec); + li = new LuceneIndex(luan,indexDir,defaultFieldParser,defaultFields,key,completer,postgresSpec); li.openCount = 1; indexes.put(key,li); } else { @@ -169,7 +169,7 @@ private final PostgresBackup postgresBackup; - private LuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,String key,LuanTable postgresSpec) + private LuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,String key,LuanFunction completer,LuanTable postgresSpec) throws LuanException, IOException, ClassNotFoundException, SQLException { this.luanLogger = luan.getLogger(LuceneIndex.class); @@ -190,8 +190,9 @@ if( postgresSpec == null ) { postgresBackup = null; } else { + if( completer == null ) + throw new LuanException("completer is required for postgres_spec"); Map spec = postgresSpec.asMap(); - LuanFunction completer = Utils.removeRequiredFunction(spec,"completer"); postgresBackup = new PostgresBackup(luan,spec); if( postgresBackup != null ) { if( !wasCreated && postgresBackup.wasCreated ) { @@ -876,6 +877,7 @@ long nextId = postgresBackup.maxId() + 1; postgresBackup.restoreLucene(this); id = idLim = nextId; + saveNextId(nextId); ok = true; writer.commit(); } finally { @@ -906,6 +908,7 @@ } private void checkPostgres(LuanFunction completer) throws IOException, SQLException, LuanException { + luanLogger.info("start postgres check"); final PostgresBackup.Checker postgresChecker; final IndexSearcher searcher; writeLock.lock();
--- a/src/luan/modules/lucene/Web_search.luan Sun Sep 08 22:13:08 2019 -0600 +++ b/src/luan/modules/lucene/Web_search.luan Mon Sep 09 01:22:23 2019 -0600 @@ -5,18 +5,22 @@ local range = Luan.range or error() local to_string = Luan.to_string or error() local stringify = Luan.stringify or error() +local eval = Luan.eval or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" local String = require "luan:String.luan" local string_to_number = String.to_number or error() local Html = require "luan:Html.luan" +local html_encode = Html.encode or error() +local Number = require "luan:Number.luan" local Web_search = {} -local function style() %> +local function style() +%> body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: sans-serif; margin: 2em 5%; } h2 { @@ -28,53 +32,38 @@ display: inline-block; margin-right: .5em; } -<% -end - -local function form() %> -<!doctype html> -<html> - <head> - <title>Lucene Query</title> - <style> - <% style() %> - input { + input, textarea { margin-top: 1em; - } - input[type="text"] { font: inherit; - padding: .5em .8em; - border-radius: 8px; - border-style: groove; - } - input[type="text"]:focus { - border-color: #66afe9; - outline: none; } span[tip] { color: #888; font-size: smaller; - margin-left: .5em; } input[type="submit"] { - color: white; - background: #337ab7; - border-color: #337ab7; - font: inherit; + cursor: pointer; padding: .5em; border-radius: 4px; } - input[type="submit"]:hover { - background: #236aa7 !important; - } +<% +end + +local function form() +%> +<!doctype html> +<html> + <head> + <title>Lucene</title> + <style> +<% style() %> </style> </head> <body> <h2>Lucene Query</h2> - <form horizontal method="post"> + <form> <div> <label>Query:</label> - <input type=text name="query" size="80" autofocus /> + <input type=text name="query" size="80" autofocus> </div> <div> <label></label> @@ -82,11 +71,11 @@ </div> <div> <label>Max Rows:</label> - <input type=text name="rows" value="100" size="3" maxlength="5" /> + <input type=text name="rows" value="100" size="3" maxlength="5"> </div> <div> <label>Sort:</label> - <input type=text name="sort" size="60" /> + <input type=text name="sort" size="60"> </div> <div> <label></label> @@ -94,21 +83,49 @@ </div> <div> <label></label> - <input type="submit" /> + <input type="submit"> </div> </form> </body> </html> -<% end +<% +end -local function result(query,sort,headers,table) %> +local function index_of(tbl,val) + for i, v in ipairs(tbl) do + if v == val then + return i + end + end + local n = #tbl + 1 + tbl[n] = val + return n +end + +local function result(index) + local query = Http.request.parameters.query + local rows = string_to_number(Http.request.parameters.rows) + local sort = Http.request.parameters.sort + local results = index.search(query,1,rows,{sort=sort}) + local headers = {} + local table = {} + for _, doc in ipairs(results) do + local row = {} + for field, value in pairs(doc) do + row[index_of(headers,field)] = value + end + row.doc = doc + table[#table+1] = row + end + local can_edit = index.completer ~= nil +%> <!doctype html> <html> <head> - <title>Lucene Query</title> + <title>Lucene</title> <style> - <% style() %> +<% style() %> table { border-collapse: collapse; width: 100%; @@ -122,42 +139,88 @@ </style> </head> <body> - <h2>Lucene Query Results</h2> - <p><label>Query:</label> <b><%=Html.encode(to_string(query))%></b></p> - <p><label>Sort:</label> <b><%=Html.encode(to_string(sort))%></b></p> + <h2>Lucene Results</h2> + <p><label>Query:</label> <b><%=html_encode(to_string(query))%></b></p> + <p><label>Sort:</label> <b><%=html_encode(to_string(sort))%></b></p> <table> <tr> <th></th> - <% for _, header in ipairs(headers) do %> +<% for _, header in ipairs(headers) do %> <th><%=header%></th> - <% end %> +<% end %> </tr> - <% for i, row in ipairs(table) do %> +<% + for i, row in ipairs(table) do + local id = row.doc.id +%> <tr> - <td><%=i%></td> - <% + <td> +<% if can_edit and id~=nil then %> + <a href="?id=<%=id%>"><%=i%></a> +<% else %> + <%=i%> +<% end %> + </td> +<% for col in range(1, #headers) do local val = row[col] %><td><%= val and stringify(val) or "" %></td><% end - %> +%> </tr> - <% end %> +<% end %> </table> </body> </html> -<% end +<% +end -local function index_of(tbl,val) - for i, v in ipairs(tbl) do - if v == val then - return i - end - end - local n = #tbl + 1 - tbl[n] = val - return n +local function edit(index) + local id = string_to_number(Http.request.parameters.id) + local doc = index.get_document("id:"..id) + doc = stringify(doc,{strict=true,number_types=true}) +%> +<!doctype html> +<html> + <head> + <title>Lucene</title> + <style> +<% style() %> + </style> + </head> + <body> + <h2>Lucene Edit</h2> + <form action="?" method=post> + <div><textarea name="doc" rows="20" cols="90" autofocus><%=html_encode(doc)%></textarea></div> + <div><input type="submit" value="Update"></div> + </form> + </body> +</html> +<% +end + + +local function update(index) + local doc = Http.request.parameters.doc + local completer = index.completer or error() + doc = eval( doc, "lucene", Number ) + doc = completer(doc) + index.save(doc) +%> +<!doctype html> +<html> + <head> + <title>Lucene</title> + <style> +<% style() %> + </style> + </head> + <body> + <h2>Lucene Updated</h2> + </body> +</html> +<% end @@ -167,23 +230,15 @@ return function() Io.stdout = Http.response.text_writer() local query = Http.request.parameters.query - if query == nil then + if Http.request.parameters.query ~= nil then + result(index) + elseif Http.request.parameters.id ~= nil then + edit(index) + elseif Http.request.parameters.doc ~= nil then + update(index) + else form() - return end - local rows = string_to_number(Http.request.parameters.rows) - local sort = Http.request.parameters.sort - local results = index.search(query,1,rows,{sort=sort}) - local headers = {} - local table = {} - for _, doc in ipairs(results) do - local row = {} - for field, value in pairs(doc) do - row[index_of(headers,field)] = value - end - table[#table+1] = row - end - result(query,sort,headers,table) end end
--- a/website/src/manual.html Sun Sep 08 22:13:08 2019 -0600 +++ b/website/src/manual.html Mon Sep 09 01:22:23 2019 -0600 @@ -1812,7 +1812,7 @@ -<h4 heading><a name="Luan.eval" href="#Luan.eval"><code>Luan.eval (text [, source_name])</code></a></h4> +<h4 heading><a name="Luan.eval" href="#Luan.eval"><code>Luan.eval (text [, source_name] [, env])</code></a></h4> <p> Evaluates <code>text</code> as a Luan expression. @@ -1821,8 +1821,8 @@ Could be defined as: <pre> - function Luan.eval(text,source_name) - return Luan.load( "return "..text, source_name or "eval" )() + function Luan.eval(text,source_name, env) + return <a href="#Luan.load">Luan.load</a>( "return "..text, source_name or "eval", env )() end </pre>