RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Виртуальная таблица Swarmvtab

1. Обзор

Виртуальная таблица "swarmvtab" позволяет пользователю запрашивать большое количество таблиц (далее "входящие в комплект" таблицы) с подобными схемами, но отличными диапазонами rowid, как будто они были таблицей единой базы данных. Таблицы могут быть расположены в различных базах данных. Таблицы Swarmvtab только для чтения.

Входящие в комплект таблицы не должны быть объявлены WITHOUT ROWID и должны все иметь ту же самую схему, но могут иметь различные имена в их базах данных. В этом контексте, "та же самая схема" означает, что:

  • У всех входящих в комплект таблиц должен быть тот же самый набор колонок в том же самом порядке.
  • Типы и сортирующие последовательности по умолчанию, приложенные к каждой колонке, должны быть тем же самым для всех входящих в комплект таблиц.
  • У всех входящих в комплект таблиц должна быть та же самая декларация PRIMARY KEY (если таковые имеются).

У таблицы swarmvtab есть та же самая схема, как у каждой из ее входящих в комплект таблиц.

Виртуальная таблица swarmvtab составлена следующим образом:

CREATE VIRTUAL TABLE temp.<name> USING swarmvtab(<sql-statement>);

Виртуальные таблицы swarmvtab должны быть созданы в схеме temp. Попытка создать swarmvtab в основной или приложенной базе данных является ошибкой.

SQL-оператор, поставляемый как аргумент CREATE VIRTUAL TABLE, выполняется, когда таблица составлена. Это должно возвратить четыре или пять колонок. Каждая возвращенная колонка описывает одну из входящих в комплект таблиц. Первые четыре колонки интерпретируются, от начала до конца, как:

  • Database URI. Имя файла или URI, который может использоваться, чтобы открыть базу данных, содержащую входящую в комплект таблицу.
  • Table name. Название составляющей таблицы в ее базе данных.
  • Minimum rowid. Самое маленькое значение rowid, которое может содержать входящая в комплект таблица.
  • Maximum rowid. Самое большое значение rowid, которое может содержать входящая в комплект таблица.

Интерпретация последнего столбца, если это присутствует, см. здесь.

Например, скажите, что SQL-оператор возвращает следующие данные, когда выполнен:

Database URITable name Minimum rowidMaximum rowid
test.db1 t1 0 10
test.db2 t2 11 20
test.db3 t1 21 30
test.db4 t1 31 40

и пользователь запросил таблицу swarmvtab для строки с rowid = 25. Таблица swarmvtab откроет файл "test.db3" базы данных и прочитает данные, чтобы возвратить из таблицы "t1" (поскольку 25 находится в пределах диапазона rowid, назначенного на таблицу "t1" в "test.db3").

Swarmvtab эффективно обращается с диапазоном и ограничениями равенства только на rowid (или другой INTEGER PRIMARY KEY). Если запрос не содержит такое ограничение, то swarmvtab находит результаты, открывая каждую базу данных в свою очередь и линейно просматривая входящую в комплект таблицу. Это производит правильный результат, но является часто медленным.

Не должно быть никакого перекрывания диапазонов rowid в строках, возвращенных SQL-оператором. Это ошибка, если перекрытие есть.

Внедрение swarmvtab может открыть или закрыть базы данных в любом пункте. По умолчанию это пытается ограничить максимальное количество одновременно открытых файлов базы данных девятью. Это не жесткий предел: возможно построить сценарий, который заставит swarmvtab превышать его.

2. Сборка и применение Swarmvtab

Код для виртуальной таблицы swarmvtab лежит в файле ext/misc/unionvtab.c главного исходного дерева SQLite. Это может быть собрано в загружаемое расширение, используя команду:

gcc -g -fPIC -shared unionvtab.c -o unionvtab.so

Альтернативно, файл unionvtab.c может быть собран в приложение. В этом случае следующая функция должна быть вызвана, чтобы зарегистрировать расширение в каждом новом соединении с базой данных:

int sqlite3_unionvtab_init(sqlite3 *db, void*, void*);

Первым переданным аргументом должен быть дескриптор базы данных, чтобы зарегистрировать расширение. Второй и третий аргументы должны оба быть переданы как 0.

Исходный файл и точка входа названы по имени "unionvtab" вместо "swarmvtab". Unionvtab это отдельная виртуальная таблица, которая связана с swarmvtab.

3. Продвинутое использование

Большинство пользователей swarmvtab использует только функции, описанные выше. Эта секция описывает особенности, разработанные для более тайных вариантов использования. Эти особенности все включают определение дополнительных параметров после SQL-оператора как часть CREATE VIRTUAL TABLE. Дополнительный параметр определяется, используя его имя, сопровождаемое символом "=", и произвольно указанным значением в кавычках. Пробел может отделить имя, "=" и значение:

CREATE VIRTUAL TABLE temp.sv USING swarmvtab (
  'SELECT ...',                -- the SELECT statement
  maxopen = 20,                -- An optional parameter
  missing='missing_udf'        -- Another optional parameter
);

