powered by simpleCommunicator - 2.0.48     © 2025 Programmizd 02
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / RFC:генерация скриптов баз данных и кода клиентского приложения +
10 сообщений из 10, страница 1 из 1
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32132269
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
из языка формальных спецификаций RAISE Specification Language -RSL.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32132270
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ресурсы:
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
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32132271
abdugani
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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.
scheme S42 =

class

type

Book_id = Int,

Book ::                --  создание типа записи из трех полей
 
                                 -- функция 
 
title : Text <-> re_title  -- re_title -позволяет заменять старое значение на новое
 
                                 -- в записи
 
author : Text <-> re_author  -- то же самое
 

price : Real <-> re_price,

Books = Book_id -m-> Book   -- создание типа отображение(таблица) 
 
                                            -- первичного ключа в запись
 
                                            -- обьявление собственно таблицы
 
variable books : Books:=[ 5  +> mk_Book( "SQL_RSL" ,  "Li" ,  12 . 0 )]


value
                                           -- сигнатура (прототип) функции
 
                                           --
 
insert : Book_id >< Book -> write books Unit
                                           -- функция вставки записи в таблицу
 
insert(bi, b) is books := books !! [bi +> b]
                                           -- !! операция оверрайд
 

pre bi ~isin dom books,         -- функция должна вызываться если
 
                                           -- bi не входит во множество
 
                                           -- определения отображения
 
                                           -- то есть не входит в первичный ключ   
 


update : Book_id >< Book -> write books Unit

update(bi, b) is books := books !! [bi +> b]

pre bi isin dom books,

has_author : Text -> read books Book_id-set

has_author(t) is                     --
 
                                           --    select id from books where author = :t  
 
{bi |                                      --         and price > 20.5
 

bi : Book_id :-

bi isin books /\ author(books(bi)) = t /\

price(books(bi)) >  20 . 5 },


ttlbooks : Text -> read books Text-set

ttlbooks(t) is

{title(b) |

b : Book :-

b isin rng books /\ author(b) = t},

titleAndPrice : Text -> read books (Text >< Real)-set

titleAndPrice(t) is

{(title(b), price(b)) | b : Book :-

b isin rng books /\ author(b) = t },

remove2 : Text -> write books Unit

remove2(ti) is

books :=

books \

{id |

id : Book_id :-

id isin books /\ title(books(id)) ~= ti}




test_case


insert( 1 , mk_Book( "SQL" ,  "Li" ,  12 . 0 )),

insert( 2 , mk_Book( "RSL" ,  "Li" ,  50 . 5 )),

insert( 3 , mk_Book( "The C++ prog.lang" ,  "Ann" ,  25 . 49 )),

books,

has_author( "Li" ),

ttlbooks( "Ann" ),

titleAndPrice( "Li" ),

[t5] hd(books)

remove2( "SQL" )

