diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2023-12-16 12:12:31 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2023-12-16 12:12:31 +0100 |
commit | 6080ac0eef9f1352649667c12dbacb6810424e64 (patch) | |
tree | b511b497f2873e5c8fad6aedb961569a02f9bb86 | |
parent | 19fffeecfc786a2e04c578c978f4df28500983f8 (diff) | |
download | www-andreasbaumann-cc-6080ac0eef9f1352649667c12dbacb6810424e64.tar.gz www-andreasbaumann-cc-6080ac0eef9f1352649667c12dbacb6810424e64.tar.bz2 |
fts5 search: better error handling and some better index loading and unloading
-rw-r--r-- | themes/new_theme/layouts/partials/ranklist_fts5.html | 119 | ||||
-rw-r--r-- | themes/new_theme/layouts/partials/widgets/fts5_search.html | 2 |
2 files changed, 90 insertions, 31 deletions
diff --git a/themes/new_theme/layouts/partials/ranklist_fts5.html b/themes/new_theme/layouts/partials/ranklist_fts5.html index 5677c40..69c0f39 100644 --- a/themes/new_theme/layouts/partials/ranklist_fts5.html +++ b/themes/new_theme/layouts/partials/ranklist_fts5.html @@ -41,53 +41,112 @@ return html; } + function submitQuery( ) { + try { + if( window.location.pathname.includes( "/search/") ) { + var q = $( "#query" ).val( ); + executeQuery( q ); + return false; + } else { + return true; + } + } catch( e ) { + alert( e ); + } + } + + var index_loaded = false; + var SQL; + var db; + var stmt; + + function loadIndex( success, fail ) { + if( !index_loaded ) { + const xhr = new XMLHttpRequest( ); + xhr.open( 'GET', '/index/posts.db', true ); + xhr.responseType = 'arraybuffer'; + xhr.onload = e => { + if( ( xhr.status == 0 ) || ( xhr.status == 200 ) ) { + const uInt8Array = new Uint8Array( xhr.response ); + requirejs(["/js/sql-wasm.js"], function(initSqlJs) { + + SQL = initSqlJs( { + locateFile: file => `/js/${file}` + } ); + + initSqlJs( ).then( function( SQL ) { + db = new SQL.Database(uInt8Array); + stmt = db.prepare( "select uri as docid,title,snippet(posts, 2, '<b>', '</b>', '...', 50) as abstract from posts where posts MATCH @query ORDER BY bm25(posts)" ); + + index_loaded = true; + + success( ); + } ); + } ); + } else { + const uInt8Array = new Uint8Array( xhr.response ); + const decoder = new TextDecoder( ); + const msg = decoder.decode( uInt8Array ); + fail( xhr.status, xhr.statusText, msg ); + } + } + xhr.send( ); + } else { + success( ); + } + } + function executeQuery( query ) { $( "#query" ).LoadingOverlay( "show" ); - const xhr = new XMLHttpRequest(); - xhr.open('GET', '/index/posts.db', true); - xhr.responseType = 'arraybuffer'; - xhr.onload = e => { - const uInt8Array = new Uint8Array( xhr.response ); - requirejs(["/js/sql-wasm.js"], function(initSqlJs) { - - const SQL = initSqlJs( { - locateFile: file => `/js/${file}` - } ); + loadIndex( + function( ) { + stmt.bind( {'@query' : query} ); - initSqlJs( ).then( function( SQL ) { - var db = new SQL.Database(uInt8Array); - const stmt = db.prepare( "select uri as docid,title,snippet(posts, 2, '<b>', '</b>', '...', 50) as abstract from posts where posts MATCH @query ORDER BY bm25(posts)" ); - stmt.bind( {'@query' : query} ); + var html; + try { + var results = []; + while( stmt.step( ) ) { + var row = stmt.getAsObject( ); + results.push( row ); + } - var results = []; - while( stmt.step( ) ) { - var row = stmt.getAsObject( ); - results.push( row ); - } - stmt.free( ); - db.close( ); + html = draw_ranklist( query, results ); + } catch( e ) { + html = "<pre><font color='red'>There was an error executing the query '" + query + "', reason: " + e + "</font></pre>\n"; + } + + $( '#ranklist' ).html( html ); - var html = draw_ranklist( query, results ); - - $( '#ranklist' ).html( html ); - - $( "#query" ).LoadingOverlay( "hide" ); - } ); - } ); + $( "#query" ).LoadingOverlay( "hide" ); + }, + function( status, statusText, msg ) { + var html = "<pre><font color='red'>There was an error executing the query '" + query + "', reason: " + status + " " + statusText + "</font></pre>\n"; + $( '#ranklist' ).html( html ); + $( "#query" ).LoadingOverlay( "hide" ); } - xhr.send( ); + ); } $( window ).load( function( ) { var paramsString = window.location.search; var searchParams = new URLSearchParams( paramsString ); if( searchParams.has( "q" ) ) { - executeQuery( searchParams.get( "q" ) ); + var q = searchParams.get( "q" ) + $( "#query" ).val( q ); + executeQuery( q ); } else { // TODO: come up with something here } // Show full page LoadingOverlay } ); + + $( window ).unload( function( ) { + if( index_loaded ) { + stmt.free( ); + db.close( ); + index_loaded = false; + } + } ); </script> <div id="ranklist"> </div> diff --git a/themes/new_theme/layouts/partials/widgets/fts5_search.html b/themes/new_theme/layouts/partials/widgets/fts5_search.html index 5da7a2a..7f58e32 100644 --- a/themes/new_theme/layouts/partials/widgets/fts5_search.html +++ b/themes/new_theme/layouts/partials/widgets/fts5_search.html @@ -1,6 +1,6 @@ <h4 class="widget__title">Search</h4> <div class="widget-search widget"> - <form class="widget-search__form" role="search" method="get" action="/search/"> + <form id="search_form" class="widget-search__form" role="search" method="get" action="/search/" onsubmit="return submitQuery( );"> <label> <input class="widget-search__field" type="search" autocomplete="off" placeholder="{{ T "search_placeholder" }}" value="" id="query" name="q" aria-label="{{ T "search_placeholder" }}"> </label> |