Как сделать калькулятор в Delphi?

Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.

Как Delphi реализует многоплатформенную разработку?

Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...

Разработаем свое BDE

Статьи » Базы данных » Разработаем свое BDE

Если вам надоела громоздкость BDE, сложность управления механизмом модификации БД в ADO. Если вам нравится FreeIB, но вы работаете с MSSQL, а еще если вас интересует, как упростить написание программ, одинаково работающих с различными SQL серверами, то эта статья для вас.

Я думаю, многие из читающих сталкивались с проблемой выбора SQL сервера для своего приложения. И хотя это действительно является серьезным вопросом, на мой взгляд самым лучшим вариантом при выборе SQL сервера - является золотая середина. А именно то, что программа должна одинаково работать с несколькими (а в идеале со всеми) серверами баз данных. При этом выбор сервера ложится на заказчика - тем самым мы предоставляем заказчику больше свободы.

На данный момент язык SQL уже стандартизирован, и большинство серверов уже могут оптимально выполнять SQL запросы без дополнительных (серверозависимых) оптимизирующих указателей. Но, к сожалению, при такой на первый взгляд прекрасной картине - мы сталкиваемся с тем, что написание таких приложений упирается в целый ряд непреодолимых проблем и большинство программистов отказывается от этого, и пишут программы для какого-то конкретного сервера. Заставить работать такое приложение с другим сервером – по трудоемкости сравнимо с написанием новой программы. В данной статье я попытаюсь рассказать о своем подходе к решению этой проблемы.


При работе со стандартными компонентами доступа к базам данных (BDE, ADO), которые на первый взгляд вроде как обладают возможностью переключения с одного сервера на другой, был обнаружен целый ряд проблем, которые привели к тому, что их использование в этих целях оказалось очень затруднительно, а порой даже невозможно. При этом большинство этих проблем выплывают при работе с MSSQL(6.5-2000). Например, в связи с особенностями реализации механизма транзакций и блокировок в данном сервере при работе с BDE иногда возникает ситуация, при которой приложение может заблокировать себя. Еще одним недостатком этих компонентов, является то, что отсутствует (либо малоэффективен) механизм работы с сессиями. А именно то, что эти компоненты могут самостоятельно устанавливать дополнительные подключения к серверу. Может быть это и не так криминально, но с моей точки зрения у программиста должен быть простой, и очень надежный механизм контроля над тем, в рамках какого подключения запускается данный запрос. Есть еще целый ряд компонентов, которые позволяют осуществлять доступ к SQL серверам, но в большинстве случаев они хоть и обладают хорошей функциональностью, но при этом привязаны к конкретному типу SQL сервера. Те же компоненты которые позволяют осуществлять доступ к различным БД – как правило платные, и ко мне они не попадались.

Проработав несколько лет с MSSQL, и немного изучив Oracle и InterBase, я пришел к выводу, что большинство проблем написания программ работающих с различными серверами связанны с тем, что в MSSQL данные слишком часто блокируются, и прочитать их до снятия блокировки возможно только при грязном чтении. Но если это обойти, то и InterBase, и Oracle вполне могут работать в так же, как и MSSQL. За исключением того, что в InterBase очень слабый механизм оптимизации запросов и на больших объемах данных он просто не справляется со сложными запросами. К сожалению, у меня не было возможности познакомиться с другими серверами баз данных, но я думаю, что уже хуже, чем в MSSQL быть не может.

Итак, что можно сделать, чтобы обойти вышеперечисленные проблемы:
· Запросы отправляемые на SQL server должны быть как можно проще и отрабатываться в очень короткие сроки. (а именно простые моментально, сложные запросы не более 5 секунд)
· Количество подключений (сессий, связей, конектов ..) к серверу БД должно быть минимальным, но достаточным. Проще всего это определяется если разделить запросы на 2 части
1 - Запросы к простым справочникам, с небольшим количеством возвращаемых записей (для всех запросов, как правило, достаточно одной сессии, но все данные необходимо «прокэшировать» в память клиента)
2 - Запросы с большим количеством возвращаемых записей («Длинные»), которые не всегда просматриваются полностью (на каждый запрос, как правило, создается свой коннект и крайне желательно ограничить количество возвращаемых записей и запустить фоновое кэширование данных, тем более, что объем оперативной памяти современных компьютеров позволяет)

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

· В любом случае необходимо позаботиться о том, чтобы транзакции (явные и не очень) были как можно короче по времени.
Если придерживаться этих на первый взгляд простых правил – то можно писать программы, которые даже при большом количестве пользователей, достаточно неплохо будут работать даже на слабых, по сегодняшним меркам, серверах. И при этом количество и время ожиданий сервера будет на приемлемом уровне.


Теперь, если все так просто, то почему же проблемы все-таки существуют? - Да очень просто – стандартные компоненты, как правило, не позволяют выполнить какие-то из данных требований. И при всей своей мощи они не справляются с возложенной на них задачей. Конечно в них есть ряд очень интересных функций, но на практике они в основном не применяются.

Давайте рассмотрим - что необходимо в настоящее время, при условии наличия мощных серверов баз данных, когда работа с dbf постепенно отходит в прошлое.

