LuaTeX non trova il modulo luasql.sqlite3

  • Creatore
    Topic
  • #93921
    robitex
    Amministratore del forum
      Up
      0
      Down
      ::


      Buongiorno e buon sabato a tutti,
      ho deciso di scrivere questo post perché potrebbe interessare ad altri trovare la soluzione a questo problema.

      —> Descrizione del sistema
      Sto lavorando in Ubuntu 13.10 con teX Live full 2013.
      Ho installato da package manager i pacchetti SQLite3 e LuaSQL.
      Il database SQLite3 è perfetto per lavorare in coppia con LuaTeX, mentre le applicazioni possibili sono veramente tante e molto interessanti.
      Non mi dispiacerebbe affatto che LuaTeX incorporasse SQLite3 o almeno lo distribuisse come fa con altre librerie Lua.

      —-> Test esterno
      Ho scritto questo codice Lua adattato da un post trovato in TeX.Exchange:
      `local luasql = require(“luasql.sqlite3”)

      env = assert(luasql.sqlite3())

      — connect to data source
      con = assert(env:connect(“luasql-test”))

      — retrieve a cursor
      cur = assert(con:execute”CREATE TABLE people (name TEXT, email TEXT)”)
      cur = assert(con:execute”INSERT INTO people VALUES ('Pippo', 'pippo@email.org')”)
      cur = assert(con:execute”INSERT INTO people VALUES ('San Remo', 'remo.san@vatican.org')”)
      cur = assert(con:execute”INSERT INTO people VALUES ('Ula op', 'ula.op@email.org')”)

      cur = assert(con:execute”SELECT name, email from people”)

      — print all rows, the rows will be indexed by field names
      row = cur:fetch ({}, “a”)
      print([[\begin{tabular}{@{}ll@{}}\toprule]])
      print([[Name & email \\\midrule]])
      while row do
      print(-2,row.name)
      print(“&”)
      print(-2, row.email)
      print(“\\\\”)
      — reusing the table of results
      row = cur:fetch (row, “a”)
      end
      print([[\bottomrule\end{tabular}]])

      — close everything
      cur:close()
      con:close()
      env:close()`

      Il test eseguito con Lua 5.2.2 per mezzo del comando $ lua test.lua ha successo.
      Viene creato il file del database chiamato luasql-test che all’interno mostra la tabella people.

      —> Test con texlua
      texlua è un programma che lancia il modulo Lua di LuaTeX per eseguire codice Lua puro.
      Se lancio il comando $ texlua test.lua questa volta ricevo l’errore seguente:
      `texlua testop.lua
      $ texlua test.lua
      test.lua:1: module 'luasql.sqlite3' not found:
      no field package.preload['luasql.sqlite3']
      no file '/usr/local/share/lua/5.2/luasql/sqlite3.lua'
      no file '/usr/local/share/lua/5.2/luasql/sqlite3/init.lua'
      no file '/usr/local/lib/lua/5.2/luasql/sqlite3.lua'
      no file '/usr/local/lib/lua/5.2/luasql/sqlite3/init.lua'
      no file './luasql/sqlite3.lua'
      no file '/usr/local/lib/lua/5.2/luasql/sqlite3.so'
      no file '/usr/local/lib/lua/5.2/loadall.so'
      no file './luasql/sqlite3.so'
      no file '/usr/local/lib/lua/5.2/luasql.so'
      no file '/usr/local/lib/lua/5.2/loadall.so'
      no file './luasql.so'
      >Exit code: 1
      `

      LuaTeX infatti sostituisce il normale processo di caricamento delle librerie di Lua per sfruttare il modulo kpathsea.
      L’errore dovrebbe essere normale, tuttavia ho inserito il percorso alla libreria nel file /usr/local/texlive/2013/texmf.cnf:
      `CLUAINPUTS = .;/usr/lib/x86_64-linux-gnu/lua/5.2//;$SELFAUTOLOC/lib/{$progname,$engine,}/lua//`

      Qualcuno vuol provare a trovare la giusta configurazione?
      Nel manuale di LuaTeX alla sezione 3.2 dice qualcosa sul percorso di ricerca moduli, mentre sul web si trova ancora poco sull’argomento.

      Riporto anche il file per LuaLaTeX che dovrebbe effettuare una query sul database e produrre una sorta di report:
      `\documentclass{article}
      \usepackage{luacode,booktabs}
      \begin{document}
      \begin{luacode*}
      local luasql = require(“luasql.sqlite3”)
      env = assert(luasql.sqlite3())

      — connect to data source
      con = assert (env:connect(“luasql-test”))
      — retrieve a cursor
      cur = assert (con:execute”SELECT name, email from people”)
      — print all rows, the rows will be indexed by field names
      row = cur:fetch ({}, “a”)
      tex.sprint([[\begin{tabular}{@{}ll@{}}\toprule]])
      tex.sprint([[Name & email \\\midrule]])
      while row do
      tex.sprint(-2,row.name)
      tex.sprint(“&”)
      tex.sprint(-2, row.email)
      tex.sprint(“\\\\”)
      — reusing the table of results
      row = cur:fetch (row, “a”)
      end
      tex.sprint([[\bottomrule\end{tabular}]])
      — close everything
      cur:close()
      con:close()
      env:close()
      \end{luacode*}
      \end{document}
      `

      L’errore in questo caso è il seguente:
      `! LuaTeX error [string “\directlua “]:1: module 'luasql.sqlite3' not found:
      no field package.preload['luasql.sqlite3']
      [luatexbase.loader] Search failed
      [kpse lua searcher] file not found: 'luasql.sqlite3'luasql/sqlite3
      no file '/usr/local/lib/lua/5.2/luasql.so'
      no file '/usr/local/lib/lua/5.2/loadall.so'
      no file './luasql.so'
      [oberdiek.luatex.kpse_module_loader]-eroux Search failed
      stack traceback:
      [C]: in function 'require'
      [string “\directlua “]:1: in main chunk.
      \luacode@dbg@exec …code@maybe@printdbg {#1} #1 }`

      Riporto anche un link ad un mio post dove riuscivo facilmente a connettermi da LuaTeX ad un database PostgreSQL:

      PostgreSQL gestisce i dati, LuaLaTeX li stampa

      Grazie e saluti.
      R.

    Visualizzazione 5 filoni di risposte
    • Autore
      Risposte
      • #93922
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Sì, penso che il problema nasca specificatamente dal fatto che kpsewhich cerca i file e solo certi file, all’interno della “foresta” degli alberi del sistema TeX.

          Penso allora che la cosa migliore si quella di caricare le librerie dentro la cartella ~/texmf/bin dell’albero perosonale; se la cartella non esiste basta crearla; non sarebbe nemmeno necessario eseguire maketxlsr per aggiornare i databse dei nomi dei file, perché TeXLive non ha bisogno di quell’informazione per l’albero personale; tuttavia quel percorso andrebbe aggiunto al percorso generale di ricerca die file a livello di sistema, perché altrimenti lavorando direttamante con Lua non troverebbe più le librerie che ora si trovano altrove.

          Oppure, visto che sei un utente esperto sia di Ubuntu sia dei sitemi UNIX, e di Windows, non hai problemi a creare dei link simbolici; probabilmente puoi lasciare le librerie dovo sono e mettere i link simbolici nell’albero personale, nella cartella ~/texmf/bin, oppure puoi spostare quelle librerie nell’albero personale e mettere nelle cartelle originali i link simbolici che puntano alle cartelle inserite dentro ~/texmf/bin/.

          Se non ho pensato delle cretinate palesi, allora credo che valga la pena provare.

          Claudio

        • #93923
          robitex
          Amministratore del forum
            Up
            0
            Down
            ::


            Claudio funziona!!! 😀 😀 😀
            Non proprio esattamente come mi hai suggerito e un poco simile ad un trucco, come vado a spiegare subito.
            In effetti i percorsi di ricerca dovrebbero essere interni all’albero TDS?
            Ed allora non mi spiego perché nel messaggio di errore viene descritto un percorso fuori dall’albero di TeX Live:
            `no file '/usr/local/lib/lua/5.2/luasql.so'`

            Allora ho fatto un primo tentativo: ho creato un link simbolico nell’albero personale alla libreria con questo comando:
            `ln -s /usr/lib/x86_64-linux-gnu/liblua5.2-sql-sqlite3.so.2.0.0 ~/texmf/bin/lua/5.2/luasql/sqlite3.so`
            e non ha funzionato.

            Secondo tentativo è quello di far trovare il link simbolico proprio nel path indicato nel messaggio d’errore.
            In questo caso ho dovuto creare le directory perché /usr/local/lib/lua/5.2/ non esiste in quanto Lua è installata da un’altra parte (del resto anche nel caaso precedente perché non esisteva neanche la directory personale).
            Il comando è stato questo dato dalla cartella /usr/local/lib/lua/5.2:
            `sudo ln -s /usr/lib/x86_64-linux-gnu/liblua5.2-sql-sqlite3.so.2.0.0 luasql.so`

            In questo caso funziona, ma non è proprio il massimo perché sono obbligato a nominare il link ‘luasql.so’. Se volessi installare un altro driver per un database diverso non potrei.

            Lua nel sistema è installata in:
            `roberto@roberto-desktop:~$ which lua
            /usr/bin/lua
            roberto@roberto-desktop:~$ lua -v
            Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
            `
            Grazie e buona serata.
            R.

          • #93924
            robitex
            Amministratore del forum
              Up
              0
              Down
              ::


              Ciao, ci sono novità.
              Ho scoperto perché vengono ricercati i file di libreria anche al di fuori del tds.
              Ciò è dovuto al fatto che il loader di Lua non è sostituito ma invece integrato da quello previsto da LaTeX e basato su kpathsea.
              La ricerca avviene quindi per prima sul searcher di kpathsea poi il controllo passa a quello di Lua 5.2.
              I percorsi di ricerca sono contenuti nella variabile di tipo stringa package.cpath.
              Per scoprirne il contenuto basta eseguire il seguente codice LuaTeX o l’equivalente LuaLaTeX o ConTeXt miv, per stampare nel log:
              `\directlua{
              texio.write_nl(package.cpath)
              }

              \bye`

              A breve cercherò di approfondire l’argomento per trovare una soluzione soddisfacente.
              Buona giornata.
              R.

            • #93925
              robitex
              Amministratore del forum
                Up
                0
                Down
                ::


                Eccomi qui!
                Osservate questo codice:
                `local cpath = kpse.find_file('sqlite3.so', 'clua')
                texio.write_nl(cpath)
                local luasql = package.loadlib(cpath, 'luaopen_luasql_sqlite3')

                env = assert(luasql().sqlite3())`

                Con esso si fa a meno di qualsiasi intervento manuale! 8)
                Per prima cosa si incarica il modulo LuaTeX kpse di ricercare il percorso della libreria specificando che si tratta di una libreria dinamica scritta in C.
                L’istruzione successiva stampa ilpercorso in console per controllo.
                Ok.
                Adesso si utilizza la funzione di basso livello package.loadlib. Essa ha bisogno di due argomenti: il percorso alla libreria (cha abbiamo appena fatto ricercare) ed il nome della funzione entry-point.

                A questo punto non rimane che creare l’ambiente per lavorare chiamando due funzioni in cascata: luasql() restituisce una tabella che contiene la funzione sqlite3, quindi il codice significa chiama luasql() per ottenere la tabella che contiene la funzione principale, ed eseguila per ottenere l’ambiente, ovvero il pieno e completo accesso alle funzionalità della libreria.

                Questo è un esempio minimo compilabile se solo si ha l’accortezza di creare a parte il file del database con il codice postato all’inizio:
                `% !TEX program = lualatex

                \documentclass{article}
                \usepackage{luacode,booktabs}

                \begin{document}
                \begin{luacode*}
                local cpath = kpse.find_file('sqlite3.so', 'clua')
                texio.write_nl(cpath)
                local luasql = package.loadlib(cpath, 'luaopen_luasql_sqlite3')

                env = assert(luasql().sqlite3())
                texio.write_nl(type(env))

                — connect to data source
                con = assert (env:connect(“luasql-test”))
                — retrieve a cursor
                cur = assert (con:execute”SELECT name, email from people”)
                — print all rows, the rows will be indexed by field names
                row = cur:fetch ({}, “a”)
                tex.sprint([[\begin{tabular}{@{}ll@{}}\toprule]])
                tex.sprint([[Name & email \\\midrule]])
                while row do
                tex.sprint(-2,row.name)
                tex.sprint(“&”)
                tex.sprint(-2, row.email)
                tex.sprint(“\\\\”)
                — reusing the table of results
                row = cur:fetch (row, “a”)
                end
                tex.sprint([[\bottomrule\end{tabular}]])
                — close everything
                cur:close()
                con:close()
                env:close()
                \end{luacode*}
                \end{document}
                `

                Non so cosa accedrebbe se sul sistema fossere installati più file sqlite3.so. Una cosa questa da approfondire.

                Se volessimo conoscere la versione della libreria dinamica potremo fare:
                `% !TEX program = lualatex

                \documentclass{article}
                \usepackage{luacode,booktabs}

                \begin{document}
                \begin{luacode*}
                local cpath = kpse.find_file('sqlite3.so', 'clua')
                texio.write_nl(cpath)
                local luasql = package.loadlib(cpath, 'luaopen_luasql_sqlite3')

                local libdin = assert(luasql())
                texio.write_nl('VERSION: '..libdin._VERSION)
                texio.write_nl('COPYRIGHT: '..libdin._COPYRIGHT)
                texio.write_nl('DESCRIPTION: '..libdin._DESCRIPTION)
                \end{luacode*}
                \end{document}`
                per ottenere in console:`VERSION: LuaSQL 2.3.0
                COPYRIGHT: Copyright (C) 2003-2012 Kepler Project
                DESCRIPTION: LuaSQL is a simple interface from Lua to a DBMS
                `

                Devo dire che la documentazione di LuaTeX non ha il pregio di essere comprensibile. lo dico perché la consultazione non è agevole: molte informazioni sono omesse ed occorre una lenta ricerca dei singoli pezzi.

                Questo post non risolve ancora completamente il problema, però spiega come funzionano le cose un po’ meglio.
                L’ideale sarebbe poter ricorrere alla funzione require() di Lua. Forse serve scrivere un searcher specializzato ed aggiungerlo agli altri di LuaTeX (una cosa simile a quello di Oberdiek [luatexbase.loder] che funziona solo per librerie esterne scritte in Lua).

                Proseguo le ricerche intanto, augurandovi una buona serata.
                R.

              • #93926
                robitex
                Amministratore del forum
                  Up
                  0
                  Down
                  ::


                  Solo un paio di veloci aggiornamenti:
                  1 – non sono riuscito a duplicare il successo del codice con la funzione di basso livello package.loadlib() con Windows.
                  ricevo in console il messaggio che il codice è andato in crash nel momento in cui eseguo la funzione restituita da loadlib().

                  2 – ho capito perché texlua mi dava diversi percorsi di ricerca: infatti il programma non coinvolge kpathsea ma esegue la ricerca tradizionale di Lua.
                  R.

                • #93927
                  robitex
                  Amministratore del forum
                    Up
                    0
                    Down
                    ::


                    Ho esplorato i package searchers disponibili in LuaLaTeX con questo codice:
                    `
                    % !TEX program = lualatex

                    % stampa informazioni sui searchers predefiniti di LuaTeX

                    \documentclass{article}
                    \usepackage{luacode,booktabs}
                    \usepackage[landscape,margin=10pt]{geometry}
                    % fornisce ben 5 funzioni di searching
                    % la prima verifica se la libreria è già stata caricata
                    % la seconda cerca librerie `lua' con kpse (file luatexbase.loader.lua)
                    % la terza cerca nella cartella locale
                    % la quarta è il searcher di Lua classico o altro simile
                    % la quinta è quella di oberdiek che cerca tra gli script in texmf

                    \begin{document}
                    \begin{luacode*}
                    tex.sprint(#package.searchers)
                    tex.print('\\\\')

                    for k, v in pairs(package.searchers) do
                    tex.print(k)
                    tex.print(type(v))
                    tex.print('\\\\')
                    tex.print('\\verb='..v('luasql.sqlite3')..'=')
                    tex.print('\\\\')

                    texio.write(v('luasql.sqlite3'))
                    end

                    \end{luacode*}
                    \end{document}
                    `

                    Vi sono 5 searcher. Alcuni sfruttano kpathsea per cercare i file ma tutti non sono adatti per caricare librerie dinamiche tranne forse quello che nei commenti del listato ho definito predefinito.

                    Ho anche scritto un searcher personalizzato che dovrebbe funzionare in Linux OsX e Windows, a meno di ulteriori problemi.
                    Ecco il codice:
                    `% !TEX program = lualatex

                    % aggiunge un nuovo searcher

                    \documentclass{article}
                    \usepackage{luacode,booktabs}

                    \begin{document}
                    \begin{luacode*}

                    function my_searcher(lib)
                    local libname = lib:match('%.(%w+)$') or lib
                    local libext
                    if os.type == 'unix' then
                    libext = '.so'
                    else
                    libext = '.dll'
                    end
                    local libfile = kpse.find_file(libname..libext, 'clua')
                    if not libfile then
                    return '\n\t[my_searcher] Search failed'
                    end
                    local fn = lib:gsub('%.', '_')
                    local loader = package.loadlib(libfile, 'luaopen_'..fn)
                    if not loader then
                    return '\n\t[my_searcher] Loading failed'
                    end
                    return loader
                    end

                    package.searchers[#package.searchers+1] = my_searcher

                    local luasql = require 'luasql.sqlite3'

                    local env = luasql.sqlite3()

                    — connect to data source
                    con = assert (env:connect(“luasql-test”))
                    — retrieve a cursor
                    cur = assert (con:execute”SELECT name, email from people”)
                    — print all rows, the rows will be indexed by field names
                    row = cur:fetch ({}, “a”)
                    tex.sprint([[\begin{tabular}{@{}ll@{}}\toprule]])
                    tex.sprint([[Name & email \\\midrule]])
                    while row do
                    tex.sprint(-2,row.name)
                    tex.sprint(“&”)
                    tex.sprint(-2, row.email)
                    tex.sprint(“\\\\”)
                    — reusing the table of results
                    row = cur:fetch (row, “a”)
                    end
                    tex.sprint([[\bottomrule\end{tabular}]])
                    — close everything
                    cur:close()
                    con:close()
                    env:close()

                    \end{luacode*}
                    \end{document}
                    `

                    Caricando il nuovo searcher da un file a parte, torna a funzionare un codice tradizionale basato sulla funzione principale require().
                    Il searcher è sostanzialmente la soluzione che avevo trovato in precedenza integrata nel sistema dei moduli di Lua.
                    Con questo, se non ci sono domande o contributi, chiuderei il filone. Nei prossimi mesi la situazione potrebbe migliorare di molto, se avranno successo i progetti del team di LuaTeX di cui fa parte il nostro Luigi Scarso.

                    Un saluto a tutti.
                    R.

                Visualizzazione 5 filoni di risposte
                • Devi essere connesso per rispondere a questo topic.

                Go to top