end



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.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32132273
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>
> 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,
при помощи которой и создавал обьекты - аналоги таблиц.
тогда вопрос с большим количеством таблиц становится не принципиальным.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32133364
abdugani
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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).
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32134073
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
 > #define CRT_ST_PROD_4(SQLPROD, RSLP, T1, ID1, T2, ID2, T3, ID3, T4, ID4) \
 >     struct SQLPROD{\
 >       int counter;\
 >       T1 ID1;\
 >       T2 ID2;\
 >       T3 ID3;\
 >       T4 ID4;\
 >       string tbl; string prod_name; string key; bool exist_tbl;\
 >       string product; string holder; bool without_init;bool with_arg;\
 >       vector<string> vs;\
 >       vector<string> vst;\
 >       SQLPROD(): counter( 4 ), tbl(#SQLPROD), prod_name(#RSLP), with_arg(false), exist_tbl(false)\
 >       {vs.push_back(#ID1); vs.push_back(#ID2); vs.push_back(#ID3); vs.push_back(#ID4); \
 >       vst.push_back(#T1); vst.push_back(#T2); vst.push_back(#T3); vst.push_back(#T4); }\
 > 
 > 
 >       SQLPROD(int k): counter( 4 ), tbl(#SQLPROD), prod_name(#RSLP), with_arg(false), exist_tbl(true)\
 >       {vs.push_back(#ID1); vs.push_back(#ID2); vs.push_back(#ID3); vs.push_back(#ID4); \
 >       vst.push_back(#T1); vst.push_back(#T2); vst.push_back(#T3); vst.push_back(#T4); }\
 > 
 >       SQLPROD(T1 id1, T2 id2, T3 id3, T4 id4) : counter( 4 ), tbl(#SQLPROD), prod_name(#RSLP),exist_tbl(false), \
 >       ID1(id1), ID2(id2), ID3(id3), ID4(id4) {vs.push_back(#ID1); vs.push_back(#ID2); vs.push_back(#ID3); vs.push_back(#ID4); \
 >       vst.push_back(#T1); vst.push_back(#T2); vst.push_back(#T3); vst.push_back(#T4); }\
 > 
 >       SQLPROD(T1 id1, RSLP p) : tbl(#SQLPROD), prod_name(#RSLP),  counter( 4 ), ID1(id1)\
 >       , ID2(p.RSL_f1), ID3(p.RSL_f2), ID4(p.RSL_f3) , without_init(false), exist_tbl(false)\
 >       {product=RSL_to_string(p);\
 >       vs.push_back(#ID1); vs.push_back(#ID2); vs.push_back(#ID3); vs.push_back(#ID4); \
 >       vst.push_back(#T1); vst.push_back(#T2); vst.push_back(#T3); vst.push_back(#T4); }\
 >       SQLPROD(T1 id1, RSLP p, SQLPROD u) : tbl(#SQLPROD),  prod_name(#RSLP), counter( 4 ), ID1(id1)\
 >       , ID2(p.RSL_f1), ID3(p.RSL_f2), ID4(p.RSL_f3) , without_init(false), with_arg(true), exist_tbl(false) \
 >       {product=RSL_to_string(p); key=cnvrt2string(ID1);\
 >       vs.push_back(#ID1); vs.push_back(#ID2); vs.push_back(#ID3); vs.push_back(#ID4); \
 >       vst.push_back(#T1); vst.push_back(#T2); vst.push_back(#T3); vst.push_back(#T4); \
 >       if (u.with_arg) holder = ',' + u.rec_val() + u.holder;\
 >       }\
 >        string rec_val(){\
 >          string s= "(" ;\
 >          s=s+ cnvrt2string(ID1); s+= ", " ;\
 >          s=s+ cnvrt2string(ID2); s+= ", " ;\
 >          s=s+ cnvrt2string(ID3); s+= ", " ;\
 >          s=s + cnvrt2string(ID4); s+= ")" ;\
 >          return s;}\
 >        string rec_field(){\
 >          string s= "(" ;\
 >          s=s+vs[ 0 ] +  ", " ;\
 >          s=s+vs[ 1 ] +  ", " ;\
 >          s=s+vs[ 2 ] +  ", " ;\
 >      s=s + vs[ 3 ] +  ")" ;\
 >      return s;}\
 > SQLPROD operator+(SQLPROD rhs){\
 >  if(rhs.with_arg==false){\
 > (*this).without_init=false; (*this).with_arg=false;\
 >  return *this;}\
 >  if(with_arg==false){\
 > rhs.without_init=false; rhs.with_arg=false;\
 >  return rhs;}\
 >  (*this).holder= holder+  ","  + rhs.rec_val() +  rhs.holder;\
 > (*this).without_init=false; (*this).with_arg=true;\
 > return *this;}\
 > };

>
в общем это читать тяжеловато.
я, мягко говоря, не допонял.
но какие то аналогии со своего опыта могу сказать.
я предпочел не писать такого рода макросы для версий таблиц от
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.
// Table/View to SDE - convertor is here: func/struct = true;tbl=Book;prf=

struct _RBook : ASAI_TSde{              // _RBook наследуется от обьекта ASAI_TSde
    TStr    title;                      // эти структуры будут учавствовать
    TStr    author;                     // для создания списка  структур
    TDouble price;                      //
 private:
    x_bool    isGood;
 public: 
    friend _API _RBook * WINAPI _iniBook( _RBook * r)
    ;
    _RBook           (                   // конструктор
        void * sqlca =  0                  //
                                         //
    ) : ASAI_TSde( "Book" ,                // название таблицы
                   (ASAI_TDB*)sqlca,     // область для   EMBEDDED SQL
                    true,                // признак таблицы
                      "",                 // создатель таблицы
                     " id")               // поле первичного ключа
    { if (_iniBook(this))
            isGood=true;
        else
            isGood=false;
    }
    friend _API void WINAPI _deiniBook( _RBook * r)
    ;
    ~_RBook          () { _deiniBook (this);}
    x_bool isWellFormed      () { return isGood;}
};

// Table/View to SDE - convertor: eof

-----------------------
конструктор будет представлять нечто такое

------------------------
Код: 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.
// Table/View to SDE - convertor is here: func/struct = false;tbl=Book;prf=
_API _RBook * WINAPI _iniBook( _RBook * r)
{
const char * _me =  "iniBook" ;
r->title.vSz  =  32 ;
r->aithor.vSz =  16 ;

if(r->push(                              // засунуть в список новое поле
              new ASAI_TField(           //
                     "title" ,             // с именем title
                     ASAI_T_TStr,        //   типа строчка
                     (void*) &(r->title))//   и область памяти
                                         //   для получения/вставки
   ) != _OK                              //   значений из/в БД
)
            goto err;



r->tank2.setNull( 0 );
if(r->push( new ASAI_TField( "author" , ASAI_T_TStr, 
                                               (void*) &(r->author))) != _OK
)
            goto err;
r->tank1.setNull( 0 );
if(r->push( new ASAI_TField( "price" , ASAI_T_TDouble, 
                                               (void*) &(r->price))) != _OK
)
            goto err;
r->pump.setNull( 0 );
        return r;
    err:
return  0 ;
}

----------------------------------------------------


to be continued
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32134075
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
alter table Position
  add  constraint pos_pmp_fk 
  foreign key (pump) references Pump(id)
  ON DELETE CASCADE;

)


3
совершенно нет ни какой нужды писать ключевое слово
delete - можно его заменить на Delete или DELETE или даже del.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32135021
abdugani
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32144639
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Abdugany

я одолел ())) еще кусок текста из твоего первого письма.
в этом отрывке ты обьяснял как реализуется функция
has_autor

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
has_author : Text -> read books Book_id-set

has_author(t) is

{bi |

bi : Book_id :-

bi isin books /\ author(books(bi)) = t /\

price(books(bi)) >  20 . 5 },


вернуть первичные ключи всех записей, у которых имя автора
совпадает с заданным параметром 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.
it becomes in S42.cc as follows:

RSL_sI has_author(const RSL_string& t_A3A){

RSL_Temp_0::t_A3A = t_A3A;

RSL_sI RSL_Temp_2 = RSL_compsql<
                      int,
                      int,
                      Book,
                      RSL_ImBook_267_tbl
                     >(
                       (RSL_IfI)RSL_identity,
                        RSL_Temp_0::RSL_Temp_1,
                        books
                     );

Return RSL_Temp_2;

}

(see definition of RSL_compsql function).

 ------ отрывок файла RSL_sql.h -----------
 

template<typename A, typename B, typename R, typename ST>
RSLSet<B> RSL_compsql(
              B (*g)(const A &),
              bool (*p)(const A &),
              RSL_SQL<A, R, ST> &rslsql
  ){
  RSLDBResult *rs;
  RSLSet<B> r=RSLSet<B>();
  A a;
  rs=rslsql.exec( "SELECT * FROM %s" , rslsql.table.c_str());
  for(int i= 0 ; i<rs->nrTuples(); i++){
    rs->seekTuple(i);
    a=string_to_RSL<A>(rs->currentrow[ 0 ]);
    if ((*p)(a)){ 
      r=RSLSet<B>((*g)(a), r);
    }
  }
  delete rs; 
  return r;
}

 -----------------------------------------------------
 





насколько я понял после выполнения этого запроса 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.
  for(int i= 0 ; i<rs->nrTuples(); i++){
    rs->seekTuple(i);
    a=string_to_RSL<A>(rs->currentrow[ 0 ]);
    if ((*p)(a)){ 
      r=RSLSet<B>((*g)(a), r);
    }
  }



содержит функции следующий, предыдущий,
с заданным порядковым номером записи от начала таблицы,
с заданным смещением вперед/назад от текущей записи

это все позволяет рассматривать результат выполнения запроса не
как множество, а как список.
поэтому при возвращении именно множества, как это делается в
функции- запросе has_author, теряется важная и полезная информация,
которая изначально присутствует в возможностях доступа через
EMBEDDED SQL, ODBC или какой то другой интерфейс.


3
создание множества ответа как нечто целое
тоже, на мой взгляд, сомнительное занятие.
надо отрисовать на экране первые 20 записей из таблицы,
в которой миллионы записей? зачем читать все миллионы?

-------------
я думаю, курсор получаемый от интерфейса субд,
надо представлять (когда нибудь потом, в конце концов) как список
со всеми возможными операциями на нем.
а скажем пересечение (или обьединение) двух списков
строить через передачу к sql-серверу соответствующего запроса.
...
Рейтинг: 0 / 0
RFC:генерация скриптов баз данных и кода клиентского приложения +
    #32150280
abdugani
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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...
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / RFC:генерация скриптов баз данных и кода клиентского приложения +
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]