Небольшое описание задачи:
Есть приложение для администрирования базы данных, требуется реализовать функциональность типа Create DML procrdures в TOAD. То есть, у нас есть табличка, к ней требуется написать процедуры add, update, delete.
Для обеспечения большей гибкости решено было сделать генерацию по шаблону, так чтобы пользовать в случае необходимости мог легко поправить его так как ему нужно.
Испробованные решения:
Первая и единственная попытка использовала XSLT преобразование. То есть генерировалось описание табличи в XML на которое натравливалось XSLT преобразование. Единственное что останавливает -- это сложность XSLT файла. Пользователю будет трудно его модифицировать.
Воспрос:
А вот, например, Smarty-шаблон намного понятнее. Есть ли подобный шаблонизатор для Delphi? Может быть есть какие-то другие предложения?
Замечания:
Просмотр первых пяти страниц гугла по разным запросам ничего не дал,
В проекте используется Delphi 7.
Здравствуйте, Eugene Tihonov, Вы писали:
ET>Небольшое описание задачи: ET> Есть приложение для администрирования базы данных, требуется реализовать функциональность типа Create DML procrdures в TOAD. То есть, у нас есть табличка, к ней требуется написать процедуры add, update, delete. ET> Для обеспечения большей гибкости решено было сделать генерацию по шаблону, так чтобы пользовать в случае необходимости мог легко поправить его так как ему нужно.
А зачем так сложно-то делали?
1) Получили список полей в таблицы в StringList (желательно первичный ключ тоже определить для таблицы FIELDPK к примеру).
FIELD1
FIELD2
etc...
2) Создали шаблон типа:
UPDATE %%TABLENAME%%
SET
%%FIELD1%%=:%%FIELD1%%,
%%FIELD2%%=:%%FIELD2%%
....
WHERE %%FIELDPK%%=:%%FIELDPK%%
3) Дали пользователю CheckListBox с возможностью снять выделение с ненужных полей
4) На основе отмеченных полей сделали простой TextReplace() для шаблона
5) Все остальные поля — убрали из шаблона.
6) Почистили возможные задвоенные запятые
Фсе
Здравствуйте, DarkMaster, Вы писали:
DM>Здравствуйте, Eugene Tihonov, Вы писали:
ET>>Небольшое описание задачи: ET>> Есть приложение для администрирования базы данных, требуется реализовать функциональность типа Create DML procrdures в TOAD. То есть, у нас есть табличка, к ней требуется написать процедуры add, update, delete. ET>> Для обеспечения большей гибкости решено было сделать генерацию по шаблону, так чтобы пользовать в случае необходимости мог легко поправить его так как ему нужно.
DM>А зачем так сложно-то делали? DM>1) Получили список полей в таблицы в StringList (желательно первичный ключ тоже определить для таблицы FIELDPK к примеру). DM> FIELD1 DM> FIELD2 DM> etc... DM>2) Создали шаблон типа: DM> UPDATE %%TABLENAME%% DM> SET DM> %%FIELD1%%=:%%FIELD1%%, DM> %%FIELD2%%=:%%FIELD2%% DM> .... DM> WHERE %%FIELDPK%%=:%%FIELDPK%% DM>3) Дали пользователю CheckListBox с возможностью снять выделение с ненужных полей DM>4) На основе отмеченных полей сделали простой TextReplace() для шаблона DM>5) Все остальные поля — убрали из шаблона. DM>6) Почистили возможные задвоенные запятые DM>Фсе
DM>Для INSERT,DELETE — по аналогии.
Спасибо за ответ.
Тут дело в том, что такую операцию скорее всего придётся проделывать не для одной таблицы, а для нескольких. Нужен общий шаблон. Пользователь его поправил и сгенерировал скрипт для всех таблиц.
Здравствуйте, Eugene Tihonov, Вы писали:
DM>>Для INSERT,DELETE — по аналогии.
ET>Спасибо за ответ.
ET>Тут дело в том, что такую операцию скорее всего придётся проделывать не для одной таблицы, а для нескольких. Нужен общий шаблон. Пользователь его поправил и сгенерировал скрипт для всех таблиц.
А какая разница для одной или нескольких? Получили список полей таблицы и генерируйте сколько душе угодно. Ваш шаблон в общем виде сводится к :
SQL_COMMAND_HEADER TABLENAME (у вас — INSERT, UPDATE, DELETE (можно SELECT) для таблицы TABLENAME)
FIELDS_LIST (подстановка имен полей FIELD_xxx=:FIELD_xxx)
SQL_COMMAND_END ( WHERE FIELD_yyy=:FIELD_yyy)
Т.е. простая работа с текстом. Вам только вместо FIELDS_LIST придется подставлять свой список и все.
Здравствуйте, Eugene Tihonov, Вы писали:
ET>Тут дело в том, что такую операцию скорее всего придётся проделывать не для одной таблицы, а для нескольких. Нужен общий шаблон. Пользователь его поправил и сгенерировал скрипт для всех таблиц.
Даже напишу примерчик :
const
UP_SQL='UPDATE %TABLENAME% SET %FIELDLIST% WHERE %PKFIELD%;';
var FieldList:TStringList;
i:integer;
SQL:string;
S:String;
//-------- .......... -------------------
GetFieldListForTable(TableName, FieldList, PKFieldName); // получили список полей + PK поля для таблицы TableName
CheckListBox1.Items.Assign(FieldList); // дали пользователю что-то почекать в списке
// .... тут диалог показали, если все ок - двигаем дальше .....
// убираем ненужные поляfor i:=Pred(CheckListBox1.Items.Count) downto 0 do
if not CheckListBox1.Checked[i] then FieldList.Delete(i);
// начинаем строить шаблон
SQL:=UP_SQL;
// подставляем имя таблицы
SQL:=StringReplace(SQL,'%TABLENAME%',TableName,[rfReplaceAll,rfIgnoreCase]);
// подставляем список полей, который предварительно строим
S:='';
for i:=0 to Pred(FieldList.Count) do
begin
S:=S+FieldList.Strings[i]+'=:'+FieldList.Strings[i];
if i<Pred(FieldList.Count) then S:=S+',';
S:=S+#13#10;
end;
SQL:=StringReplace(SQL,'%FIELDLIST%',S,[rfReplaceAll,rfIgnoreCase]);
// ну и под конец - заканчиваем генерацию
S:=PKFieldName+':='+PKFieldName;
SQL:=StringReplace(SQL,'%PKFIELD%',S,[rfReplaceAll,rfIgnoreCase]);
Здравствуйте, DarkMaster, Вы писали:
DM>Здравствуйте, Eugene Tihonov, Вы писали:
ET>>Тут дело в том, что такую операцию скорее всего придётся проделывать не для одной таблицы, а для нескольких. Нужен общий шаблон. Пользователь его поправил и сгенерировал скрипт для всех таблиц.
DM>Даже напишу примерчик :
DM>
DM>const
DM> UP_SQL='UPDATE %TABLENAME% SET %FIELDLIST% WHERE %PKFIELD%;';
DM>var FieldList:TStringList;
DM> i:integer;
DM> SQL:string;
DM> S:String;
DM>//-------- .......... -------------------
DM> GetFieldListForTable(TableName, FieldList, PKFieldName); // получили список полей + PK поля для таблицы TableName
DM> CheckListBox1.Items.Assign(FieldList); // дали пользователю что-то почекать в списке
DM> // .... тут диалог показали, если все ок - двигаем дальше .....
DM> // убираем ненужные поля
DM> for i:=Pred(CheckListBox1.Items.Count) downto 0 do
DM> if not CheckListBox1.Checked[i] then FieldList.Delete(i);
DM> // начинаем строить шаблон
DM> SQL:=UP_SQL;
DM> // подставляем имя таблицы
DM> SQL:=StringReplace(SQL,'%TABLENAME%',TableName,[rfReplaceAll,rfIgnoreCase]);
DM> // подставляем список полей, который предварительно строим
DM> S:='';
DM> for i:=0 to Pred(FieldList.Count) do
DM> begin
DM> S:=S+FieldList.Strings[i]+'=:'+FieldList.Strings[i];
DM> if i<Pred(FieldList.Count) then S:=S+',';
DM> S:=S+#13#10;
DM> end;
DM> SQL:=StringReplace(SQL,'%FIELDLIST%',S,[rfReplaceAll,rfIgnoreCase]);
DM> // ну и под конец - заканчиваем генерацию
DM> S:=PKFieldName+':='+PKFieldName;
DM> SQL:=StringReplace(SQL,'%PKFIELD%',S,[rfReplaceAll,rfIgnoreCase]);
DM>
Ещё раз спасибо за ответ и за предложение.
Однако, например, в случае генерации какого-нибудь insert_country получится, что надо иметь список полей некольких разных типов.
При такой реализации у пользователя путём правки шаблонов не получиться изменить префикс параметров (наприемер in_id).
Кроме того, если он захочет сгенерировать для Oracle пакет вместо набора процедур, у него ничего не получится.
Короче решили мы всё таки использовать XSLT для такой задачи. Есть такой продукт, который именно так и делает: http://www.latticesoft.com/
Чтобы закончить тему скажу следующее:
При углубленном поиске по интеренету оказалось, что время от времени у людей встаёт вопрос о наличии такого шаблонизатора для Delphi, но найти удалось только делфёвую обёртку над Smarty. Однако для других платформ (.NET, Java) имеется и не один компонент с подобной функциональностью.