Найдите исполнителя для вашего проекта прямо сейчас!
Разместите заказ на фриланс-бирже и предложения поступят уже через несколько минут.

Постановка на разработку классов TDataObject.

Особое предупреждение!

По своему назначению, разработка крайне критичная.

Если вы раньше не делали ничего подобного, и/или не уверены в своих силах – пожалуйста, не беритесь.

Требуются ссылки на уже сделанные работы подобного рода.

Назначение класса: операции с данными, ранее выбранными из БД, и теперь сохраненными в памяти PC. Нечто вроде TDataSet, но проще и с большей функциональностью.

Название класса: TDataObject.

Родитель: TObject .

Бюджет – 15.000 рублей.

Срок реализации – 31 день.

Рассмотрю 3 конкурсных работы, с оплатой 30$ за каждую, со сроками исполнения 10 дней.

Требования к конкурсным работам.

1. Реализация методов SortBy и Find (См. ниже);

2. Демка:

2.1. TdataTable имеет 4 поля:

2.1.1. IntegerField: integer;

2.1.2. NumCField: string[10] – символьное длиной 10 символов, содержащее только цифры;

2.1.3. StringField – полей типа string (неограниченной длины).

2.1.4. NoSortField: string.

2.2. Должна осуществлять операции:

2.2.1. Генерации 10.000.000 записей (стандартным генератором случайных чисел);

2.2.2. Их сортировки по произвольным последовательностям полей IntegerField, NumCField и StringField.

2.2.3. Пользовательский интерфейс может быть максимально простым (во избежание его влияния на производительность).

Требования.

1.) Надежность.

2.) Скорость.

3.) Никаких вопросов, почему меня не устраивают стандартные компоненты VCL, предназначенные для работы с базами данных. Я не знаю, почему Борланд до сих пор не сделал ничего подобного.

Концепция.

Требуется разработать объекты двух типов:

1) Структура - TDataStructure;

2) Таблица – TDataTable(TDataStructure);

Описатели-определители.

Их структура будет дана дополнительно.

TDataFieldDef – описатель для полей. Подобны TFieldDef, но построены на несколько других принципах (ориентация не на типы полей, а на их назначение). Организуются по иерархическому принципу. Должна быть возможность поддержки полей-структур и полей-таблиц.

TDataObjectDef(TDataFieldDef) - описатель для TDataObject.

Операции поиска.

Перед началом производства каких-либо действий поиска с таблицей, она должна быть обязательно отсортирована (иначе выдать ошибку). Так что должен быть быстрый, надежный и простой способ ее отсортировать, порядок сортировки должен быть запомнен. При добавлении или удалении записей, заданный порядок сортировки не должен нарушаться.

Любые операции поиска осуществляются по принципу двоичного дерева. Потому сортированность имеет критичное значение (без соответствующей сортировки, результаты поиска будут некорректными).

Записи-ссылки.

Должна быть поддержка как обычных записей, так и записей-ссылок. Запись-ссылка – это запись, которая не содержит собственных физических данных, а только ссылку на физические данные другой таблицы. При этом должны запоминаться:

• Таблица, являющаяся ссылочной;

• Таблица, которой принадлежат физические данные.

С помощью таблиц-ссылок, должна быть возможность организации в связанные «гирлянды». Например есть «корневая» таблица, содержащая массив физических данных.

К ней создается таблица-ссылка, содержащая ссылки на определенное подмножество записей этой таблицы. Далее, к таблице-ссылке создается следующая таблица-ссылка, содержащая ссылки на более узкое подмножество записей.

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

С помощью массивов таких ссылок, должна быть возможность создания вторичных индексов для таблиц, для поддержки нескольких альтернативных порядков сортировки (каждая таблица может иметь несколько таблиц-сателлитов, содержащих только ссылки на ее физические данные, и отсортированных по альтернативным принципам).

