От автора.
По роду своей деятельности мне приходилось применять нетривиальные решения для достижения поставленных целей. И часто, для удобства просмотра и обработки информации применяю массивы. А для удобства работы с массивами – ArrayServer (сервер-массив).
До последнего времени в качестве ArrayServer использовал bArrayServer. Но, в ходе работы был вынужден внести множество изменений. И, некоторое время назад я попытался списаться с автором библиотеки, предложив ему свои поправки. Автор bArrayServer рекомендовал мне написать свой класс.
Что ж… Не я первый, не я последний. И к концу лета 2012 года работа была сделана.
Краткое описание «движка»
Форматы данных ArrayServer-а:
AS_DATAFORMAT_FAST
AS_DATAFORMAT_NORMAL
AS_DATAFORMAT_DBASE
При использовании форматов AS_DATAFORMAT_FAST и AS_DATAFORMAT_NORMAL - добавлены два типа полей:
"O" - объект
"U" - неопределённый (любой)
Для этих типов полей не ведётся контроль их длины (хотя DBS_LEN д.б. > 0).
При использовании формата AS_DATAFORMAT_FAST - считается, что пользователь (программист) всё делает правильно, контроль за данными снижен. Нет контроля при записи и чтении данных, что увеличивает скорость работы.
При использовании формата AS_DATAFORMAT_NORMAL - добавлен контроль считываемых данных (только для DBASE типов полей) и приведение их к требуемому формату.
При использовании формата AS_DATAFORMAT_DBASE - допустимы только поля DBASE-типа. Чтение и запись данных - контролируются по максимуму.
Сделан контроль структуры базы данных.
- При DBASE-форматах из имён полей убираются пробелы и их длина ограничивается 10-ю символами.
- Вставлены ограничения на длины полей.
- Для цифровых полей длина десятичной части <= общей длины - 3 (знак+одно целое+точка).
Примечание: в DBF допустимо создание цифровых полей, имеющих только десятичную часть, но не все программы это поддерживают. Если Вам нужны такие крайности - всё в Ваших руках :))
Число записей в базе ограничено MAX_RECCOUNT – 2 147 483 646.
// Максимальное положительное LONG - 1 == 0x7FFFFFFF - 1
// Это же значение для bArrayServer-а: BMAX_RECORDS = 0x0FFFFFFF (268 435 455)
Метод Use позволяет менять и тело БД и дополнять другими данными (склейка массива).
Как и для DbServer – сделана работа SetOrderCondition( ).
Разрешена работа с Custom, Unique-ордерами и пр. Вообще, в отличии от bArrayServer, задействованы все установки SetOrderCondition( ).
Т.к. при работе с ArrayServer-ом дисковые операции не предусмотрены (это не файл), то
и размер буфера - нулевой. Работа с буфером данных - не предусмотрена.
Т.к. это не файловый сервер, то блокировки фактически не работают (они не нужны). RLOCK( ), RLockVerify( ), UnLock( ) и т.п. - всегда возвращают TRUE. __NotifyBufferFlush( ) - тоже ничего не делает.
Но, все эти методы оставлены для совместимости!
Кодировка сервера пока всегда ANSI. См. :Info( DBI_ISANSI )
Ордера.
- Как и в среде DBF, в этом классе возможно создание неполных ордеров. Т.е. таких, которые не содержат ключевые выражения для всех записей (как-то: Custom, Unique и пр.). Поэтому при смене ордера всегда может возникать ситуация, когда нельзя определить позицию ключа для текущей записи.
- Как и в среде DBF, при смене ордера - позиция записи не меняется (остаётся прежняя), независимо от того, найдена соответствующая позиция ключа или нет. Для решения возможных противоречий, как и в DBF, рекомендуется использовать Seek( ).
- Т.к. кодировка сервера пока только ANSI, то и ключевые выражения - тоже в ней.
Внимание! Важная информация о разделителях разрядов и дробных частей в ключевых выражениях. (См. случаи создания ордеров с преобразованием типа Str( NumberField ) и др.). Т.к. символы разделителей разрядов и дробных частей произвольно не меняются, их можно изменить только при отсутствии ордеров. Вид этих символов-разделителей фиксируется сервером при создании ордера. Если символы-разделители надо изменить, то сначала надо закрыть (удалить) все ордера, потом – установить нужное, и пересоздать ордера заново. Соответственно, OrderInfo( DBOI_KEYVAL ) - выдаст значение с учётом разделителей, установленных для сервера в настоящее время. См. :Info( DBI_GETDELIMETER ), Info( DBI_SETDELIMETER ).
SetRelation и др.
Мы можем установить связь с Detail-сервером. А вот DbServer в качестве Master-сервера для нас, скорее всего, не сможет быть, т.к. он работает через алиас. А у нас алиаса нет. Проблему можно обойти, сделав SubClassing и, написав для Вашего нового класса подходящий метод SetRelation( ).
См., как пример - bDbServer:SetRelation( ) из библиотеки bBrowser.
Мастер-сервер может быть только один.
Деталь-серверов - столько, сколько надо.
Примечания:
Класс пока без методов: Scope( ) и Eval( ).
В принципе, ядро для использования методов Scope( ) и Eval( ) – сделано.
Уже созданные методы – учитывают их использование. Заинтересованные лица могут спокойно это доделать. Что для этого надо:
- ClearScope( )
- Eval( )
- ForBlock:ACCESS
- ForBlock:ASSIGN
- Scope:ACCESS
- Scope:ASSIGN
- WhileBlock:ACCESS
- WhileBlock:ASSIGN
Отличия от классов DbServer и bArrayServer
METHOD Init( auStruct [, auData] [, wDataFormat] [, lReadOnly] ) CLASS msArrayServer
Arguments:
auStruct - A two-dimensional array that defines the field structure of the server. The first dimension of the array defines the fields. The second dimension defines the structure of each field.
The second dimension consists of five elements that are described in the following table:
Constant
|
Data type
|
Description
|
DBS_NAME
|
String
|
Name of field.
|
DBS_TYPE
|
String
|
Data type of field.
|
DBS_LEN
|
Integer
|
Length of field, including the decimal point and the decimal places.
|
DBS_DEC
|
Integer
|
Number of decimals.
|
DBS_ALIAS
|
String
|
Alias of field.
|
auData - A two-dimensional array that contains the records of the server. The array has the format { {aRecord1}, {aRecord2},…{aRecordn} } where each record is {ufield1, uField2, …}.
wDataFormat - The mode of data. The following values are supported:
Constant
|
Description
|
AS_DATAFORMAT_FAST
|
There is no verification of data (as in bArrayServer - BDATAFORMAT_NORMAL).
|
AS_DATAFORMAT_NORNAL
|
Simple verifications of data become (as in bArrayServer - BDATAFORMAT_DBASE). Default value.
|
AS_DATAFORMAT_DBASE
|
All necessary verifications of the input and output data (as in DbServer).
|
METHOD ClearOrder( [ <cOrder> | <nPosition> ] ) CLASS msArrayServer
// Description : Remove single or all orders associated with the data.
// Parameters : [<cOrder> | <nPosition>]
// Returns : LOGIC
Note: Unlike bArrayServer: if the specified warrant isn't present – TRUE returned value.
METHOD ClearSelection( ) AS VOID PASCAL CLASS msArrayServer
// Description : Completion of work with the Master-server (Master-Detail mode).
// Parameters : No
// Returns : VOID
ASSIGN DataFormat( wNewValue AS DWORD ) AS DWORD PASCAL CLASS msArrayServer
// Description : Sets new mode of data.
// Parameters : DWORD
// Returns : DWORD (New Mode)
wNewValue:
Constant
|
Description
|
AS_DATAFORMAT_FAST
|
There is no verification of data (as in bArrayServer - BDATAFORMAT_NORMAL).
|
AS_DATAFORMAT_NORMAL
|
Simple verifications of data become (as in bArrayServer - BDATAFORMAT_DBASE). Default value.
|
AS_DATAFORMAT_DBASE
|
All necessary verifications of the input and output data (as in DbServer).
|
ASSIGN SetViewDeleted( wNewValue AS DWORD ) AS DWORD PASCAL CLASS msArrayServer
// Description : Sets a new browse mode of deleted records.
// Parameters : DWORD
// Returns : DWORD (New Mode)
wNewValue - A numeric value that indicates how deleted records are to be treated. The following values are supported:
Constant
|
Description
|
AS_VIEWDELETED_FALSE
|
Deleted records are hidden.
|
AS_VIEWDELETED_TRUE
|
Deleted records are visible.
|
AS_VIEWDELETED_AUTO
|
The setting of the function SetDeleted() is used.
|
METHOD Use( auData AS ARRAY, lAppend := FALSE AS LOGIC ) AS LOGIC PASCAL ;
CLASS msArrayServer
// Description: Sets an array with data that contains the records of the server.
// Parameters : auData, lAppend
// Returns : LOGIC
auData - A two-dimensional array that contains the records of the server. The array has the format { {aRecord1}, {aRecord2},…{aRecordn} } where each record is {ufield1, uField2, …}.
lAppend - If FALSE (default) - Sets an array with data that contains the records of the server. If TRUE - is made addition of data (as ACopy( )).
METHOD Delete( [cForCondition | cbForCondition], [cWhileCondition | cbWhileCondition],;
[uScope], [lMark] ) CLASS msArrayServer
// Description : Delete the current record or the records specified with the scoping parameters.
// Parameters : [cForCondition | cbForCondition],;
// [cWhileCondition | cbWhileCondition],;
// [uScope],;
// [lMark]
// Returns : LOGIC (TRUE if successful; otherwise, FALSE)
Arguments:
If no parameters are specified, Delete() is subject to the server scope set with the msArrayServer ForBlock, WhileBlock and Scope access/assign methods. If not set, this server scope defaults to "no scope," and the method processes the current record.
cForCondition | cbForCondition – The condition evaluated for each record in the scope; if TRUE, the record is included in the processing. It provides the same functionality as the FOR clause of record processing commands.
cWhileCondition | cbWhileCondition – The condition evaluated for each record from the current record until the condition returns FALSE. It provides the same functionality as the WHILE clause of record processing commands.
uScope – The range of records to process, providing the same functionality as the ALL, REST and NEXT clauses of record processing commands.
uScope
|
Description
|
DBSCOPEALL
|
The scope is all the records in the table. This is the default, although if a WHILE condition is specified, the scope becomes DBSCOPEREST.
|
DBSCOPEREST
|
The scope is the remaining records in the table from the current position.
|
<nRecords>
|
The scope is the next <nRecords> records.
|
lMark – A logical value that determines whether the record is irrevocably deleted (FALSE) or marked for deletion (TRUE). Value by default – TRUE.
Этот проект продолжает развиваться и дополняться новыми методами. В ближайшее время будет производиться очередная оптимизация кода. Так что – «продолжение следует»!
В файле для скачивания после распаковки Вы получите:
- msArrSrv.dll
- msArrSrv-DLL.aef
- «Table of methods.xls» - список сделанных методов и описания их соответствий с другими классами.
P.S.: В настоящее время (12.03.2016) актуальная версия библиотеки – 1.0.0.24.