1. Производить подключение(я) к серверу базы данных.
2. Осуществлять контроль над транзакциями
3. Выполнять SQL запросы и возвращать клиету результаты выполнения этих запросов (Эти результаты, как правило, возвращаются в виде таблицы).
4. дать пользователю возможность отредактировать эту таблицу (пока без модификации данных на сервере)
5. на основе деиствий пользователя программа должна сформировать запросы на модификацию БД.
6. произвести синхронизацию данных сервера и клиента, после проведения изменений данных на сервере .
И что нам позволяют стандартные ADO и BDE ?
С первми четырьмя пунктами они практически справляются, а вот с 5 и 6 картина совершенно другая. ADO может сделать и 5 и 6, но нонтролировать то, как он это делает - практически не представляется возможным. При этом трудно предсказать как он поведет себя при смене сервера. BDE же хоть и предоставляет возможность контролировать пункт 5, но синхронизировать данные без переоткрытия запроса - не представляется возможным. Есть очень хорошие компоненты в которых все это реализованно - но они работают только с Interbase (их даже называть не нужно).

При написании программы структура БД достаточно хорошо известна и если всю логику работы по формированию запросов на изменение БД возложить на программу, и не перекладывать это на ADO или BDE то мы можем гарантировать, что генерируемые запросы на модификацию БД (при одинаковых условиях) будут постоянными. В связи с тем, что SQL достаточно стандартный то эти запрсы будут одинаково отрабатываться на разных серверах. Итого при написании компонентов для работы с БД можно выделить 2 части


1. Конкретная реализация работы с сервером, и реализация простыых функций DataSet
2. формирование последовательности SQL запросов для модификации и синхронизации.

Все, что необходимо от 1-й части - это простая передача запросов серверу и возвращение результатов. весь список функций состоит из пары десятков пунктов. Самая сложность этой части заключается в поддержке функций DataSet.


Неужели для того, чтобы запускать запросы необходим дистрибутив в несколько мегабайт? - Конечно нет. Для того, чтобы реализовать это взаимодействие с сервером достаточно реализовать всего лиш пару десятков функций. Как показала практика скомпилированная dll с этими функциями занимает около 100 килобайт. Функции, которые вынесены в dll, как две капли воды похожи на то, что необходимо реализавать в DataSet. Поэтому ни для кого не составит труда разобраться в них.

При всех минусах решения вынести эти функции именнов в dll у него есть пара больших плюсов.
1. dll можно написать не на Delphi (и не понадобится партировать функции серверного API под Delphi, что занимает очень много времени)
2. Это старый и очень надежный метод для организации plugin - ов.
во второй же части на основе простейших функций DataSet необходимо дать программисту осуществлять полный контроль над SQL, и дать возможность синхронизировать данные.

Поработав с различными компонентами и повнимательнее изучив используемые в DataSet объекты и структуры, можно прийти к выводу, что в стандартных структурах есть все, что необходимо для описания логики формирования запросов на обновление. Но как это ни странно они (эти свойства) практически не применяются. В частности основная информация о полях хранится в TField, а у этого объекта есть свойство ProviderFlags (где есть 4 очень хороших флажка). Ну и на основе этой информации можно составить 99% всех запросов на обновление. Более того даже при выборке из различных таблиц очень легко настроить обновление именно нужной таблицы. Для формирования запроса нехватает только имени таблицы, которое легко можно организовать. При этом получается простой, но очень эффективный механизм формирования SQL, который не зависит от особенностей BDE или ADO.

По поводу синхронизации данных то тут возможны 2 варианта

1. не синхронизировать весь набор, а синхронизировать только текущую строчку (ведь для 99% случаев этого достаточно) тут от программиста требуется дополнительный SQL для одной строчки.
2. Переоткрытие запроса и нахождение текущего положения. Это тоже достаточно просто организовать на основе все тогоже свойства ProviderFlags.


На вопрос - зачем это нужно, когда уже есть куча всяких разных компонентов на все случаи жизни. Можно ответить - конечно возможно обойтись тем, что уже есть. И на BDE и ADO можно писать вполне приличные программы, но ведь есть примеры когда библиотеки начинавшиеся как бесплатные, превращались в стандартные компоненты DELPHI. И наверняка большинство программистов работающих с BDE или ADO недовольны имеющимися возможностями. А написание компонентов, которые будут позволять делать все то, что необходимо - это не такая уж и тяжелая задача. И она вполне реальная и более того, большинство, из того, что здесь написано, уже работает. Пусть пока только для MSSQL и Oracle. Но в принципе уже можно воспользовавшись OLEDB драйвером подключаться и к другим SQL серверам.

Если вас заинтересовала эта идея, то присоединяйтесьв любой роли - критика, тестера или разработчика. Есть еще очень интересная идея организации объекта, который позволит быстро работать с очень большими наборами данны, но в связи с нехваткой времени - этот проект пока стоит на месте.

Результаты того, как это продвигается дальше и присоедениться вы можете по адресу http://erquery.narod.ru .
Любые вопросы присылайте по адресу kostik00@mail.ru

Другое по теме:

Категории

Статьи

Советы

Copyright © 2024 - All Rights Reserved - www.delphirus.com