Если таблица не отсортирована требуемым образом, но имеет вторичный индекс по этому порядку сортировки – не выдавать ошибку об отсутствии сортировки, а использовать вторичный индекс.

Алгоритм изменения содержимого таблиц.

Отличается от принятого в VCL, и заимствован из языка ABAP платформ фирмы SAP.

Каждая таблица имеет “HeaderLine: TDataStructure”, совпадающую по своей структуре со структурой таблицы.

Данные в этой структуре можно свободно менять без вызова всяких Edit, отображение изменений в таблицу произойдет только после вызова Modify.

Доступ к значениям полей.

Аналогично TDataSet:

TDataStructure[FieldName: string]: Variant;

МЕТОДЫ.

Особо Критичные.

1) SortBy(Имена полей: string имен полей через точку с запятой; AIndexName: string);

Сортирует таблицы в заданном порядке. Хотелось бы использовать самый быстрый существующий алгоритм (например, алгоритм «быстрой сортировки» Хоара, хотя, учитывая, что придется сортировать по нескольким полям одновременно – возможно, лучше подойдет сортировка методов вставок). Если задается AIndexName, создается таблица-сателлит с этим именем, представляющая собой вторичный индекс. Если не задан – сортируется физически сама таблица.

2) Find(Критерии: TRanges); // находит первую запись, удовлетворяющую заданным критериям, данные помещаются в HeaderLine

Это базовые методы. К ним предъявляются наиболее высокие требования.

Полный простор для творчества. Assembler приветствуется.

Пояснения.

===================================

TComparisonType = (ctLessThan, ctLessEqaulThan, ctEqual, ctBetween, ctGreaterEqual, ctGreaterThan, ctMask);

TIncludeType = (itInclude, itExclude)

TRangesItem = record

FieldName: string;

Low, High: string;

Option: TComparisonType:

Sign : TIncludeType;

end;

TRanges = array of TRangesItem;

ctMask = задание множеств значений по маске («*PSIH*», «$$$», и т.д.  ).

С помощью таких массивов, получаем средство для исчерпывающего описания множества значений для всех полей. Идея заимствована из языка ABAP системы SAP R/3.

Массивы для разных полей стыкуются друг с другом по правилу AND.

Внутри массива для каждого из полей, стыкуются по правилу

(IncludeRange1 OR IncludeRange2 OR …IncludeRangeN) AND NOT (ExcludeRange1 OR ExcludeRange2 OR … ExcludeRangeN)

==========================================

Остальные методы.

3) Constructor TDataObject.Create(TDataObjectDef);

Конструктор, создает TDataObject заданной структуры;

4) Constructor TDataTable.CreateAsCopyFrom(AAsRefs: boolean; ASource: TDataTable; ARanges: TRanges; ASortFields: string);

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

Если “AAsRefs = true”, создает таблицу с записями-ссылками. Иначе копирует физические данные

5) Constructor TDataObject.CreateFromPack(ASource: string);

Создает TDataObject из пакета. При этом пакет должен содержать не только данные, но и описание структуры. См. подробнее методы PackToString, UnpackFromString.

6) TDataTable.BeginLoop(Критерии: TRanges; LoopName: string);

7) TDataTable.NextLoop(LoopName: string): boolean;

8) TDataTable.EndLoop(LoopName: string);

Для организации циклов по записям, удовлетворяющих заданным условиям. Поиск первой записи, удовлетворящей заданным условиям, должен осуществляться по принципу двоичного дерева, далее читаются остальные записи. Таблица должна быть соответствующим образом отсортирована, иначе ошибка.

EndLoop сбрасывает режим.

Должна быть возможность циклов по нескольким принципам одновременно (для этого и введен параметр LoopName). Например, идет внешний цикл по одному принципу. А внутри цикла, идет еще вложенный цикл по этой же таблице, организованный по другому принципу.

9) TDataTable.GetLoopProgress(ALoopName: string): integer;