Следующие разделы описывают поддержанные параметры. Определение непризнанного названия параметра является ошибкой.

3.1. Параметры SQL

Если название параметра начинается с ":", это, как предполагается, значение, чтобы связать с SQL-оператором прежде, чем выполнить его. Значение всегда связывается как текст. Ошибка, если указанный параметр SQL не существует. Например:

CREATE VIRTUAL TABLE temp.x1 USING swarmvtab (
  "SELECT :dir || local_filename, tbl, min, max FROM components",
  :dir = '/home/user/app/databases/');

Когда вышеупомянутый CREATE VIRTUAL TABLE выполняется, swarmvtab связывает текстовое значение "/home/user/app/databases/" с параметром :dir SQL-оператора прежде, чем выполнить его.

Единственный CREATE VIRTUAL TABLE может содержать любое количество параметров SQL.

3.2. Параметр "maxopen"

По умолчанию swarmvtab пытается ограничить количество одновременно открытых баз данных девятью. Этот параметр позволяет этому пределу быть измененным. Например, чтобы составить swarmvtab-таблицу, которая может держать до 30 баз данных открытыми одновременно:

CREATE VIRTUAL TABLE temp.x1 USING swarmvtab ("SELECT ...", maxopen=30);

Увеличивание числа открытых баз данных может улучшить работу в некоторых сценариях.

3.3. Отзыв "openclose"

Параметр "openclose" позволяет пользователю определять название определенной применением функции SQL, которая будет вызвана непосредственно перед тем, как swarmvtab открывает базу данных, и снова сразу после того, как это закрывает ее. Первым аргументом, переданным функции, является имя файла или URI, определяющий базу данных, которая будет открыта или недавно закрыта (то же самое значение, возвращенное в крайнем левом столбце SQL-оператора, предоставленного команде CREATE VIRTUAL TABLE). Второй аргумент это целочисленное значение 0, когда функция вызвана прежде, чем открыть базу данных, и 1, когда это вызвано после того, как она закрывается. Например, если:

CREATE VIRTUAL TABLE temp.x1 USING swarmvtab ("SELECT ...",
       openclose = 'openclose_udf');

тогда, прежде чем каждая база данных, содержащая входящую в комплект таблицу, открыта, swarmvtab эффективно выполняет:

SELECT openclose_udf(<database-name>, 0);

После того, как база данных закрывается, swarmvtab управляет эквивалентом:

SELECT openclose_udf(<database-name>, 1);

Любое значение, возвращенное функцией openclose, проигнорировано. Если отзыв, сделанный прежде, чем открыть базу данных, возвращает ошибку, то файл базы данных не открыт, а ошибка, возвращена пользователю. Это единственный сценарий, в котором swarmvtab выпустит вызов "open", также в конечном счете не издавая соответствующий вызов "close". Если все еще есть открытые базы данных, вызовы "close" могут быть изданы из возможного sqlite3_close().

Ошибки, возвращенные вызовами "close", всегда игнорируются.

3.4. Отзыв "missing"

Параметр "missing" позволяет пользователю определять название определенной применением функции SQL, которая будет вызвана непосредственно перед тем, как swarmvtab открывает базу данных, если это находит, что необходимый файл базы данных не присутствует на диске. Это предоставляет применению возможность восстановить необходимую базу данных из отдаленного источника, прежде чем swarmvtab попытается открыть ее. Единственным аргументом, переданным функции "missing", является имя или URI, который определяет открываемую базу данных. Допустим:

CREATE VIRTUAL TABLE temp.x1 USING swarmvtab ("SELECT ...",
       openclose = 'openclose_udf', missing='missing_udf');

тогда функция missing вызвана следующим образом:

SELECT missing_udf(<database-name>);

Если функция возвращает ошибку, то база данных не открыта, а ошибка возвращена пользователю. Если функция openclose формируется, то "close" выпущена в этом пункте, чтобы соответствовать более ранней "open". Следующий псевдокод иллюстрирует процедуру, используемую swarmvtab, когда составляющая база данных открыта.

SELECT openclose_udf(<database-name>, 0);
if( error ) return error;
if( db does not exist )
{
  SELECT missing_udf(<database-name>);
  if( error )
  {
    SELECT openclose_udf(<database-name>, 1);
    return error;
  }
}
sqlite3_open_v2(<database-name>);
if( error )
{
  SELECT openclose_udf(<database-name>, 1);
  return error;
}
// db successfully opened!

3.5. Значения компоненты таблицы "context"

Если оператор SELECT определен как часть CREATE VIRTUAL TABLE, команда возвращает пять колонок, последний столбец используется только для прикладного контекста. Swarmvtab не использует это значение вообще, за исключением того, что это передается после <database-name> функциям openclose и missing, если определено. Другими словами, вместо того, чтобы вызвать функции, как описано выше, если колонка "context" присутствует, swarmvtab вместо этого вызывает:

SELECT missing_udf(<database-name>, <context>);
SELECT openclose_udf(<database-name>, <context>, 0);
SELECT openclose_udf(<database-name>, <context>, 1);