|
| 1 | +## Copyright (C) 2023 John Donoghue |
| 2 | +## |
| 3 | +## This file is part of Octave. |
| 4 | +## |
| 5 | +## Octave is free software; you can redistribute it and/or modify it |
| 6 | +## under the terms of the GNU General Public License as published by |
| 7 | +## the Free Software Foundation; either version 3 of the License, or (at |
| 8 | +## your option) any later version. |
| 9 | +## |
| 10 | +## Octave is distributed in the hope that it will be useful, but |
| 11 | +## WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | +## General Public License for more details. |
| 14 | +## |
| 15 | +## You should have received a copy of the GNU General Public License |
| 16 | +## along with Octave; see the file COPYING. If not, see |
| 17 | +## <http://www.gnu.org/licenses/>. |
| 18 | + |
| 19 | +## -*- texinfo -*- |
| 20 | +## @deftypefn {} {@var{data} =} sqlfind (@var{db}, @var{pattern}) |
| 21 | +## @deftypefnx {} {@var{data} =} sqlfind (@var{db}, @var{pattern}, @var{propertyname}, @var{propertyvalue} @dots{}) |
| 22 | +## Find information about table types in a database. |
| 23 | +## |
| 24 | +## @subsubheading Inputs |
| 25 | +## @table @asis |
| 26 | +## @item @var{db} |
| 27 | +## currently open sqlite database. |
| 28 | +## @item @var{pattern} |
| 29 | +## Name or pattern to match table in database. Use '' to match match all tables. |
| 30 | +## @item @var{propertyname}, @var{propertyvalue} |
| 31 | +## property name/value pairs where known properties are: |
| 32 | +## @table @asis |
| 33 | +## @item Catalog |
| 34 | +## catalog value to match |
| 35 | +## @item Schema |
| 36 | +## schema value to match |
| 37 | +## @end table |
| 38 | +## @end table |
| 39 | +## |
| 40 | +## Note: currently the property values are not used in the filter process. |
| 41 | +## |
| 42 | +## @subsubheading Outputs |
| 43 | +## @table @asis |
| 44 | +## @item @var{data} |
| 45 | +## a table containing the query result. Table columns are |
| 46 | +## 'Catalog', 'Schema', 'Table', 'Columns', 'Type'. |
| 47 | +## @end table |
| 48 | +## |
| 49 | +## @subsubheading Examples |
| 50 | +## Show all tables in the database. |
| 51 | +## @example |
| 52 | +## @code { |
| 53 | +## # create sql connection to an existing database |
| 54 | +## db = sqlite("mytest.db"); |
| 55 | +## # list all tables |
| 56 | +## data = sqlfind(db, ''); |
| 57 | +## } |
| 58 | +## @end example |
| 59 | +## |
| 60 | +## Show information about TestTable |
| 61 | +## @example |
| 62 | +## @code { |
| 63 | +## # create sql connection |
| 64 | +## db = sqlite("mytest.db"); |
| 65 | +## # list matching tables |
| 66 | +## data = sqlfind(db, 'TestTable'); |
| 67 | +## } |
| 68 | +## @end example |
| 69 | +## |
| 70 | +## @seealso{sqlite} |
| 71 | +## @end deftypefn |
| 72 | + |
| 73 | +function data = sqlfind (db, pattern, varargin) |
| 74 | + if nargin < 2 |
| 75 | + print_usage(); |
| 76 | + endif |
| 77 | + |
| 78 | + if !ischar(pattern) |
| 79 | + error ("Expected pattern as a string"); |
| 80 | + endif |
| 81 | + |
| 82 | + if numel(varargin) >0 |
| 83 | + if mod (numel(varargin), 2) != 0 |
| 84 | + error ("expected property name, value pairs"); |
| 85 | + endif |
| 86 | + if !iscellstr (varargin (1:2:numel(varargin))) |
| 87 | + error ("expected property names to be strings"); |
| 88 | + endif |
| 89 | + endif |
| 90 | + |
| 91 | + # TODO: currently ignoring the properties |
| 92 | + |
| 93 | + [~, dbname, ~] = fileparts(db.Database); |
| 94 | + |
| 95 | + query = "select name from sqlite_schema where type = 'table' AND name not like 'sqlite_%'"; |
| 96 | + if !isempty(pattern) |
| 97 | + query = [query "AND name like '" pattern "'"]; |
| 98 | + endif |
| 99 | + |
| 100 | + tables = fetch(db, query); |
| 101 | + |
| 102 | + # TODO: currently getting error when go to access data in table from within the @octave_sqlite folder |
| 103 | + # but not as a struct |
| 104 | + tables = table2struct(tables).name; |
| 105 | + |
| 106 | + tablename = {}; |
| 107 | + catalog = {}; |
| 108 | + schema = {}; |
| 109 | + type = {}; |
| 110 | + columns = {}; |
| 111 | + |
| 112 | + for t = 1:length(tables) |
| 113 | + name = tables{t}; |
| 114 | + ti = fetch(db, sprintf("pragma table_info('%s');", name)); |
| 115 | + ti = table2struct(ti).name; |
| 116 | + |
| 117 | + tablename{end+1} = name; |
| 118 | + catalog{end+1} = dbname; |
| 119 | + schema{end+1} = 'dbo'; |
| 120 | + type{end+1} = 'table'; |
| 121 | + |
| 122 | + cols = {}; |
| 123 | + for j=1:length(ti) |
| 124 | + cols{end+1} = ti(j); |
| 125 | + endfor |
| 126 | + columns{end+1} = cols; |
| 127 | + endfor |
| 128 | + |
| 129 | + data = dbtable(catalog, schema, tablename, columns, type, "VariableNames", {'Catalog', 'Schema', 'Table', 'Columns', 'Type'}); |
| 130 | + |
| 131 | +endfunction |
| 132 | + |
| 133 | +%!test |
| 134 | +%! testfile = file_in_loadpath("data/bookdb.db"); |
| 135 | +%! db = sqlite(testfile, "readonly"); |
| 136 | +%! data = sqlfind(db, ""); |
| 137 | +%! assert(size(data), [3 5]) |
| 138 | +%! |
| 139 | +%! data = sqlfind(db, "Authors"); |
| 140 | +%! assert(size(data), [1 5]) |
| 141 | +%! assert(data{1,3}{1}, 'Authors') |
| 142 | +%! close (db); |
0 commit comments