Выдает округленный до целого прогресс прохождения Loop’a . Процент рассчитывается исходя из общего количества записей, и текущей позиции курсора (даже если заданы условия в Loop’e).

10) TDataTable.Function IsNew(ALoopName, AFieldNames: string): Boolean;

Используется внутри циклов по таблицам (см. ALoopName) . Возвращает true, если комбинация значений полей, имена которых указаны в AFieldNames (через точку с запятой), отличается от комбинации значений этих полей на предыдущем проходе.

11) TDataTable.Function IsEnd(ALoopName, AFieldNames: string): Boolean;

Почти то же самое, но для определения изменений значений на следующем проходе (true, если данная комбинация значений сменится в следующем проходе).

12) TDataTable.Function IsLast(ALoopName, AFieldNames: string): Boolean;

Почти аналогично, но true при последнем проходе.

13) TDataTable.ReadByIndex(AIndex: integer);

Читает запись по ее индексу, данные помещаются в HeaderLine.

14) TDataTable.Collect(ARanges: TRanges; const AKeyFields, ASumFields, ACountFields): TDataTable;

Все три параметра представляют собой последовательности имен полей, разделенных точкой с запятой. AKeyFields является обязательным параметром, но может содержать значение «*» (все поля являются ключевыми).

Создает сводную таблицу (по записям, удовлетворяющим заданным условиям), построенную по следующему принципу:

AKeyFields – список ключевых полей, по которым происходит группировка.

ASumFields – список полей, значения которых суммируются.

ACountFields – список полей, по которым подсчитывается количество уникальных значений полей.

Структура результирующей таблицы:

Поля из AKeyFields – без изменения имени, в том же порядке, каком перечислены и с тем же порядком сортировки;

Поля из ASumFields – имена суммируемых полей + приставка _SUM;

Поля из ACountFields – имена полей + приставка _COUNT;

Плюс, поле с фиксированным именем COUNT – содержит количество полей, вошедших в каждую группировку.

15) TDataTable.SumBy(ARanges: TRanges; const AKeyFields, ASumFields, ACountFields):TDataStructure;

Возвращает структуру, состоящую из полей, перечисленную через точку с запятой в AKeyFields, ASumFields, ACountFields, с правилами именования полей аналогичную в Collect, плюс поле COUNT. Структура содержим суммарные значения полей ASumFields у записей, удовлетворяющих ARanges, имеющих значения ключевых полей AKeyFields такие же, как у HeaderLine.

AKeyFields – список ключевых полей, по которым происходит группировка.

ASumFields – список полей, значения которых суммируются.

ACountFields – список полей, по которым подсчитывается количество уникальных значений.

16) TDataObject.PackToString: string;

Выполняет «развертывание» данных таблица в одну строку. Есть некоторые наработки, уточнения будут даны в более детальной постановке.

17) TDataObject.UnpackFromString(ASource: string);

Выполняет восстановление данных из строки (пакета).

Это основные особенности.

В детальной постановке будут еще дополнительные хотелки.

18 лет назад
av111
Гость 
NaN летРоссия
18 лет в сервисе
Был
17 лет назад
2 отзыва(-1)
Выбранный исполнитель
ossadchy
Юрий 
39 летУкраина
18 лет в сервисе
Был
15 лет назад
28 отзывов(-4)
18 лет назад
$600
10 дней
Работа выполнена безупречно, на совесть. Я думал, что моя задумка сама по себе гениальна :-) . Но Юрий выполнил ее даже лучше, чем я ожидал, использовав более оптимальные алгоритмы, чем предполагалось вначале. Работа выполнялась ответственно, без задержек, постоянно появлялись новые версии. Юрий постоянно держал в курсе работ, в Тырнете был создан сайт моего проекта, на который выкладывались текущие версии реализации, что удобно. Я по собственной инициативе заплатил за работу больше, чем было указано в тендере.