|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
из языка формальных спецификаций RAISE Specification Language -RSL. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2003, 00:31 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
ресурсы: RAISE группа работает на базе университета ООН в Макао http://www.iist.unu.edu/raise введение в rsl : http://users.i.com.ua/~agp1/arts/rslintro.tar.gz RAISE Specification Method (пример Харбор ): ftp.iist.unu.edu/pub/RAISE/method_book/book.zip текущая версия (под win32) проверяльщика / компилятора rsl -> c++ http://users.i.com.ua/~agp1/tools/rsl.win32.tar.gz руководство по компилятору ftp.iist.unu.edu/pub/RAISE/tool_manual реализация примера Харбор под Сайбез АСА http://users.i.com.ua/~agp1/software/hrb1.0.tar.gz использование rsl при реализации одной утилиты для заправочной станции сайбез АСА http://users.i.com.ua/~agp1/software/gsau0.90.tar.gz http://foxserver.nsvisual.com/objdb/gsau/uslrdb1251.html ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2003, 00:41 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
As for RSL -> SQL we decided to translate as database table only imperative specifications. All specification couldnot be translated as database table. In RSL, database tables can be represented as mapping from T1 to T2, where T1 is some type which is key and T2 some data. T1 in sql corresponds to field with constraints PRIMARY KEY or UNIQUE, T2 maybe splitted into several columns. Lets consider simple case, following specification Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131.
In this specification we have variable books wich type is mapping from Int to Book. Book type in its turn represents record of three fields(title of the book, author of the book and price of the book). It should be translated into sql table with 4 fields the first one with constraint either PRIMARY KEY or UNIQUE. Translator to C++(without SQL) works pretty well (see S42.rsl, S41.h and S41.cc attached files). So it will be better to change as less as possible in translator file(in GENTLE cpp.g). First thing which we did is to change RSLMap with RSL_SQL. RSL_sql.h file heavily based on RSL_map.h. All operators and functions which were defined in RSL_map.h are declared and defined in RSL_SQL.h file. Moreover defined some extra functions in RSL_SQL.h. In this case most difficult thing is that how to create table with correct filed type and filed name. For this reason we defined a bit complex but very powerfull macro, which name is CRT_ST_PROD_n. Where is n- the number of column of the table. See S42.rsl, S42.h and S42.cc files. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2003, 00:50 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
> > As for RSL -> SQL we decided to translate as database table only imperative ^^^^^^^^^^ I agree > specifications. All specification couldnot be translated as database table. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I am afraid I dont understand this statment. > In RSL, database tables can be represented as mapping from T1 to T2, where > T1 is some type which is key and T2 some data. T1 in sql corresponds to > field with constraints PRIMARY KEY or UNIQUE, T2 maybe splitted into several > columns. Lets consider simple case, following specification > >------------ > scheme S42 = > > class > ........................... > ttlbooks : Text -> read books Text-set > > ttlbooks(t) is > > {title(b) | > > b : Book :- > > b isin rng books /\ author(b) = t}, > >---------------- > .... > > In this specification we have variable books wich type is mapping from Int > to Book. Book type in its turn represents record of three fields(title of > the book, author of the book and price of the book). It should be translated > into sql table with 4 fields the first one with constraint either PRIMARY yes but I dont like so simple example at all. > KEY or UNIQUE. Translator to C++(without SQL) works pretty well (see > S42.rsl, S41.h and S41.cc attached files). So it will be better to change as > less as possible in translator file(in GENTLE cpp.g). First thing which we :)) of course > > did is to change RSLMap with RSL_SQL. RSL_sql.h file heavily based on > to be continued --- в своих рассуждениях как использовать rsl для спецификаций под RDBMS я начал думать совершенно также как ты в примере S42.rsl. 1 sql является очень экономным языком. в области, предназначенном для его применения, он экономнее чем rsl. кроме того, желательно что бы текст на rsl, хоть как то был похож на sql, для того, что бы sql программист мог его читать. поэтому я убежден, что надо стремиться к "похожести" спецификаций к, собственно, тексту sql - программ. например, ты ввел функцию insert (аналог оператора INSERT), имхо надо ввести функции delete и select - аналоги оператора DELETE и SELECT. с update - отдельный разговор. зачем функция для удаления называется remove2? дальше про удаление ( про select/has_author - те же мысли), в sql я могу задавать любые условия для удаления записей. почему такое универсальное средство как язык спецификаций начинает меня ограничивать настолько сильно и на ранних стадиях проекта. почему можно удалять только по имени книги? а если будет 20 полей в таблице - я буду вынужден писать 20 функций удаления по одному для каждого поля? на примере delete и твоем типе T1 (предназначенный для первичного ключа) у меня называется Key. я строил функцию (оператор) как delete Key-set -> write tbl Unit. (gsau/docs/rsl/Relation.rsl строчка 92). для более легкого создания необходимого множества (параметр функции) первичных ключей была написана функция where : (record -> Bool) -> read tbl Key-set - аналог фразы WHERE языка sql. теперь при необходимость применять функцию delete для удаления нужных записей я могу использовать любой предикат со множеством определения равным типу Book (хотя даже это сильное ограничение). и твою функцию remote2 (при необходимости) записал бы следующим образом remote2(ti) is delete( where(-\p:Book :- title(p) = ti) ) алгоритм работы можно представлять себе так where пробегает по первичному ключу таблицы, вынимает соотвествующие записи и если функция -\p:Book :- title :- title (p) = ti принимает значение true складывает этот ключ в выходное множество ключей. после чего delete удаляет записи с первичными ключами из построенного множества. моя версия remote2 короче твоей и почти похожа на sql оператор delete - излишестом есть только текст "-\p:Book :-". на sql соответствующий текст выглядит еще короче вместо "-\p:Book :- title(p) = ti" имеем "title = ti" 2 мне не нравится такой простой пример (из одной таблицы) вообще. в моем текущем проете 34 таблицы. я буду вынужден задавать функции insert, update, remote2, has_author для каждой из 34 таблиц? иногда бывает что таблицы имеет одну структуру - то есть для них придется создавать функции insert(и другие тоже) с какими-то модификациями в имени (перегрузка не будет работать) поэтому я написал параметризованную схему Relation.rsl, при помощи которой и создавал обьекты - аналоги таблиц. тогда вопрос с большим количеством таблиц становится не принципиальным. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2003, 00:53 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
Alexei First of all I am very thankful for all your help. I looked your gsauExm. It is very close and easy to understand for sql programmers. In Relation.rsl you used scheme with parameters. It is nice idea to have some relation with other tables. But have you tryed C++ translator? It seems automatic translator doesnot work if we use scheme with parameters. Moreover we cannot use C++ keywords in RSL specification(for example delete). ... |
|||
:
Нравится:
Не нравится:
|
|||
04.04.2003, 11:09 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
Hi Abdugany > > In S42.h you can see > > CRT_ST_PROD_4( RSL_ImBook_267_tbl, Book, int, RSL_key, RSL_string, title, > RSL_string, author, double, price); > > Which is macro. It defined as structure(see defenition of macros in > RSL_sql_prods.h file). The macro takes several argument: first one is the > name of class, the second is the RSLProduct3 type and others with pair the > type of column and the name of column. In short it holds the structure of > table. Type RSL_string corresponds to CHAR() sql type and other UDT > translated as TEXT type. In stage of translator it is difficult to know the > name of first field, so we decided it should be RSL_key for any tables. > > Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61.
> в общем это читать тяжеловато. я, мягко говоря, не допонял. но какие то аналогии со своего опыта могу сказать. я предпочел не писать такого рода макросы для версий таблиц от 1 до 30 полей, как я увидел у тебя в хедере, а написал генератор обьектов из определения таблицы. (в моем конструкторе используются на самом деле, как и у тебя , имена полей и их типы. что генерировать твой макрос, что генерировать мой конструктор - усилия одинаковые) суть работы генератора обьектов для С++ кода (я упрощаю) 1 я определил обьект (обозначим его) TSde, имеющий поля название таблицы, признак таблица или обзор (table view) и список структур (для хранения имени поля, типа и переменных для хранения значения и признака NULL). для такого обьекта можно определить фукнкции члены класса delete, insert, select, update; и функциями для использования списка. функции занимаются тем, что получив на вход фразы where и order by строят по имени таблицы, списку структур строят соответствующий оператор языка SQL и выполняют его. 2 для каждой конкретной структуры я строю не маркос а обьект, котроые наследует свойства обьекта SDE. к примеру C++ обьект сгенерированный под запись Book :: title : Text <-> re_title author : Text <-> re_author price : Real <-> re_price, будет выглядеть приблизительно таким образом ---------------------------------------------------------- Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
----------------------- конструктор будет представлять нечто такое ------------------------ Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
---------------------------------------------------- to be continued ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2003, 09:58 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
Abdugani ------ It is nice idea to have some relation with other tables. But have you tryed C++ translator? It seems automatic translator doesnot work if we use scheme with parameters. Moreover we cannot use C++ keywords in RSL specification(for example delete). ----- 1 транслятор из своего текста в c++ я не делал. я автоматически генерировал т с++-тексты по определению таблицы или обзора. 2 для с++ текста эта параметризация, на мой взгляд, не играет ни какой роли и может быть опущена. параметризацию надо использовать для генерации констрайнтов в sql скриптах (например для создания фразы Код: plaintext 1. 2. 3. 4.
) 3 совершенно нет ни какой нужды писать ключевое слово delete - можно его заменить на Delete или DELETE или даже del. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2003, 10:10 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
Alexei yes, It is difficult to understand. A bit complicated macros. It is produced by Perl script. I wrote script in Perl and using this script I got such macros. First times, when I was workin in rsl->sql I wrote a class like your's(which you described above) in C++. Then I wanted to change translator file(GENTLE file cpp.g). I collided with some difficulties. How to addapt this class in general case(for any specification).? I find that I have to change rahther more place in cpp.g file. So I decided to write macros. It is difficult to understand because it is produced by Perl script. Actually it is simple: #define CRT_ST_PROD_4(SQLPROD, RSLP, T1, ID1, T2, ID2, T3, ID3, T4, ID4) \ This macro takes 8-arguments. 1) SQLPROD - the name of struct; 2) RSLP - it is object of RSLProduct3<T2, T3, T4> class (in this case T2 = RSL_string, T3 = RSL_string, T4 = double); 3) T1, T2, T3, T4 - built in or UD C++ data type. They are converted in corresponding sql's field data type(see function convert in RSL_SQL.h file); 4) ID1, ID2, ID3, ID4 - the name of table column. There are several constructors. Don't pay attention all of them. I forgot to remove some of them(now I removed). 1) SQLPROD(int k): counter(4), tbl(#SQLPROD), prod_name(#RSLP), with_arg(false), exist_tbl(true)\ If we wanted to work with existing table translator uses this constructor. The function of this cons-r is to initialise boolean exist_tbl variable with true value.(In this case in RSL we have to define variable like this variable books : Books ) 2) SQLPROD(T1 id1, RSLP p, SQLPROD u) : tbl(#SQLPROD), prod_name(#RSLP), counter(4), ID1(id1)\ If we want to create new table with some initial value this constructor will be used by translator. The function of this constructor is to held values in some variables. (This constructor will be used by translator if it finds in RSL file such declaration: variable books : Books:=[1 +> mk_Book("SQL_RSL", "Li", 12.0), 2 +>mkBooks("C++", "Jhon"), 25.0] ) 3) SQLPROD(): counter(4), tbl(#SQLPROD), prod_name(#RSLP), with_arg(false), exist_tbl(false)\ This will be used when in RSL file translator finds such declarattion variable books:Books:=[] Functions rec_field() and rec_val() holds the table column's name and the value of some tuple. The former is used in creating table the later one is used for inserting or updating data. For concrete specification it is better to use class like yours. For automatic translator(in general case) to use macros is much more easier. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.04.2003, 17:53 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
2 Abdugany я одолел ())) еще кусок текста из твоего первого письма. в этом отрывке ты обьяснял как реализуется функция has_autor Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
вернуть первичные ключи всех записей, у которых имя автора совпадает с заданным параметром t и стоимость книги больше чем 20.5 отрывок письма Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51.
насколько я понял после выполнения этого запроса has_author ("blablabla") второй фактический параметр, передаваемый в RSL_compsql, есть функция-предикат RSL_Temp_0::RSL_Temp_1. таким образом выполняется запрос "SELECT * from Books" и для каждой записи происходит проверка выполняется ли предикат на этой записи. я прав? я понял существенную разницу в течении наших мыслей я в своем примере GSAU старался перенести выполнение всяческих запросов на SQL сервер. ты стараешься получить реализацию конвертора, поменьше вмешиваясь в существующий код. как программист, я согласен с твоим ходом мысли до определенных границ. )))))))) получить готовую реализацию побыстрее. ))))))))))) но для промышленной реализации такая версия имхо не годится. тут мне не нравится 3 момента. 1 проверка на выполнение предиката выполняется на клиенте. проще выполнить небольшую конвертацию условия author(books(bi)) = t /\ price(books(bi)) > 20.5 во фразу where author = 'blablabla' AND price > 20.5 и, вместо запроса "SELECT * from Books ", выполнить следующий запрос "SELECT * from Books where author = 'blablabla' AND price > 20.5" /* в твоей версии на таблицах с большим количеством строчек и запросами, возвращающими мало записей, сеть будет перегружена просто недопустимым образом */ 2 проход по таблице Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
содержит функции следующий, предыдущий, с заданным порядковым номером записи от начала таблицы, с заданным смещением вперед/назад от текущей записи это все позволяет рассматривать результат выполнения запроса не как множество, а как список. поэтому при возвращении именно множества, как это делается в функции- запросе has_author, теряется важная и полезная информация, которая изначально присутствует в возможностях доступа через EMBEDDED SQL, ODBC или какой то другой интерфейс. 3 создание множества ответа как нечто целое тоже, на мой взгляд, сомнительное занятие. надо отрисовать на экране первые 20 записей из таблицы, в которой миллионы записей? зачем читать все миллионы? ------------- я думаю, курсор получаемый от интерфейса субд, надо представлять (когда нибудь потом, в конце концов) как список со всеми возможными операциями на нем. а скажем пересечение (или обьединение) двух списков строить через передачу к sql-серверу соответствующего запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2003, 10:23 |
|
RFC:генерация скриптов баз данных и кода клиентского приложения +
|
|||
---|---|---|---|
#18+
Alexei >... ... я прав? Yes, Alexei, you are right. It works in this way. >тут мне не нравится 3 момента. >1 >проверка на выполнение предиката выполняется на клиенте. >проще выполнить небольшую конвертацию условия >author(books(bi)) = t /\ price(books(bi)) > 20.5 >во фразу where >author = 'blablabla' AND price > 20.5 >и, вместо запроса "SELECT * from Books ", >выполнить следующий запрос >"SELECT * from Books where author = 'blablabla' AND price > 20.5" >/* >в твоей версии >на таблицах с большим количеством строчек и запросами, возвращающими >мало записей, сеть будет перегружена просто недопустимым образом >*/ I don't like myself such automatic translator. It doesnot use power of sql. When I begun to work on translator I wanted to use a bit complicated predicates in server side. After discussing with Mr.Chris George I found it is very hard work or even impossible to produce correct sql statements in translation stage. With all your remarks and comments I am quite agree. I tested several examples wich has few datas in tables. It is ok and works. But I am afraid if there are a litle more datas in table it works very slowly. Now I am looking Gentle code and thinking about how automatically produce a bit complicated sql commands from source specification(from RSL). Anyway I am trying... ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2003, 16:10 |
|
|
start [/forum/topic.php?fid=32&msg=32135021&tid=1546989]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
62ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 251ms |
total: | 404ms |
0 / 0 |