powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Кто все эти люди ?
25 сообщений из 25, страница 1 из 1
Кто все эти люди ?
    #39429443
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Частенько захожу на гитхаб и вижу у людей проекты на C++, Scala, TypeScript, JavaScript и далее. Как они всё это совмещают ? Какую голову нужно иметь ? Тут в яве одной с её фреймворками можно заковыряться на годы, а люди кучу языков используют. У меня было так C# -> плюсы + питон -> C# + C++ - >C# -> Java + JavaScript. Причём плюсы я практически забыл, за шарпом не слежу, в яве столько всего что на что-то ещё просто времени нет ковыряться.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429458
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всякие люди бывают, есть акыны: что вижу - то пою. Поизучал одно чуть-чуть - залил, второе - залил. Вершков насобирал, вроде всего много, а серьезно ни в чем не разбирается.

Если какой-то крупный проект, то там много народу трудится: кроме разработчиков - тестировщики, писатели документации и т.д. и т.п.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429463
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch,

На основной работе одним человеком обычно используется один конкретный стек технологий. С течением времени могут меняться работа или проекты со сменой этого стека. Это долгий процесс. Что не мешает читать о новых технологиях и языках, ковыряться в исходниках опен сорса, скачивать проекты с гитхаба, запускать их, использовать наработки в текущей работе, внедрять новые технологии по ходу дела, писать демо-проекты для себя, обсуждать и спорить с коллегами, пилить очередной велосипед... У многих людей программирование и разработка это также и хобби, что позволяет получать не только зарплату, но и искреннее удовольствие от работы, получая бонусом непрерывный профессиональный рост.

На деле же, людей с глубоким знанием большого количества языков и платформ не существует. Многим хватает хелоу ворлда, чтобы с уверенностью записать новый язык в список своих абилок.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429464
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch,

Почему с шарпа ушёл на яву? Обстоятельства или личная инициатива?
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429471
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttponuch,

Почему с шарпа ушёл на яву? Обстоятельства или личная инициатива?

Личная. ряд причин: окончательно перешёл на линукс, в яве я чувствую себя более комфортно. сейчас ухожу в безумный мир стартапов, видимо придётся плюсы вспоминать :)
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429473
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchЛичная. ряд причин: окончательно перешёл на линукс, в яве я чувствую себя более комфортно. сейчас ухожу в безумный мир стартапов, видимо придётся плюсы вспоминать :)

Ясно, спасибо за ответ
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429491
scf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch,

Заинтересовало, т.к. стек именно мой)
- C++ - я с него начинал, куча старых проектов осталась, иногда пописываю
- Scala - перешел на нее с Java, использую по работе. Оба языка нужны для разработки
- JS - в наше время просто необходимо знать, т.к. будущее у домашних проектов, в основном, находится в вебе
- TypeScript - так сказать, расширение JS, без которого тяжко.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429583
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch,

здравствуйте, это я
правда проектов на гитхабе нет
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429633
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch, хотя бы один тынц дайте, хочется посмотреть на "и далее"
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429720
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAponuch, хотя бы один тынц дайте, хочется посмотреть на "и далее"

парадокс (шото напоминающее операцию like)


Код: 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.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
proc isSpace1(char)
private x
x = substr(char,1,1)
if(x = " " or x = "\t"  ) then
       return true
endif
return false
endproc

proc countErrs(s1, s2)
private   a1, a2, a1L, a2L, a1P, a2P,  ; array, array length, array pointer
          errs, mmatch,
          MODUL,x
MODUL = 100                   ;     1283  - 83 mmatch
                              ;     12      errors
                              ;
 deSpace( s1, s2)      a1P = 1     a2P = 1
;? "-------------------"
calls=0
x = countMatch(0,0)

errs  = int(x / MODUL)
mmatch = x - int(x / MODUL) * MODUL
;? "mmatch = ", mmatch," calls = ", calls
return errs
endproc

proc countMatch(mmatch, errs)
calls= calls+1
while(a1P <= a1L and a2P <= a2L )
   if( a1[a1P]  <>  a2[a2P] ) then
           return searchMatch (mmatch,errs)
   endif
   a1P = a1P + 1
   a2P = a2P + 1
   mmatch = mmatch + 1
endwhile

errs = errs + max(0, max ( a1L+1 - a1P, a2L+1 - a2P))
return errs * MODUL + mmatch
endproc



proc searchMatch(mmatch, errs)
private err,      x,y,m,e, structP
structP = 0
err = 1
   WHILE a1P + err <= a1L or a2P + err <= a2L
                            ; поиск возможных продолжений
                            ; по каждому продолжению
                            ; записывается структура <a1P, a2P, mmatch, errs>
                            ; для оценки выбора продолжения
       array x[2*err]
       array y[2*err]
       array m[2*err]
       array e[2*err]
       structP = searchSequel(err)
       if(structP > 0) then
            quitloop
       endif
       err = err + 1
   endWHILE
   errs = errs + err
   if(structP > 0) then
         return weightSequel(mmatch, errs, structP)
   endif
return (errs * MODUL) + mmatch
endproc

proc saveStruct(p, i1, i2)
p = p + 1
if(p <= 2*err) then
      x[p]  = i1
      y[p]  = i2
      m[p]  = 0
      e[p]  = 0
      return 1
endif
return 0
endproc

proc   searchSequel(err)   ;  доступ к структуре в вызвавшей программе
private rc, i1, i2
rc = 0
i1 = a1P
i2 = a2P
while( (i1 < a1P + err) OR (i2 < a2P + err))
      if((i2 <= a2L) and (a1P + err <= a1L)) then
           if( a2[i2] = a1[a1P + err] ) then
               rc = rc + saveStruct(rc, a1P + err, i2)
           endif
      endif
      if((i1 <= a1L) and (a2P + err <= a2L)) then
           if( a1[i1] = a2[a2P + err] ) then
               rc = rc + saveStruct(rc, i1, a2P + err)
           endif
      endif
      i1 = i1 + 1
      i2 = i2 + 1
endwhile
if(i1 <= a1L and i2 <= a2L) then
     if( a1[i1] = a2[i2] ) then
         rc = rc + saveStruct(rc, i1, i2)
     endif
endif
return rc
endproc


proc   weightSequel(mmatch, errs, sP)
private p, errsMatch , minEr, maxMa , er, ma, i1, i2, ppp
errsMatch = 0
minEr =  32000
maxMa = -32000
  for p from 1 to sP
      er = errs
      a1P = x[p]
      a2P = y[p]
      errsMatch = countMatch (mmatch, errs)
      m[p] =  errsMatch - int(errsMatch / MODUL) * MODUL
      e[p] =  int(errsMatch / MODUL)
      if (m[p] > maxMa) then
            ppp   = p
            minEr = e[p]
            maxMa = m[p]
      else if (m[p] = maxMa and e[p] < minEr) then
            ppp   = p
            minEr = e[p]
            maxMa = m[p]
      endif
      endif
  endfor
errsMatch = minEr * MODUL + maxMa
return errsMatch
endproc

proc deSpace( string1, string2)
private i,j, prevChar, char
prevChar = 0;
i = 0;
j = 0

;string1 = ltrim(rtrim(string1))
a1L = len(string1)
array a1[a1L]


for i from 1 to a1L
     char = substr(string1, i, 1)
     if((not isSpace1(char)) or (not isSpace1(prevChar))) then
          j = j + 1
          a1[j] = char
          prevChar = char
     endif
endfor
a1L = j
prevChar = 0;
i = 0;
j = 0

;string2 = ltrim(rtrim(string2))
a2L = len(string2)
array a2[a2L]

for i from 1 to a2L
     char = substr(string2, i, 1)
     if((not isSpace1(char)) or (not isSpace1(prevChar))) then
          j = j + 1
          a2[j] = char
          prevChar = char
     endif
endfor
a2L = j
endproc

proc printArray(arr, arrL)
private i
@ 2,2
?? "--> "
for i from 1 to arrL
        execute "?? "+arr+"["+strval(i)+"]"
endfor
?? " <--"
endproc




rsl


Код: 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.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
1114.
1115.
1116.
1117.
1118.
1119.
1120.
1121.
1122.
1123.
1124.
1125.
1126.
1127.
1128.
1129.
1130.
1131.
1132.
1133.
1134.
1135.
1136.
1137.
1138.
1139.
1140.
1141.
1142.
1143.
1144.
1145.
1146.
1147.
1148.
1149.
1150.
1151.
1152.
1153.
1154.
1155.
1156.
1157.
1158.
1159.
1160.
1161.
1162.
1163.
1164.
1165.
1166.
1167.
1168.
1169.
1170.
1171.
1172.
1173.
1174.
1175.
1176.
1177.
1178.
1179.
1180.
1181.
1182.
1183.
1184.
1185.
1186.
1187.
1188.
1189.
1190.
1191.
1192.
1193.
1194.
1195.
1196.
1197.
1198.
1199.
1200.
1201.
1202.
1203.
1204.
1205.
1206.
1207.
1208.
1209.
1210.
1211.
1212.
1213.
1214.
1215.
1216.
1217.
1218.
1219.
1220.
1221.
1222.
1223.
1224.
1225.
1226.
1227.
1228.
1229.
1230.
1231.
1232.
1233.
1234.
1235.
1236.
1237.
1238.
1239.
1240.
1241.
1242.
1243.
1244.
1245.
1246.
1247.
1248.
1249.
1250.
1251.
1252.
1253.
1254.
1255.
1256.
1257.
1258.
1259.
1260.
1261.
1262.
1263.
1264.
1265.
1266.
1267.
1268.
1269.
1270.
1271.
1272.
1273.
1274.
1275.
1276.
1277.
1278.
1279.
1280.
1281.
1282.
1283.
1284.
1285.
1286.
1287.
1288.
1289.
1290.
1291.
1292.
1293.
1294.
1295.
1296.
1297.
1298.
1299.
1300.
1301.
1302.
1303.
1304.
1305.
1306.
1307.
1308.
1309.
1310.
1311.
1312.
1313.
1314.
1315.
1316.
1317.
1318.
1319.
1320.
1321.
1322.
1323.
1324.
1325.
1326.
1327.
1328.
1329.
1330.
1331.
1332.
1333.
1334.
1335.
1336.
1337.
1338.
1339.
1340.
1341.
1342.
1343.
1344.
1345.
1346.
1347.
1348.
1349.
1350.
1351.
1352.
1353.
1354.
1355.
1356.
1357.
1358.
1359.
1360.
1361.
1362.
1363.
1364.
1365.
1366.
1367.
1368.
1369.
1370.
1371.
1372.
1373.
1374.
1375.
1376.
1377.
1378.
1379.
1380.
1381.
1382.
1383.
1384.
1385.
1386.
1387.
1388.
1389.
1390.
1391.
1392.
1393.
1394.
1395.
1396.
1397.
1398.
1399.
1400.
1401.
1402.
1403.
1404.
1405.
1406.
1407.
1408.
1409.
1410.
1411.
1412.
1413.
1414.
1415.
1416.
1417.
1418.
1419.
1420.
1421.
1422.
1423.
1424.
1425.
1426.
1427.
1428.
1429.
1430.
1431.
1432.
1433.
1434.
1435.
1436.
1437.
1438.
1439.
1440.
1441.
1442.
1443.
1444.
1445.
1446.
1447.
1448.
1449.
1450.
1451.
1452.
1453.
1454.
1455.
1456.
1457.
1458.
1459.
1460.
1461.
1462.
1463.
1464.
1465.
1466.
1467.
1468.
1469.
1470.
1471.
1472.
1473.
1474.
1475.
1476.
1477.
1478.
1479.
1480.
1481.
1482.
1483.
1484.
1485.
1486.
1487.
1488.
1489.
1490.
1491.
1492.
1493.
1494.
1495.
1496.
1497.
1498.
1499.
1500.
1501.
1502.
1503.
1504.
1505.
1506.
1507.
1508.
1509.
1510.
1511.
1512.
1513.
1514.
1515.
1516.
1517.
1518.
1519.
1520.
1521.
1522.
1523.
1524.
1525.
1526.
1527.
1528.
1529.
1530.
1531.
1532.
1533.
1534.
1535.
1536.
1537.
1538.
1539.
1540.
1541.
1542.
1543.
1544.
1545.
1546.
1547.
1548.
1549.
1550.
1551.
1552.
1553.
1554.
1555.
1556.
1557.
1558.
1559.
1560.
1561.
1562.
1563.
1564.
1565.
1566.
1567.
1568.
1569.
1570.
1571.
1572.
1573.
1574.
1575.
1576.
1577.
1578.
1579.
1580.
1581.
1582.
1583.
1584.
1585.
1586.
1587.
1588.
1589.
1590.
1591.
1592.
1593.
1594.
1595.
1596.
1597.
1598.
1599.
1600.
1601.
1602.
1603.
1604.
1605.
1606.
1607.
1608.
1609.
1610.
1611.
1612.
1613.
1614.
1615.
1616.
1617.
1618.
1619.
1620.
1621.
1622.
1623.
1624.
1625.
1626.
1627.
1628.
1629.
1630.
1631.
1632.
1633.
1634.
1635.
1636.
1637.
1638.
1639.
1640.
1641.
1642.
1643.
1644.
1645.
1646.
1647.
1648.
1649.
1650.
1651.
1652.
1653.
1654.
1655.
1656.
1657.
1658.
1659.
1660.
1661.
1662.
1663.
1664.
1665.
1666.
1667.
1668.
1669.
1670.
1671.
1672.
1673.
1674.
1675.
1676.
1677.
1678.
1679.
1680.
1681.
1682.
1683.
1684.
1685.
1686.
1687.
1688.
1689.
1690.
1691.
1692.
1693.
1694.
1695.
1696.
1697.
1698.
1699.
1700.
1701.
1702.
1703.
1704.
1705.
1706.
1707.
1708.
1709.
1710.
1711.
1712.
1713.
1714.
1715.
1716.
1717.
1718.
1719.
1720.
1721.
1722.
1723.
1724.
1725.
1726.
1727.
1728.
1729.
1730.
1731.
1732.
1733.
1734.
1735.
1736.
1737.
1738.
1739.
1740.
1741.
1742.
1743.
1744.
1745.
1746.
1747.
1748.
1749.
1750.
1751.
1752.
1753.
1754.
1755.
1756.
1757.
1758.
1759.
1760.
1761.
1762.
1763.
1764.
1765.
1766.
1767.
1768.
1769.
1770.
1771.
1772.
1773.
1774.
1775.
1776.
1777.
1778.
1779.
1780.
1781.
1782.
1783.
1784.
1785.
1786.
1787.
1788.
1789.
1790.
1791.
1792.
1793.
1794.
1795.
1796.
1797.
1798.
1799.
1800.
1801.
1802.
1803.
1804.
1805.
1806.
1807.
1808.
1809.
1810.
1811.
1812.
1813.
1814.
1815.
1816.
1817.
1818.
1819.
1820.
1821.
1822.
1823.
1824.
1825.
1826.
1827.
1828.
1829.
1830.
1831.
1832.
1833.
1834.
1835.
1836.
1837.
1838.
1839.
1840.
1841.
1842.
1843.
1844.
1845.
1846.
1847.
1848.
1849.
1850.
1851.
1852.
1853.
1854.
1855.
1856.
1857.
1858.
1859.
1860.
1861.
1862.
1863.
1864.
1865.
1866.
1867.
1868.
1869.
1870.
1871.
1872.
1873.
1874.
1875.
1876.
1877.
1878.
1879.
1880.
1881.
1882.
1883.
1884.
1885.
1886.
1887.
1888.
1889.
1890.
1891.
1892.
1893.
1894.
1895.
1896.
1897.
1898.
1899.
1900.
1901.
1902.
1903.
1904.
1905.
1906.
1907.
1908.
1909.
1910.
1911.
1912.
1913.
1914.
1915.
1916.
1917.
1918.
1919.
1920.
1921.
1922.
1923.
1924.
1925.
1926.
1927.
1928.
1929.
1930.
1931.
1932.
1933.
1934.
1935.
1936.
1937.
1938.
1939.
1940.
1941.
1942.
1943.
1944.
1945.
1946.
1947.
1948.
1949.
1950.
1951.
1952.
1953.
1954.
1955.
1956.
1957.
1958.
1959.
1960.
1961.
1962.
1963.
1964.
1965.
1966.
1967.
1968.
1969.
1970.
1971.
1972.
1973.
1974.
1975.
1976.
1977.
1978.
1979.
1980.
1981.
1982.
1983.
1984.
1985.
1986.
1987.
1988.
1989.
1990.
1991.
1992.
1993.
1994.
1995.
1996.
1997.
1998.
1999.
2000.
2001.
2002.
2003.
2004.
2005.
2006.
2007.
2008.
2009.
2010.
2011.
2012.
2013.
2014.
2015.
2016.
2017.
2018.
2019.
2020.
2021.
2022.
2023.
2024.
2025.
2026.
2027.
2028.
2029.
2030.
2031.
2032.
2033.
2034.
2035.
2036.
2037.
2038.
2039.
2040.
2041.
2042.
2043.
2044.
2045.
2046.
2047.
2048.
2049.
2050.
2051.
2052.
2053.
2054.
2055.
2056.
2057.
2058.
2059.
2060.
2061.
2062.
2063.
2064.
2065.
2066.
2067.
2068.
2069.
2070.
2071.
2072.
2073.
2074.
2075.
2076.
2077.
2078.
2079.
2080.
2081.
2082.
2083.
2084.
2085.
2086.
2087.
2088.
2089.
2090.
2091.
2092.
2093.
2094.
2095.
2096.
2097.
2098.
2099.
2100.
2101.
2102.
2103.
2104.
2105.
2106.
2107.
2108.
2109.
2110.
2111.
2112.
2113.
2114.
2115.
2116.
2117.
2118.
2119.
2120.
2121.
2122.
2123.
2124.
2125.
2126.
2127.
2128.
2129.
2130.
2131.
2132.
2133.
2134.
2135.
2136.
2137.
2138.
2139.
2140.
2141.
2142.
2143.
2144.
2145.
2146.
2147.
2148.
2149.
2150.
2151.
2152.
2153.
2154.
2155.
2156.
2157.
2158.
2159.
2160.
2161.
2162.
2163.
2164.
2165.
2166.
2167.
2168.
2169.
2170.
2171.
2172.
2173.
2174.
2175.
2176.
2177.
2178.
2179.
2180.
2181.
2182.
2183.
2184.
2185.
2186.
2187.
2188.
2189.
2190.
2191.
2192.
2193.
2194.
2195.
2196.
2197.
2198.
2199.
2200.
2201.
2202.
2203.
2204.
2205.
2206.
2207.
2208.
2209.
2210.
2211.
2212.
2213.
2214.
2215.
2216.
2217.
2218.
2219.
2220.
2221.
2222.
2223.
2224.
2225.
2226.
2227.
2228.
2229.
2230.
2231.
2232.
2233.
2234.
2235.
2236.
2237.
2238.
2239.
2240.
2241.
2242.
2243.
2244.
2245.
2246.
2247.
2248.
2249.
2250.
2251.
2252.
2253.
2254.
2255.
2256.
2257.
2258.
2259.
2260.
2261.
2262.
2263.
2264.
2265.
2266.
2267.
2268.
2269.
2270.
2271.
2272.
2273.
2274.
2275.
2276.
2277.
2278.
2279.
2280.
2281.
2282.
2283.
2284.
2285.
2286.
2287.
2288.
2289.
2290.
2291.
2292.
2293.
2294.
2295.
2296.
2297.
2298.
2299.
2300.
2301.
2302.
2303.
2304.
2305.
2306.
2307.
2308.
2309.
2310.
2311.
2312.
2313.
2314.
2315.
2316.
2317.
2318.
2319.
2320.
2321.
2322.
2323.
2324.
2325.
2326.
2327.
2328.
2329.
2330.
2331.
2332.
2333.
2334.
2335.
2336.
2337.
2338.
2339.
2340.
2341.
2342.
2343.
2344.
2345.
2346.
2347.
2348.
2349.
2350.
2351.
2352.
2353.
2354.
2355.
2356.
2357.
2358.
2359.
2360.
2361.
2362.
2363.
2364.
2365.
2366.
2367.
2368.
2369.
2370.
2371.
2372.
2373.
2374.
2375.
2376.
2377.
2378.
2379.
2380.
2381.
2382.
2383.
2384.
2385.
2386.
2387.
2388.
2389.
2390.
2391.
2392.
2393.
2394.
2395.
2396.
2397.
2398.
2399.
2400.
2401.
2402.
2403.
2404.
2405.
2406.
2407.
2408.
2409.
2410.
2411.
2412.
2413.
2414.
2415.
2416.
2417.
2418.
2419.
2420.
2421.
2422.
2423.
2424.
2425.
2426.
2427.
2428.
2429.
2430.
2431.
2432.
2433.
2434.
2435.
2436.
2437.
2438.
2439.
2440.
2441.
2442.
2443.
2444.
2445.
2446.
2447.
2448.
2449.
2450.
2451.
2452.
2453.
2454.
2455.
2456.
2457.
2458.
2459.
2460.
2461.
2462.
2463.
2464.
2465.
2466.
2467.
2468.
2469.
2470.
2471.
2472.
2473.
2474.
2475.
2476.
2477.
2478.
2479.
2480.
2481.
2482.
2483.
2484.
2485.
2486.
2487.
2488.
2489.
2490.
2491.
2492.
2493.
2494.
2495.
2496.
2497.
2498.
2499.
2500.
2501.
2502.
2503.
2504.
2505.
2506.
2507.
2508.
2509.
2510.
2511.
2512.
2513.
2514.
2515.
2516.
2517.
2518.
2519.
2520.
2521.
2522.
2523.
2524.
2525.
2526.
2527.
2528.
2529.
2530.
2531.
2532.
2533.
2534.
2535.
2536.
2537.
2538.
2539.
2540.
2541.
2542.
2543.
2544.
2545.
2546.
2547.
2548.
2549.
2550.
2551.
2552.
2553.
2554.
2555.
2556.
2557.
2558.
2559.
2560.
2561.
2562.
2563.
2564.
2565.
2566.
2567.
2568.
2569.
2570.
2571.
2572.
2573.
2574.
2575.
2576.
2577.
2578.
2579.
2580.
2581.
2582.
2583.
2584.
2585.
2586.
2587.
2588.
2589.
2590.
2591.
2592.
2593.
2594.
2595.
2596.
2597.
2598.
2599.
2600.
2601.
2602.
2603.
2604.
2605.
2606.
2607.
2608.
2609.
2610.
2611.
2612.
2613.
2614.
2615.
2616.
2617.
2618.
2619.
2620.
2621.
2622.
2623.
2624.
2625.
2626.
2627.
2628.
2629.
2630.
2631.
2632.
2633.
2634.
2635.
2636.
2637.
2638.
2639.
2640.
2641.
2642.
2643.
2644.
2645.
2646.
2647.
2648.
2649.
2650.
2651.
2652.
2653.
2654.
2655.
2656.
2657.
2658.
2659.
2660.
2661.
2662.
2663.
2664.
2665.
2666.
2667.
2668.
2669.
2670.
2671.
2672.
2673.
2674.
2675.
2676.
2677.
2678.
2679.
2680.
2681.
2682.
2683.
2684.
2685.
2686.
2687.
2688.
2689.
2690.
2691.
2692.
2693.
2694.
2695.
2696.
2697.
2698.
2699.
2700.
2701.
2702.
2703.
2704.
2705.
2706.
2707.
2708.
2709.
2710.
2711.
2712.
2713.
2714.
2715.
2716.
2717.
2718.
2719.
2720.
2721.
2722.
2723.
2724.
2725.
2726.
2727.
2728.
2729.
2730.
2731.
2732.
2733.
2734.
2735.
2736.
2737.
2738.
2739.
2740.
2741.
2742.
2743.
2744.
2745.
2746.
2747.
2748.
2749.
2750.
2751.
2752.
2753.
2754.
2755.
2756.
2757.
2758.
2759.
2760.
2761.
2762.
2763.
2764.
2765.
2766.
2767.
2768.
2769.
2770.
2771.
2772.
2773.
2774.
2775.
2776.
2777.
2778.
2779.
2780.
2781.
2782.
2783.
2784.
2785.
2786.
2787.
2788.
2789.
2790.
2791.
2792.
2793.
2794.
2795.
2796.
2797.
2798.
2799.
2800.
2801.
2802.
2803.
2804.
2805.
2806.
2807.
2808.
2809.
2810.
2811.
2812.
2813.
2814.
2815.
2816.
2817.
2818.
2819.
2820.
2821.
2822.
2823.
2824.
2825.
2826.
2827.
2828.
2829.
2830.
2831.
2832.
2833.
2834.
2835.
2836.
2837.
2838.
2839.
2840.
2841.
2842.
2843.
2844.
2845.
2846.
2847.
2848.
2849.
2850.
2851.
2852.
2853.
2854.
2855.
2856.
2857.
2858.
2859.
2860.
2861.
2862.
2863.
2864.
2865.
2866.
2867.
2868.
2869.
2870.
2871.
2872.
2873.
2874.
2875.
2876.
2877.
2878.
2879.
2880.
2881.
2882.
2883.
2884.
2885.
2886.
2887.
2888.
2889.
2890.
2891.
2892.
2893.
2894.
2895.
2896.
2897.
2898.
2899.
2900.
2901.
2902.
2903.
2904.
2905.
2906.
2907.
2908.
2909.
2910.
2911.
2912.
2913.
2914.
2915.
2916.
2917.
2918.
2919.
2920.
2921.
2922.
2923.
2924.
2925.
2926.
2927.
2928.
2929.
2930.
2931.
2932.
2933.
2934.
2935.
2936.
2937.
2938.
2939.
2940.
2941.
2942.
2943.
2944.
2945.
2946.
2947.
2948.
2949.
2950.
2951.
2952.
2953.
2954.
2955.
2956.
2957.
2958.
2959.
2960.
2961.
2962.
2963.
2964.
2965.
2966.
2967.
2968.
2969.
2970.
2971.
2972.
2973.
2974.
2975.
2976.
2977.
2978.
2979.
2980.
2981.
2982.
2983.
2984.
2985.
2986.
2987.
2988.
2989.
2990.
2991.
2992.
2993.
2994.
2995.
2996.
2997.
2998.
2999.
3000.
3001.
3002.
3003.
3004.
3005.
3006.
3007.
3008.
3009.
3010.
3011.
3012.
3013.
3014.
3015.
3016.
3017.
3018.
3019.
3020.
3021.
3022.
3023.
3024.
3025.
3026.
3027.
3028.
3029.
3030.
3031.
3032.
3033.
3034.
3035.
3036.
3037.
3038.
3039.
3040.
3041.
3042.
3043.
3044.
3045.
3046.
3047.
3048.
3049.
3050.
3051.
3052.
3053.
3054.
3055.
3056.
3057.
3058.
3059.
3060.
3061.
3062.
3063.
3064.
3065.
3066.
3067.
3068.
3069.
3070.
3071.
3072.
3073.
3074.
3075.
3076.
3077.
3078.
3079.
3080.
3081.
3082.
3083.
3084.
3085.
3086.
3087.
3088.
3089.
3090.
3091.
3092.
3093.
3094.
3095.
3096.
3097.
3098.
3099.
3100.
3101.
3102.
3103.
3104.
3105.
3106.
3107.
3108.
3109.
3110.
3111.
3112.
3113.
3114.
3115.
3116.
3117.
3118.
3119.
3120.
3121.
3122.
3123.
3124.
3125.
3126.
3127.
3128.
3129.
3130.
3131.
3132.
3133.
3134.
3135.
3136.
3137.
3138.
3139.
3140.
3141.
3142.
3143.
3144.
3145.
3146.
3147.
3148.
3149.
3150.
3151.
3152.
3153.
3154.
3155.
3156.
3157.
3158.
3159.
3160.
3161.
3162.
3163.
3164.
3165.
3166.
3167.
3168.
3169.
3170.
3171.
3172.
3173.
3174.
3175.
3176.
3177.
3178.
3179.
3180.
3181.
3182.
3183.
3184.
3185.
3186.
3187.
3188.
3189.
3190.
3191.
3192.
3193.
3194.
3195.
3196.
3197.
3198.
3199.
3200.
3201.
3202.
3203.
3204.
3205.
3206.
3207.
3208.
3209.
3210.
3211.
3212.
3213.
3214.
3215.
3216.
3217.
3218.
3219.
3220.
3221.
3222.
3223.
3224.
3225.
3226.
3227.
3228.
3229.
3230.
3231.
3232.
3233.
3234.
3235.
3236.
3237.
3238.
3239.
3240.
3241.
3242.
3243.
3244.
3245.
3246.
3247.
3248.
3249.
3250.
3251.
3252.
3253.
3254.
3255.
3256.
3257.
3258.
3259.
3260.
3261.
3262.
3263.
3264.
3265.
3266.
3267.
3268.
3269.
3270.
3271.
3272.
3273.
3274.
3275.
3276.
3277.
3278.
3279.
3280.
3281.
3282.
3283.
3284.
3285.
3286.
3287.
3288.
3289.
3290.
3291.
3292.
3293.
3294.
3295.
3296.
3297.
3298.
3299.
3300.
3301.
3302.
3303.
3304.
3305.
3306.
3307.
3308.
3309.
3310.
3311.
3312.
3313.
3314.
3315.
3316.
3317.
3318.
3319.
3320.
3321.
3322.
3323.
3324.
3325.
3326.
3327.
3328.
3329.
3330.
3331.
3332.
3333.
3334.
3335.
3336.
3337.
3338.
3339.
3340.
3341.
3342.
3343.
3344.
3345.
3346.
3347.
3348.
3349.
3350.
3351.
3352.
3353.
3354.
3355.
3356.
3357.
3358.
3359.
3360.
3361.
3362.
3363.
3364.
3365.
3366.
3367.
3368.
3369.
3370.
3371.
3372.
3373.
3374.
3375.
3376.
3377.
3378.
3379.
3380.
3381.
3382.
3383.
3384.
3385.
3386.
3387.
3388.
3389.
3390.
3391.
3392.
3393.
3394.
3395.
3396.
3397.
3398.
3399.
3400.
3401.
3402.
3403.
3404.
3405.
3406.
3407.
3408.
3409.
3410.
3411.
3412.
3413.
3414.
3415.
3416.
3417.
3418.
3419.
3420.
3421.
3422.
3423.
3424.
3425.
3426.
3427.
3428.
3429.
3430.
3431.
3432.
3433.
3434.
3435.
3436.
3437.
3438.
3439.
3440.
3441.
3442.
3443.
3444.
3445.
3446.
3447.
3448.
3449.
3450.
3451.
3452.
3453.
3454.
3455.
3456.
3457.
3458.
3459.
3460.
3461.
3462.
3463.
3464.
3465.
3466.
3467.
3468.
3469.
3470.
3471.
3472.
3473.
3474.
3475.
3476.
3477.
3478.
3479.
3480.
3481.
3482.
3483.
3484.
3485.
3486.
3487.
3488.
3489.
3490.
3491.
3492.
3493.
3494.
3495.
3496.
3497.
3498.
3499.
3500.
3501.
3502.
3503.
3504.
3505.
3506.
3507.
3508.
3509.
3510.
3511.
3512.
3513.
3514.
3515.
3516.
3517.
3518.
3519.
3520.
3521.
3522.
3523.
3524.
3525.
3526.
3527.
3528.
3529.
3530.
3531.
3532.
3533.
3534.
3535.
3536.
3537.
3538.
3539.
3540.
3541.
3542.
3543.
3544.
3545.
3546.
3547.
3548.
3549.
3550.
3551.
3552.
3553.
3554.
3555.
3556.
3557.
3558.
3559.
3560.
3561.
3562.
3563.
3564.
3565.
3566.
3567.
3568.
3569.
3570.
3571.
3572.
3573.
3574.
3575.
3576.
3577.
3578.
3579.
3580.
3581.
3582.
3583.
3584.
3585.
3586.
3587.
3588.
3589.
3590.
3591.
3592.
3593.
3594.
3595.
3596.
3597.
3598.
3599.
3600.
3601.
3602.
3603.
3604.
3605.
3606.
3607.
3608.
3609.
3610.
3611.
3612.
3613.
3614.
3615.
3616.
3617.
3618.
3619.
3620.
3621.
3622.
3623.
3624.
3625.
3626.
3627.
3628.
3629.
3630.
3631.
3632.
3633.
3634.
3635.
                                  АННОТАЦИЯ
     
     
          Данный документ содержит  сведения  о  назначении  компоненты
     "Gass Station Advanced Utilities", общего ее описания  и  действий
     по настройке и тестированию.
     
     От читателя требуется знание терминов и основных принципов  работы
     SQL сервера (с которыми можно познакомится  в  книге  [1]);  языка
     C++, протоколов TCP/IP. Для постановки  задачи  используется  язык
     формальных спецификаций RSL (cm. [2,3] ).
     
     Работа выполнена по заказу компании TechnoLux, Ltd..
     
     Данный  документ  является  обьединением  документов   ТЕХНИЧЕСКОЕ
     ЗАДАНИЕ, ОПИСАНИЕ ПРОГРАММЫ.
     
     Дата создания документа: 24.12.2002

                                      5
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




           1.  ОБЩИЕ СВЕДЕНИЯ О "Gass Station Advanced Utilities"



     Информационная система  "Gass  Station  Advanced  Utilities"  версии  0
модификации 90 имеет обозначение GSAU \ve. "Gass Station Advanced Utilities"
является  набором  файлов  документации,  исполняемых   файлов   (работающих
частично  под  управлением  Windows  32,  частично  под  управлением  Unix),
исходных  текстов  программ   написанных   на   языке   C   (которые   могут
компилироваться под Windows 32 и Unix), скриптов, написанных на диалекте SQL
- Sybase SQL Anywere, для построения тестовой БД.
     
     
     
     
     1.1.  НАЗНАЧЕНИЕ "Gass Station Advanced Utilities"



     "Gass Station Advanced Utilities" предназначена для:

     - описания высокоуровневого протокола управления  насосами  заправочной
станции;

     - передачи  команд  управления  от  оператора  к  контроллерам  насосов
заправочной станции;

     - передачи информации о состоянии  насосов  и  контроллеров  насосов  к
оператору;

     - является  демонстрацией  возможностей  Библиотеки  Интерфейса  Обмена
Данными ( [4] );

     - является демонстрацией возможностей языка формальных спецификаций RSL
( [4] ) и применения его к использованию при проектирования реляционных БД.

                                      6
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     
     
     1.2.  МИНИМАЛЬНАЯ КОНФИГУРАЦИЯ ТЕХНИЧЕСКИХ И ПРОГРАММНЫХ
           СРЕДСТВ



     Минимальная конфигурация GSAU включает в себя

     - контроллер для управления насосами - ????????

     - выделенный  сервер,  работающий  под  управлением   FreeBSD   4.6   c
установленным Sybase ASA SQL сервером. Допускается использование Linux.

     - хотя  бы  один  клиент,  работающий  под   управлением   Windos   32.
Рекомендутеся WinNT, (Win2000, WinXP).

     - требуется  наличие   установленного   и   настроенного   программного
обеспечения для поддержки сети, использующей протоколы TCP/IP. Требования  к
сетевому оборудованию и программному обеспечению  совпадают  с  требованиями
Sybase SQL Anywhere.

     
     
     
     
     1.3.  ПРОЦЕДУРА УСТАНОВКИ GSAU



     not ready
     
     
     
     
     1.4.  ЗАПУСК И ОСТАНОВ GSAU



     not ready

                                      7
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




               2.  ОПИСАНИЕ "Gass Station Advanced Utilities"


     
     
     
     
     2.1.  ВВЕДЕНИЕ



     После нескольких лет изучения литературы, касающейся вопросов

     1) построения реляционных баз данных ([1]);

     2) построения надежного программного обеспечения ([6]);

     3) использования   формальных   методов   для   построения    надежного
программного обеспечения (RAISE: [2], [3]; VDM: [7]),
и, пообщавшись c некоторыми разработчиками и проектантами, удалось заметить,
что программисты, которые работают в данных областях, как бы игнорируют друг
друга. То есть те, кто использует формальные методы, ни чего  не  знают  про
реляционные базы данных, а те, кто занимется теорией и практикой реляционных
базы  данных,  ведать  не  ведают  о  формальных   подходах   к   построению
программного обеспечения.

     В документе делается попытка  показать  пути  для  использования  языка
формальных спецификаций RAISE для проектирования БД и  наметить  возможности
по  автоматической  генерации  SQL  -  скриптов  и  кода,   написанного   на
процедурных языках (например C++) из формальных  спецификаций  языка  RAISE.
Таким образом, используя мощь  формальной  пошаговой  разработки  и  жесткой
проверки типов на ранних стадиях RAISE Development Method-а, можно  было  бы
добиться существенного прогресса в таких нетривиальных  вопросах,  например,
как согласованное измененение типов полей таблиц  в  SQL  -  скриптах  языка
определения данных и, соответствующих этим  полям,  переменных  процедурного
языка.

     В связи с очевидной необьятностью данной задачи в  общем  (замахиваться
на генерацию всех тонкостей,  например,  SQL  от  Oracle  -  на  наш  взгляд
бесперспективная  задача),  было  принято  решения   сконцентрироваться   на
подмножестве DML (язык манипулирования  данными),  как  наиболее  близкий  к
"чистому" SQL и оставить без рассмотрения всевозможные диалекты для создания
хранимых процедур  (PL/SQL,  Transact  SQL,  Watcom  SQL  и  так  далее).  В
результате удалось

     1) создать специальный  тип  отношение  Relation,  как  отображение  из
натуральных  чисел(поля  первичного  ключа)  в   неинтерпретируемую   запись
(собственно сама запись);

     2) ввести функции (-члены  класса),  моделирующие  все  четыре  операци
(Insert, Update, Delete, Select с учетом организации курсоров);
                                      8
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     3) ввести функции (-члены класса), моделирующие фразу where (where);

     4) ввести функции (-члены класса), моделирующие  проверку  всевозможных
ограничений целостности (check, unique);

     5) промоделировать   условия   ссылочной    целостности    (referential
integrity);

     6) и показать способ записывания триггеров.

     7) показать какие поля структур должны иметь умолчательные  значения  и
могут не вводится в БД, а какие обязательно должны вводится явно. Это  можно
сделать через перегрузку функции insert.

     Со стороны  клиентской  части  приложения  (процедурный  язык  высокого
уровня) была создана библиотека обмена с базой данных ([4], [5]), основанная
на идее использования для обмена (Select,  Update,  Insert)  информацией  не
отдельных  host-  переменных,  а  специальных   структур   обмена,   которые
автоматически создаются из определения таблицы или  обзора.  Причем  удалось
добиться  "существенной  похожести"  обьектов,  наследующих  свойства   типа
отношеня Relation и структур обмена, таким образом, что одна  строчка  языка
формальных  спецификаций  транслируется  в  одну  (ну  почти  одну)  строчку
процедурного языка. В данном случае - C++.

     Все вышеизложенное  позволяет  считать  что  создан  некоторый  подход,
позволяющий  проектировать  и  разрабатывать   приложения,   основанные   на
реляционных базах данных таким  формальным  методом  как  RAISE  Development
Method. В качестве иллюстрации по использованию данного  подхода  приводится
пример разработка протокола общения между контроллером насосов и клиентскими
местами (операторами) заправочной станции.
     
     
     
     
     2.2.  ОБЩАЯ СХЕМА КОМПОНЕНТ GSAU И ИНТЕРФЕЙСОВ МЕЖДУ НИМИ



     Согласно рекомендациям ([6]) определим компоненты  из  которых  состоит
система GSAU и проследим потоки данных между компонентами.

     Cписок компонент системы GSAU:

     - исполнитель (agent) -  человек,  который  непосредственно  пользуется
насосом и наливает горючее в бак автомобиля;

     - бак автомобиля, далее бачок;

     - шланг насоса (nozzle);

     - насос  (pump);  кнопка  (позиция)  выбора  горючего,   далее   кнопка
(position). С каждой кнопкой жестко связана некотороя  пропорция  в  которой
смешивается  (или  не  смешивается)  горючее  из  разных  баков  заправочной
станции. ;
                                      9
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     - бак заправочной станции, далее бак  (tank).  На  заправочной  станции
содержится по два бака горючего разного качества. В момент заправки  горючее
из двух баков смешивается в заданной пропорции;

     - контроллер -  устройство  передающиее  информацию  между  насосами  и
компьютером;

     - com  -  порт  (com  port)  -  устройство,  через  которое  контроллер
подключается к компьютеру.

     - драйвер  контроллера  (driver)   -   программа,   которая   позволяет
обменивается  информацией  контроллеру  (через  com-  порт)  и   приложению,
использующему  контроллер.  В  нашем  случае  это  "Gass  Station   Advanced
Utilities";

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

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

     - менеджер драйверов контроллера (manager) - программа, маскирующая  от
основной части GSAU особенности реализации и сам факт наличия того или иного
контроллера.

     - наблюдатель  за  корректростью  изменения  состояния   насоса   (pump
monitor), наблюдатель состояний.

     - база данных - не комментируется.

     - UDP/TCP отправитель и получатель  -  компоненты  GSAU,  для  передачи
информации через UDP/TCP протоколы соответствено.

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

     - оператор.

     Драйвера, менеджер драйверов, наблюдатель  состояния,  TCP  получатель,
UDP отправитель и база данных физически  располагаются  на  GSAU  -  сервере
(Unix box). Наблюдатель ввода  и  приложение  интерфейса  пользователя,  UDP
получатель, TCP отправитель - физически  располагаются  на  GSAU  -  клиенте
(Windows box).

                                     10
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     2.2.1.  Описание взаимодействия GSAU- сервера и GSAU- клиента


     GSAU- сервер и GSAU- клиент обмениваются информацией друг  с  другом  в
асинхронном режиме через две пары каналов.  (Вообще  говоря  GSAU-  клиентов
может быть больше одного, но этот вопрос в данный момент нас не интересует и
на  схеме  не  отражен).  В  каждой  из  пар  роль  одного   канала   играет
соответствующий   протокол   интернета,   роль   второго    канала    играет
соответствующая таблица БД. Каждая из компонент может послать  информацию  в
другую компоненту в любой момент времени. От сервера  к  клиенту  (клиентам)
информация посылается через протокол UDP (на схеме -  проходит  через  канал
UDP, таблицу State), так как все клиенты должны  отображать  все  изменения,
которые  происходят  на  насосах  станции.  Таким  образом  получаем  одного
отправителя и много получателей информации. От клиента (клиентов) к  серверу
информация посылается через протокол TCP (канал TCP и таблицу Command),  так
как имется в точности один отправитель и один получатель информации.

     В   каждой   отдельной   операции    пересылки/требования    информации
пересылается один отдельно взятый атрибут насоса.

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


     Основными типами потоков данных  есть  State,  StateIndicator  (синоним
Indicator), Command,  CommandIndicator  (синоним  Indicator).  Типы  Pump  и
Position   будут   использоваться   для   построения   структур   обмена   и
соответствующих конкретных таблиц на основе типа Relation.

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

     - pump (натуральное число) - содержит уникальный идентификатор насоса,

     - и state (может иметь любой тип из заданного множества  типов  (TTank,
Gas, OnLine и т.д.) - аналог обьединения (Union) языка СИ) каждый из которых
описывает соответствующй атрибут насоса.  Таким  образом,  любая  переменная
типа State однозначно задает значение любого атрибута любого насоса.

     Далее, тип Command имеет дополнительный атрибут логического  типа,  что
бы показать должен ли контроллер задать (писать) желаемое значение желаемого
атрибута  насоса  или  контроллер  должен  вычитать  (читать)  значение  это
значение желаемого атрибута.
                                     11
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     Переменные типа Command и State записываются в  соответствующие  строки
таблиц  базы  данных  ("медленная"  связь).  Информация  о   наличии   новой
команды/новом состоянии передается через "быстрый" канал связи (сеть TCP/IP)
переменными типа Indicator, уведомляя об изменениях, произошедших в таблицах
БД. Переменная типа Indicator имеет поля, необходимые для надежной работы  и
однозначного определения, передаваемой информации. Поле index -  опеределяет
таблицу и колонку в которой произошли изменения, поле id задает строчку этой
таблицы, поле get_set -  сообщает  является  ли  заданная  строчки  командой
установить или вычитать значения.

     Большая часть типов для атрибутов, например тип Gas,  является  записью
(Record)  и,  одновременно  с  определением   переменной   заданного   типа,
опеределяет несколько функций, которые могут использоваться  вместе  с  этой
переменной - конструктор, деструкторы и реконструкторы.  Имена  деструкторов
совпадают с именами полей, имена реконструкторов перечисляются после символа
<->. Рассмотрим изложенное на примере типа Gas. Тут заданы следующие функции

     - mk_Gas : Real >< Nat -> Gas - создание записи (конструктор)

     - v : Gas -> Real - доступ к полям (деструктор)

     - p : Gas -> Nat

     - v : Real >< Gas -> Gas - изменение записи (реконструктор)

     - p : Nat >< Gas -> Gas

     Таким образом, определив переменные или величины как x : Gas, y:  Real,
z: Nat, мы получаем возможность писать

     - mk_Gas(y,z)

     - y = v(x) - а не x.v как в большинстве языков программирования

     - 5 < p(x)

     - x := v(3.141592, x)

     - p(22222, x)


db_start

scheme Types =
    extend db_start with class
type
    TTank         = {|n : Nat:- n <=2 |}, -- 0 нет бака, 1 и 2 номера баков
    Gas           :: v: Real  <-> v       --  value of gas
                     p: Nat   <-> p,      --  what is position

                   --  типы для описания отдельных характеристик
                   --  используются в структуре, для передачи состояния

                              -- кол-во бензина на заданной кнопке
                                     12
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    OnLine        :: v: Bool  <-> v ,
                              -- есть ли связь с насосом
    Start         :: v: Text  <-> v, -- момент, когда начал считать счетчик
                                     --  total
    Total         :: v: Real  <-> v, -- количестов горючего протекшего
                                     -- через насос
    Measure,                         -- единица измерения
    FreeFill      :: v: Bool  <-> v, -- нужно ли ожидать разрешения наливать
                                     --  горючее


--    Query         :: v: Text  <-> v, -- момент сьема состояния
    Button        :: v: Nat   <-> v, -- агент выбрал кнопку для набора
    NozzleUp      :: v: Bool  <-> v, -- снят ли шланг
    Filling       :: v: Bool  <-> v, -- льется ли горючее
    Filled        :: v: Real  <-> v, -- сколько безина налито в текущем
                                     -- /предыдущем
                                     -- работы цикле
    CycleEnd      :: v: Bool  <-> v, -- разрешение закончить цикл и перейти
                                     --  к  след.
                                     -- горючего
    Paid          :: v: Bool  <-> v, -- горючее уже оплачено кредитной
                                     -- карточкой через устройство на насосе


    FillStart     :: v: Bool  <-> v, -- оператор разрешил наливать горючее
    Limit         :: v: Gas  <->  v, -- оператор задал кол-во горючего и
                                     --  кнопку
    EndWait       :: v: Bool  <-> v, -- ожидает разрешение перейти к
                                     --  следующему циклу работы
    Freeze        :: v: Bool  <-> v, -- работа насоса остановлена
    Restart       :: v: Bool  <-> v, -- перевести насос в начальное
                                     -- состояние


    Error         :: v: Text <-> v,  -- обнаружена программная ошибка

    Proportion    :: p: Nat                     <-> p
                                     -- uid of position/button
                     v: {|n: Nat:- n <= 100|}   <-> v,
                          -- пропорция смеси горючего на заданной кнопке
    EOG           :: p: Nat        <-> p
                     isGas: Bool   <-> isGas,
                          -- end of gas               на заданной кнопке
    Tank          :: p: Nat          <-> p
                     tank1: TTank    <-> tank1
                     tank2: TTank    <-> tank2,
                          -- два бака горючего        на заданной кнопке
    Mark          :: p: Nat        <-> p
                     name: Text    <-> name,
                          -- марка бензина            на заданной кнопке
    Price         :: p: Nat    <-> p
                     v: Real   <-> v,
                          -- цена бензина             на заданной кнопке
                                     13
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02



    State1  =             --  состояние насосов. в этой структуре
                          --  записывается один из атрибутов
                          --  насоса

               Gas        | OnLine  |  Total  |  Start    | Freeze   |
               Error      | Restart |  --Query   |
               Proportion | Filled  | EndWait | CycleEnd  | Filling  |
               EOG        | NozzleUp  | Limit   | FillStart | FreeFill |
               Tank       | Measure | Paid |
               Mark       | Price   | Button
   ,
    State         ::    pump  : Nat     <-> pump  -- uid of pump
                        state : State1  <-> state --
   ,
    Indicator      --  информация, передаваемая от сервера к клиенту
                   --  (и обратно)
                   --  по быстрому каналу связи. получатель использует
                   --  эту информацию для чтения изменения в состоянии
                   --  и отображения этого изменения
                   ::
                messageNo   : Nat   <->
                                   messageNo  -- последов.номер сообщения
                                              -- для решения вопроса было
                                              -- ли потеряно некоторое
                                              -- сообщение при передаче
                index       : Nat   <->
                                   index      -- число, которое определяет
                                              -- таблицу и колонку из
                                              -- которой читать
                id          : Key  <->
                                   id         -- номер строчки, которая
                                              -- изменилась
                get_set     : Bool <->
                                   get_set    -- поле имеет различный смысл
                                              -- для индикаторов состояний и
                                              -- индикаторов команд
--
-- I am to lazy to modify rest of  rsl-code
--                note        : Text <->
--                                   note       -- поле предназначено для
--                                              -- перечи информацией,
--                                              -- неинтерпретируемой
--                                              -- рассматриваемой компонентой
   ,
    StateIndicator = Indicator
                   --   get_set = false => значение поля
                   --                      было потребовано оператором
                   --   get-set = true  => значение поля было вычитано
                   --                      сервером без команды оператора
   ,
    Pump           --  описание насосов в БД и
                   --  параметры насоса  (меняются редко)
                                     14
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                   --
                   --
           ::   uid      : Nat     <->  uid
                onLine   : Bool    <->  onLine
                start    : TDate   <->  start
                total    : Real    <->  total
                measure  : Text    <->  measure
                nPoss    : Nat     <->  nPoss
                                    -- ? сколько кнопок на насосе
                freeFill : Bool    <->  freeFill

                   --  сигналы, поступающие со стороны агента

                button   : Nat     <->  button   -- кнопка на насосе,
                                                 -- выбранная агентом
                nozzleUp : Bool    <->  nozzleUp
                filling  : Bool    <->  filling
                filled   : Real    <->  filled
                paid     : Bool    <->  paid
                endWait  : Bool    <->  endWait

                   -- сигналы, поступающие со стороны оператора

                fillStart: Bool    <->  fillStart
                cycleEnd : Bool    <->  cycleEnd
                setPos   : Nat     <->  setPos
                setLimit : Real    <->  setLimit
                freeze   : Bool    <->  freeze
                restart  : Bool    <->  restart

                   -- это генерируется программой

                error    : Text    <->  error
                query    : TDate   <->  query
--                name     : Nat     <-> name
   ,
    Position       --  описание кнопок на насосе
           ::   uid      : Nat     <-> uid
                price    : Real    <-> price
                mark     : Text    <-> mark
                tank1    : TTank   <-> tank1
                tank2    : TTank   <-> tank2
                eog      : Bool    <-> eog
                proportion: Nat    <-> proportion
                pump     : Key     <-> pump
--                name     : Text    <-> name
   ,
    Command        --  команды оператора
            =      --  представляют собой  пару брать/установить
               Bool ><       -- false - to get new state of pump
                             -- true  - to set new state of pump
                   -- и что брать/установить. "что" - определяется
               State         --  ранее введенным типом состояние

                                     15
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

   ,
    CommandIndicator = Indicator
                   --   get_set = false => оператор потребовал
                   --                         значение поля
                   --   get_set = true  => оператор устанавливает
                   --                         значение поля

                   --
                   -- набор служебных функций приложения
                   --


value
                   --  является ли изменение состояния допустимым?
                   --  функция - "guards" [2] для выражения предусловий
                   --  в данной работе не используется
                   --
    isConversionValid : State >< State ->      Bool
   ,               --  функция восстановления состояние насоса
    StateCorrection   : State >< State ->
                                               Command
   ,
    pStt : StateIndicator,    -- предыдущее состояние
    rcvCnt: Int    -- recovery count - счетчик попыток восстановления

end


     
     
     2.2.3.  Глобальные обьекты проекта


     Авторы   RSL   рекомендуют   после   определения    схемы    (файл    с
rsl-спецификациями) Types, содержащий типы и атрибуты  для  не  динамических
обьектов, на ее основе определить глобальный обьект T.




Types

object T : Types


После чего ссылаться на введенные типы и атрибуты в форме  T.xxx.  Например,
для  описания  прототипа  функции  get  из  раздела   "Определение   функций
интерфейса с базой данных" используется следующий текст
        get:        T.CommandIndicator      ->
                                write
                                    Pump.any, Position.any,
                                    Cmd4Pmp.any,  Cmd4Pos.any

                                T.Command
                                     16
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     Запись T.Сommand означает,  что  всюду  определенная  (total  function,
символ ->, в отличие от частично определенных функций, символ -~->)  функция
get вырабатывает значения типа Command из  значений  типа  CommandIndicator,
которые были определены в глобальном обьекте T.

     Кроме того, данная функция обладает  правом  писать  в  любые  атрибуты
переменных - обьектов Pump, .... Функции с правом доступа  к  каким  -  либо
переменным также будут называться операторами.



     
     
     2.2.4.  Cхема взаимодействия между GSAU-сервером и GSAU
             клиентом


                                     17
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


     ver 00.90.10 - some description in DB.rsl have been added

     ver 00.90.00 - improvement of the description

     ver 00.07.06 - the field note have been added to indicator

     ver 00.07.05 - there was a bug in the put - functions

     ver 00.07.04 - a lot if needless let-s have been
                    removed from  DB.rsl
     ver 00.07.03 - phrase check && unique have been added to Relation

     ver 00.07.01
          . . . . . . . . . . . . . . . . . . . . . .
          .                     TCP                 .
          .                                         .
        /-- < TCPReciever <-------------< TCPSender<--------------------\
       |  . . . . . . . . . . . . . . . . . . . . . .                   |
       |<-----------------\                                             |
       |                  |. . . . . . .                                |
/ --->--\---> server>-\   |.           .                                |
|                     |   |\-<Command<---------------------------------\|
|                     |   |.           .                                |
\<DriverManager<-----<|   |.   DB      .                                |
                      |   |.           .      /--------< UserInterface<-\
         /----------- /   |./>State>\  .      |                         |
         |                |.|       |<--------/                         |
         |                /.|. . . .\. .                                |
         \--->PumpMonitor>-\/       /--> client>------------------------/
                           |        |
 /-------------------------/        \-------------------\
 |        . . . . . . . . . . . . . . . . . . . . . . . |
 \----------> UDPSender >---------------->UDPReciever>--/
          .                                           .
          .                     UDP                   .
          . . . . . . . . . . . . . . . . . . . . . . .


     Взаимодействие между \id - сервером и клиентов заключается в  том,  что
они посылают друг другу индикаторы команд и состояний через каналы  TCP/UDP.
Получатив  индикатор  команды  или  состояния,  соответствующая   компонента
(сервер или клиент) читает необходимую информацию из подходящих таблиц БД.

     В первых строчках схемы обьявляется использование схем T и DB. Схема  T
содержит описание глобального обьекта проекта (обсуждалось выже),  схема  DB
используется для наследования (extend DB) ее свойств текущей схемой GSAU, то
есть GSAU порождается из схемы DB.


T
,DB
scheme GSAU =
--hide sqlCode   in
                                     18
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

extend DB with
class
channel
    TCP : T.CommandIndicator,
    UDP : T.StateIndicator
variable
    msgCnt : Nat := 0
value
                           -- work of server

    Server: Unit    ->
                        write any in TCP out UDP
                        Unit
    Server() is
        (let v = TCP? in   UDP! server(v)  end
         |=|             -- оператор внешнего выбора
                         -- если в канале TCP есть что читать,
                         -- Server должен прочитать это и отреагировать,
                         -- иначе он может сам вывести информацию
                         -- об изменениях на насосах в канал UDP.
         UDP! server ()  --
                         -- подразумевается, что вызов server()
                         -- отрабатывает быстрее, чем оператор вводит
                         -- новые команды, так же как и вызов client()
                         -- (см. ниже) работает быстрее,
                         -- чем происходят изменения на насосах.
        )
        ; Server()
   ,
    server : T.CommandIndicator  ->
                        write any
                        T.StateIndicator
                               -- реакция на сигнал от клиента
    server (ci) is             -- сервер отвечает
    PumpMonitor( DriverManager( get(ci)))
   ,

    server : Unit   ->
                         write any
                         T.StateIndicator
    server () is
    PumpMonitor( DriverManager( )) -- сервер генерирует информацию
   ,                               -- без запроса клиента


                                   -- компонента, следящая за состояние
                                   -- системы
    PumpMonitor:  Bool ><          --
                  T.State    -~->
                          write any
                          T.StateIndicator

    PumpMonitor (g_s, s) is
      local
                                     19
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

        variable
          newS   : T.State := s,
          cnt    : Int     := 0
      in                           -- попытки восстановления допустимого
                                   -- состояния
        while(T.isConversionValid (newS, get(T.pStt)) = false) do
          let
            (a, b) = DriverManager(T.StateCorrection(newS,
                                                     get(T.pStt)
                                                    )
                                  )
          in
           --  newG_s := a;
             newS   :=  b
          end
          ;
          cnt := cnt + 1;
          if cnt >= T.rcvCnt then
            stop
          end
        end;
        msgCnt := msgCnt + 1;
        put(g_s, newS, msgCnt)
      end
   ,

                           -- источник возникновения сообщений
                           -- о измененном состоянии насоса / контроллера
                           --

    DriverManager: T.Command  ->    Bool >< T.State,   -- (true, state)
    DriverManager: Unit       ->    Bool >< T.State,   -- (false, state)



                           -- work of client


    Client: Nat    ->                                  -- number of client
                        write any in UDP out TCP
                        Unit
    Client(n) is
        (let v = UDP? in      TCP!  client(v, n)   end
         |=|
         TCP! client(n)
        )
        ; Client(n)
   ,

    client : T.StateIndicator >< Nat ->
                         write any

                         T.CommandIndicator
                                          -- оператор реагирует на изменения
                                     20
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                                          -- в насосах
    client ( si, n) is
    put( UserInterface ( get(si), n), n)
   ,

    client : Nat    ->                        -- оператор выдал команду
                         write any
                         T.CommandIndicator   -- для насосов
    client (n) is
    put( UserInterface ( n ), n)
   ,
                           -- источник возникновения команд
                           -- этой функцией замаскирован оператор
                           -- системы, который выдает команды

    UserInterface: T.State >< Nat    ->    T.Command,
    UserInterface: Nat               ->    T.Command

end



     Описаны взаимодействие между GSAU -  сервером  и  GSAU  -  клиентами  и
алгоритмы   работы   наиболее   крупных   компонент.   Мы   может    перейти
непосредственно к рассмотрении функций работы  с  БД  (какие  и  есть  нашим
главным интересом).
     
     
     2.2.5.  Описание БД и операторов языка манипулирования
             данными DML



     
     
     2.2.6.  Функции высокоуровневого интерфейса


     Следующая схема языка RSL в действительности содержит директивы
для

     1) создания 4 - х таблиц в БД. Эти директивы  относятся  к  группе  DDL
языка SQL. По - видимому они должны быть  реализованы  как  SQL-  скрипт  и,
вообще говоря, будут выполняться на  SQL  -сервере  в  момент  инициализации
экземпляра БД;

     2) создания набора функций для интерфейса между выполняемыми файлами  и
БД. Мы имеем  два  выполняемых  файла:  GSAU-  клиент  и  выполняемый  файл,
располагающийся на GSAU - сервере - некоторый процесс (все кроме  собственно
БД). Эти функции должны быть транслированы в язык C.



T
                                     21
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

,Relation
,TPump
,TPosition
scheme  DB  =
extend  db_start with
class

     
     
     2.2.6.1.  Определение таблиц базы данных GSAU


     В обьекте DB приводится описание всех обьектов, представляющих  таблицы
базы данных, и реляционных связей между ними. Использование параметризованых
rsl  -  схем  позволяет   описывать   ссылочные   ограничения   целостности.
(referencial integrity) Это достигается  передачей  в  качестве  актуального
параметра второго обьекта - партнера (родителя  или  ребенка)  при  описании
первого обьекта. Например,  в  таблице  Position  есть  поле  pump,  которое
ссылается на таблицу Pump, этот факт отражается, тем что в  обьект  Position
(соответствующий таблице Position) передается актуальный параметр (родитель)
- обьект Pump (соответствующий таблице Pump), а  в  обьект  Pump  передается
актуальный  параметр  (ребенок)  -  обьект  Position.  В  обьекте   Position
проверяется наличие первичного ключа для ссылки на обьект Pump, а в  обьекте
Pump актуальный параметр используется для  спецификации  алгоритма  операции
delete (on delete restrict) - если в обьекте Position есть строчки,  которые
ссылаются  на  первичный   ключ   p   в   Pump,   то   применение   операции
Pump.delete({p}) приведет к  каскадному  удалению  этих  записей  в  таблице
Position.


    object

                          -- в эти две таблицы будем
                          -- записывать параметры команд оператора
                          --
        Cmd4Pmp : TPump  (Cmd4Pos)
       , Cmd4Pos : TPosition (Cmd4Pmp)


                          -- State << Pump >< Position
                          -- в эти две таблицы будем записывать
                          -- изменения атрибутов насосов и контроллеров
       , Position: TPosition (Pump)
       , Pump    : TPump  (Position)

     
     
     2.2.6.2.  Определение функций интерфейса с базой данных GSAU


     Все множество функций представляет собой две пары put и get. Одна  пара
- положить/взять команду, вторая - положить/взять состояние параметра.


                                     22
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    value
                                -- положить / взять  команду

        get:        T.CommandIndicator      ->
                                write
                                    Pump.any, Position.any,
                                    Cmd4Pmp.any,  Cmd4Pos.any

                                T.Command
        get (ci) is
          let T.mk_Indicator (_, idx, id, g_s) = ci in
            if idx < 100 then     -- будем использовать атрибуты
              let p = if          -- насоса
                          g_s

     
     
     2.2.6.2.1.  Использование оператора SELECT


     Это пример использования оператора SELECT. В  случае  трансляции  этого
текста в С++ код, в этом месте можно использовать структура  обмена  данными
(sde).  Тогда  преобразование  кода  представляется  очевидным.  Смотри  для
примера файл src/gsau_up.cpp, строчка #35

    GSAU_RCmd4Pmp  Cmd4Pmp  (database);
    ...
            rc = Cmd4Pos.Select(&id);   // строчка #59
            p  = (GSAU_RPosition *) &Cmd4Pos;
    ...

здесь происходит создание обьекта - структуры обмена данными (sde) Cmd4Pmp и
чтение заданной строчки из таблицы SQL  серверва  в  эту  структуру  обмена.
После этого можно использовать поля структуры обмена. Они  приняли  значения
одноименных столбцов таблицы. Пример  использования  приводится  на  строчке
#196 файла gsau_pu.cpp.

                        p->proportion.toStr(),   //


     Наблюдается  полное  совпадения.  Практически  1  строчка  rsl   текста
преобразуется в 1 строчку C++ кода.



                      then
                          Cmd4Pmp.select(id)
                      else
                          Pump.select (id)
                      end
              in              -- после извлечения записи она больше
                              -- не нужна


                                     23
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     2.2.6.2.2.  Использование оператора DELETE


     Это пример использования оператора DELETE.




                if g_s then Cmd4Pmp.delete({id}) end;

                              -- из записи p извлечь атрибут uid и какой
                ( g_s,        -- сделать из них пару
                              -- (признак_команды, состояние)
                  T.mk_State (
                      T.uid(p),
                      case idx of
                        1 ->  T.mk_OnLine(T.onLine(p))
                       ,
                        2 ->  T.mk_Start(T.start(p))
                       ,
                        3 ->  T.mk_Total(T.total(p))
                         ,
                        4 ->  T.mk_Measure(T.measure(p))
                       ,
                        5 ->  T.mk_NPos(T.nPos(p))

                       ,
                        6 ->  T.mk_FreeFill(T.freeFill(p))
                       ,
                        7 ->  T.mk_Button(T.button(p))
                       ,
                        8 ->  T.mk_NozzleUp(T.nozzleUp(p))
                       ,
                        9 ->  T.mk_Filling(T.filling(p))
                       ,
                        10 -> T.mk_Filled(T.filled(p))
                       ,
                        11 -> T.mk_CycleEnd(T.cycleEnd(p))
                       ,
                        12 -> T.mk_Paid(T.paid(p))
                       ,
                        13 -> T.mk_FillStart(T.fillStart(p))
                       ,
                        14 -> T.mk_Limit(T.mk_Gas(T.setLimit(p),
                                              T.setPos(p)
                                             )
                                    )
                       ,
                        15 -> T.mk_EndWait(T.endWait(p))
                       ,
                        16 -> T.mk_Freeze(T.freeze(p))
                       ,
                        17 -> T.mk_Restart(T.restart(p))
                                     24
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                       ,
                        18 -> T.mk_Error(T.error(p))

                      end
                  )
                )
              end
            else                           -- будем использовать атрибуты
              let p = if                   -- кнопки насоса
                          g_s
                      then
                          Cmd4Pos.select(id)
                      else
                          Position.select (id)
                      end
              in
                if g_s then Cmd4Pos.delete({id}) end;
                ( g_s,
                  T.mk_State (
                      T.uid(p),     -- !!!!!! эта ошибка  сюда надо ложить
                                    --  уид насоса
                      case idx of
                                           --
                        101 ->  T.mk_Proportion(T.pump(p), T.proportion(p))
                                           --     ^^^^
                                           --     а сюда уид позиции
                       ,
                        102 ->  T.mk_EOG(T.pump(p), T.eog(p))
                       ,
                        103 ->  T.mk_Tank(T.pump(p),T.tank1(p), T.tank2(p))
                       ,
                        104 ->  T.mk_Mark(T.pump(p), T.mark(p))
                       ,
                        105 ->  T.mk_Price(T.pump(p), T.price(p))
                      end
                  )
                )
              end
            end
          end
       ,

        put:        T.Command >< Nat ->     -- client number
                                write  Pump.any, Position.any,
                                       Cmd4Pmp.any,  Cmd4Pos.any
                                T.CommandIndicator
        put ((g_s, stt), n) is
        local
          variable
            p   : Nat-set := {},
            idx : Nat     := 0
        in
          let T.mk_State(pUid, s) = stt in
        --                        --
                                     25
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

            if g_s then           -- в случае команды установить

     
     
     2.2.6.2.3.  Использование оператора INSERT


     Это пример использования оператора INSERT. В  этом  месте  используется
перегруженная функция insert, в  котороя  явно  задается  только  поле  uid.
Остальные поля принимают значения по умолчанию.



              Cmd4Pmp.insert(     -- создал запись и вставил ее в спец.
                                  --  таблицу
                    pUid          -- (ЭТО СПЕЦ. ИНСЕРТ cm Pump.rsl)
              );
              p := {Cmd4Pmp.identity};-- и взял ее id
              Cmd4Pmp.query(T.timeStamp(),p)
                                  -- записал время выдачи команды
            else                  -- для чтения - узнать id существующей
                                  -- записи
              p:= Pump.uid2id(pUid)
            end
            ;
            if p~= {} then
              case s of
              T.mk_OnLine(b) ->

     
     
     2.2.6.2.4.  Использование оператора UPDATE


     Это пример использования  оператора  UPDATE.  С  этим  оператором  есть
небольшая  сложность.  В  случае  rsl  -   текста   я   не   переживаю   про
производительность и, как видно ниже, просто  заменяю  поле  onLine  таблицы
Cmd4Pmp во всех строчках, первичный ключ которых содержится во множестве  p.
Если понадобится редактировать второе поля  необходимо  поступать  таким  же
образом. Это не ДОЛЖНО переносится в C++ текст  в  такой  форме  (это  будет
снижать производительность). Надо поменять  значение  соответствующих  полей
структуры обмена данными и потом выполнить операцию update  сразу  для  всех
полей записи таблицы (структуры обмена).



                  if g_s then     -- если задавать значение
                                  -- то в новую запись вписать значение
                                  --  онлайн
                      Cmd4Pmp.onLine (b, p)
                  end;             -- иначе ничего не делать
                  idx := 1
             ,
              T.mk_Start(t) ->
                                     26
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                  if g_s then
                      Cmd4Pmp.start (t, p)
                  end;
                  idx := 2
             ,
              T.mk_Total(t) ->
                  if g_s then
                      Cmd4Pmp.total (t, p)
                  end;
                  idx := 3
             ,
                T.mk_Measure(t) ->            -- не готово
                  if g_s then
                      Cmd4Pmp.measure (t, p)
                  end;
                  idx := 4
             ,
              T.mk_NPos(t) ->
                  if g_s then
                      Cmd4Pmp.nPos (t, p)
                  end;
                  idx := 5
             ,
                T.mk_FreeFill(t) ->
                  if g_s then
                      Cmd4Pmp.freeFill (t, p)
                  end;
                  idx := 6
             ,                  --
                                -- попытка установить атрибут насоса
                                -- шланг_поднять в тру не несет большого
                                -- смысла, (шланг от этого не подымется)
                                -- наверно в драйвере эта команда будет
                                -- запрещена или будет игнорироваться.
                                -- этоже отностся к NPos и, вообще, к
                                -- атрибутам для сигналов, поступающих
                                -- со стороны атента.
                                -- введено для однообразия и будущего
                                -- развития.
              T.mk_Button(t) ->
                  if g_s then
                      Cmd4Pmp.button (t, p)
                  end;
                  idx := 7
             ,
              T.mk_NozzleUp(t) ->
                  if g_s then
                      Cmd4Pmp.nozzleUp (t, p)
                  end;
                  idx := 8
             ,
              T.mk_Filling(t) ->
                  if g_s then
                      Cmd4Pmp.filling (t, p)
                                     27
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                  end;
                  idx := 9
             ,
              T.mk_Filled(t) ->
                  if g_s then
                      Cmd4Pmp.filled(t, p)
                  end;
                  idx := 10
             ,
              T.mk_CycleEnd(t) ->
                  if g_s then
                      Cmd4Pmp.cycleEnd (t, p)
                  end;
                  idx := 11
             ,
              T.mk_Paid(t) ->
                  if g_s then
                      Cmd4Pmp.paid (t, p)
                  end;
                  idx := 12
             ,
              T.mk_FillStart(t) ->
                  if g_s then
                      Cmd4Pmp.fillStart (t, p)
                  end;
                  idx := 13
             ,
              T.mk_Limit(T.mk_Gas(r,b)) ->
                  if g_s then
                      Cmd4Pmp.setLimit (r, p);
                      Cmd4Pmp.setPos  (b, p)
                  end;
                  idx := 14
             ,
              T.mk_EndWait (t) ->
                  if g_s then
                      Cmd4Pmp.endWait (t, p)
                  end;
                  idx := 15
             ,
              T.mk_Freeze(t) ->
                  if g_s then
                      Cmd4Pmp.freeze (t, p)
                  end;
                  idx := 16
             ,
              T.mk_Restart(t) ->
                  if g_s then
                      Cmd4Pmp.restart (t, p)
                  end;
                  idx := 17
             ,
              T.mk_Error(t) ->
                  if g_s then
                                     28
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                      Cmd4Pmp.error (t, p)
                  end;
                  idx := 18
             ,
              T.mk_Proportion (b, v) ->          -- а читаю я правильно
                  if g_s then                    -- читаю уид позиции
                      Cmd4Pos.insert(  b, hd p)     -- спец. таблицу
                      ;
                      p := {Cmd4Pos.identity};
                      Cmd4Pos.proportion (v, p)
                  else                 -- по уиду позиции и id насоса взяли
                                       -- id позиции
                      p := Position.uid_pump2id (b, hd p)
                  end;
                  idx := 101
             ,
              T.mk_EOG (b, v) ->
                  if g_s then          -- ошибочка есть
                      Cmd4Pos.insert( b, hd p)
                      ;
                      p := {Cmd4Pos.identity};
                      Cmd4Pos.eog (v, p)
                  else
                      p := Position.uid_pump2id (b, hd p)
                  end;
                  idx := 102
             ,
              T.mk_Tank (b, t1, t2) ->
                  if g_s then
                      Cmd4Pos.insert( b, hd p)
                      ;
                      p := {Cmd4Pos.identity};
                      Cmd4Pos.tank1 (t1, p);
                      Cmd4Pos.tank2 (t2, p)
                  else
                      p := Position.uid_pump2id (b, hd p)
                  end;
                  idx := 103
             ,
              T.mk_Mark (b, v) ->
                  if g_s  then
                      Cmd4Pos.insert( b, hd p)
                      ;
                      p := {Cmd4Pos.identity};
                      Cmd4Pos.mark (v, p)
                  else
                      p := Position.uid_pump2id (b, hd p)
                  end;
                  idx := 104
             ,
              T.mk_Price (b, v) ->
                  if g_s then
                      Cmd4Pos.insert( b, hd p)
                      ;
                                     29
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                      p := {Cmd4Pos.identity};
                      Cmd4Pos.price (v, p)
                  else
                      p := Position.uid_pump2id (b, hd p)
                  end;
                  idx := 105
              end
            end
            ;
            T.mk_Indicator(0, idx,
                        if p~={} then hd p else T.notFound end, g_s)
          end
        end
       ,
                                   -- положить / взять состояние
 --
 --           the server - client stream
 --

        get:        T.StateIndicator      ->
                              write Pump.any,
                                    Position.any
                              T.State
        get(si) is
           let T.mk_Indicator (_, idx, id, _) = si in
             if idx < 100 then
               let p = Pump.select(id) in
                 T.mk_State ( T.uid(p),
                     case idx of
                       1  ->   T.mk_OnLine(T.onLine(p))
                      ,
                       2  ->   T.mk_Start (T.start(p))
                      ,
                       3  ->   T.mk_Total (T.total(p))
                      ,
             --        4  ->   T.mk_Measure  (T.measure(p))
             --       ,
             --        5  ->   T.mk_NPos     (T.nPos   (p))
             --       ,
                       6  ->   T.mk_FreeFill (T.freeFill(p))
                      ,
                       7  ->   T.mk_Button(T.button(p))
                      ,
                       8  ->   T.mk_NozzleUp (T.nozzleUp (p))
                      ,
                       9  ->   T.mk_Filling (T.filling (p))
                      ,
                       10 ->   T.mk_Filled(T.filled(p))
                      ,
                       11 ->   T.mk_CycleEnd (T.cycleEnd (p))
                      ,
                       12 ->   T.mk_Paid (T.paid (p))
                      ,
                       13 ->   T.mk_FillStart (T.fillStart(p))
                                     30
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                      ,
                       14 ->   T.mk_Limit (T.mk_Gas(T.setLimit (p),
                                                    T.setPos(p)
                                                    )
                                          )
                      ,
                       15 ->   T.mk_EndWait (T.endWait (p))
                      ,
                       16 ->   T.mk_Freeze (T.freeze(p))
                      ,
                       17 ->   T.mk_Restart (T.restart(p))
                      ,
                       18 ->   T.mk_Error (T.error(p))
                     end
                 )
               end
             else
               let p = Position.select(id) in
                 T.mk_State ( T.uid(p),
                     case idx of
                       101  ->  T.mk_Proportion (T.pump (p),
                                         T.proportion(p))
                      ,
                       102  ->  T.mk_EOG (T.pump (p), T.eog(p))
                      ,
                       103  ->  T.mk_Tank (T.pump (p), T.tank1(p),
                                                  T.tank2(p))
                      ,
                       104  ->  T.mk_Mark (T.pump (p), T.mark(p))
                      ,
                       105  ->  T.mk_Price (T.pump (p), T.price(p))
                     end
                 )
               end

             end
           end

       ,
                                   --
                                   -- вывод состояния в БД
                                   -- и создание индикатора состояния
                                   --
        put:      Bool >< T.State  >< Nat
                  ->               -- выводить состояние можно на всякий
                              write  --State.any,
                                   -- надо изменить строчку либо в
                                Pump.any,
                                Position.any
                              T.StateIndicator
                                   -- таблице Position, либо в Pump
        put(g_s, stt, cnt) is                        --
        local
          variable
                                     31
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

            p   : Nat-set := {},            -- состояние s
            idx : Nat := 0                  -- проапдейтили значение кнопки
        in                                  -- для насоса с id p
          let T.mk_State(pUid, s) = stt in  -- для насоса p получили
                                            -- изменение
            p := Pump.uid2id(pUid) ;
            if p ~= {} then
                Pump.query(T.timeStamp(), p);
                case s of
                T.mk_OnLine(b)   ->  Pump.onLine(b,p) ;
                                     idx := 1
               ,
                T.mk_Start(t)    ->  Pump.start(t,p);
                                     idx := 2
               ,
                T.mk_Total(r)    ->  Pump.total(r,p);
                                     idx := 3
               ,
     --             T.mk_Measure() ->  skip  4
     --             T.mk_NPos   () ->  skip  5

                T.mk_FreeFill(b) ->  Pump.freeFill (b, p);
                                     idx :=  6
               ,
                T.mk_Button(n) ->
                                     Pump.button(n,p);
                                     idx := 7
               ,
                T.mk_NozzleUp(b) ->  Pump.nozzleUp(b, p);
                                     idx := 8
               ,
                T.mk_Filling(b)  ->  Pump.filling (b, p);
                                     idx :=  9
               ,

                T.mk_Filled(r)   ->  Pump.filled (r, p);
                                     idx := 10
               ,
                T.mk_CycleEnd(b) ->  Pump.cycleEnd (b,p);
                                     idx := 11
               ,
                T.mk_Paid(b)     ->  Pump.paid (b,p);
                                     idx := 12
               ,
                T.mk_FillStart(b)->  Pump.fillStart (b, p);
                                     idx := 13
               ,
                T.mk_Limit(T.mk_Gas(r,b)) ->     -- команда задает два
                                                 -- значения
                                                 -- кнопку и кол-во горючего
                                     Pump.setLimit (r,p);
                                     Pump.setPos   (b,p);
                                     idx :=  14
               ,
                                     32
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                T.mk_EndWait(b)  ->  Pump.endWait(b,p);
                                     idx := 15
               ,
                T.mk_Freeze(b)   ->  Pump.freeze(b,p);
                                     idx := 16
               ,
                T.mk_Restart(b)   -> Pump.restart(b,p);
                                     idx := 17
               ,
                T.mk_Error(b)   ->   Pump.error(b,p);
                                     idx := 18
               ,

     
     
     2.2.6.2.5.  Использование оператора UPDATE #2




                T.mk_Proportion(b,v) ->
                                     p := Position.uid_pump2id(b, hd p);
                                     Position.proportion(v, p);
                                     idx := 101
                                --
                                -- update Proportion set proportion = :v
                                --     where id in (select id
                                --                  from Proportion
                                --                  where  uid = :b and
                                --                         pump = :p
                                --                 )
                                --
               ,
                T.mk_EOG(b, v)   ->
                                     p := Position.uid_pump2id (b, hd p);
                                     Position.eog(v,  p);
                                     idx := 102
               ,
                T.mk_Tank(b, t1, t2) ->
                                     p := Position.uid_pump2id(b, hd p);
                                     Position.tank1(t1,  p);
                                     Position.tank2(t2,  p);
                                     idx := 103
               ,
                T.mk_Mark(b,v)   ->
                                     p := Position.uid_pump2id(b, hd p);
                                     Position.mark(v,   p);
                                     idx :=  104
               ,
                T.mk_Price(b, v) ->
                                     p :=  Position.uid_pump2id(b, hd p);
                                     Position.price( v,  p);
                                     idx := 105
--             ,
                                     33
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

--              _            ->      skip
                end
            end;
            T.mk_Indicator(cnt,
                                 idx,
                                  if p~={}then hd p else T.notFound end,
                                   g_s)
          end
        end
end




     
     
     2.2.6.3.  Описание таблицы типа TPump.


     Этот  текст  непосредственно  должен  конвертироваться   в   SQL-скрипт
генерации БД. Так как RSL по умолчанию  не  создает  функции  именения  поля
необходимо для полей которые  можно  редактировать  в  таблице  надо  задать
функции изменения поля. Они являются аналогом SQL - оператора

UPDATE Pump SET xxxx=yyyyy WHERE id in {ks}


                                  Примечание
     
     Возможно, что так как в SQL редактирование разрешено по умолчанию,
     то надо создать новый тип в RSL  (или  как  -  то  параметризовать
     Short Record Definition), для которого  генерировать  эти  функции
     автоматически. И, только, в случае  явного  запрета  редактировать
     поля не генерировать их.

     Тип создается на основе типа обьявленного в RSL - схеме Relation. Схема
параметризуется  подчиненной  таблицей  типа  TPosition.  Показано,  что   в
SQL-скрипте создания подчиненной таблицы должно появится обьявление внешнего
ключа внешнего  ключа  (ссылочная  целостность),  ссылающегося  на  поле  id
главной таблицы типа TPump. Кроме того, операция удаления строчки в  главной
таблице должна вызывать каскадное удаление строчек в подчиненной таблице.


T
,Relation                       -- ST - slave table
scheme TPump  ( ST: Relation(T{Position for record}) )
    =
                                -- запись record заменил на запись Pump
                                -- теперь можно редактировать поля
    extend   hide hideDelete in   use hideDelete for delete in
                 Relation (T {Pump for record} ) with
                                --
                                --
    class
                                     34
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    value
        --
        --  функции изменения полей (аналог update)
        --

        uid    : Nat  >< Key-set -> write tbl, sqlCode Unit
        uid    (b, ks) is set_int  (b, ks, T.uid)
       ,
        onLine : Bool >< Key-set -> write tbl, sqlCode Unit
        onLine (b, ks) is set_bool (b, ks, T.onLine)
       ,
        start  : Text >< Key-set -> write tbl, sqlCode Unit
        start  (b, ks) is set_text (b, ks, T.start)
       ,
        total  : Real >< Key-set -> write tbl, sqlCode Unit
        total  (b, ks) is set_real (b, ks, T.total)
       ,
        measure : Text >< Key-set -> write tbl, sqlCode Unit
        measure (b, ks) is set_text (b, ks, T.measure)
       ,
        nPoss   : Nat >< Key-set -> write tbl, sqlCode Unit
        nPoss   (b, ks) is set_int (b, ks, T.nPoss)
       ,
        freeFill: Bool >< Key-set -> write tbl, sqlCode Unit
        freeFill(b, ks) is set_bool (b, ks, T.freeFill)
       ,


        query  : Text >< Key-set -> write tbl, sqlCode Unit
        query  (b, ks) is set_text (b, ks, T.query)
       ,
        button  : Nat >< Key-set -> write tbl, sqlCode Unit
        button  (b, ks) is set_int (b, ks, T.button)
       ,
        nozzleUp  : Bool >< Key-set -> write tbl, sqlCode Unit
        nozzleUp  (b, ks) is set_bool (b, ks, T.nozzleUp)
       ,
        filling  : Bool >< Key-set -> write tbl, sqlCode Unit
        filling (b, ks) is set_bool (b, ks, T.filling)
       ,
        filled  : Real >< Key-set -> write tbl, sqlCode Unit
        filled  (b, ks) is set_real (b, ks, T.filled)
       ,
        cycleEnd : Bool >< Key-set -> write tbl, sqlCode Unit
        cycleEnd(b, ks) is set_bool (b, ks, T.cycleEnd)
       ,
        paid     : Bool >< Key-set -> write tbl, sqlCode Unit
        paid    (b, ks) is set_bool (b, ks, T.paid    )
       ,



        fillStart: Bool >< Key-set -> write tbl, sqlCode Unit
        fillStart(b, ks) is set_bool (b, ks, T.fillStart)
                                     35
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

       ,
        setPos  : Nat >< Key-set -> write tbl, sqlCode Unit
        setPos  (b, ks) is set_int (b, ks, T.setPos)
       ,
        setLimit: Real >< Key-set -> write tbl, sqlCode Unit
        setLimit(b, ks) is set_real (b, ks, T.setLimit)
       ,
        endWait : Bool >< Key-set -> write tbl, sqlCode Unit
        endWait (b, ks) is set_bool (b, ks, T.endWait)
       ,
        freeze  : Bool >< Key-set -> write tbl, sqlCode Unit
        freeze  (b, ks) is set_bool (b, ks, T.freeze)
       ,
        restart : Bool >< Key-set -> write tbl, sqlCode Unit
        restart (b, ks) is set_bool (b, ks, T.restart)
       ,

        error   : Text >< Key-set -> write tbl, sqlCode Unit
        error   (b, ks) is set_text (b, ks, T.error)
       ,
        --
        -- поля для оператора Update закончились
        --




     Необходимо уметь задавать умолчательные значения поля таблицы  и  уметь
показать эти значения программисту.

     Перегруженная функция insert содержит эти значения.

     Функция uid2id  является  примером  применения  функции  where  обьекта
Relation.

        insert  : Nat -> write tbl, sqlCode, identity Unit
        insert  (uid) is
            insert ( T.mk_Pump (uid, false, timeStamp(), 0.0,
                                                  "litre", 0, false,
                              0, false, false, 0.0, false, false,
                              false, false, 0, 0.0, false, false,
                              "", timeStamp()
                             )
                   )
       ,
        uid2id : Nat -> write tbl, sqlCode
                        Key-set
        uid2id ( u) is where ( -\p:T.Pump:- T.uid(p) = u )



     Перегруженная функция delete должна  выполнять  каскадное  удаление  ()
записей в подчиненной таблице. Перегруженная операция delete
        alter table Position
                                     36
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

          add  constraint pos_pmp_fk
          foreign key (pump) references Pump(id)
          ON DELETE CASCADE;
является часть этого оператора alter Table. В  действительности  она  задает
фразу "ON DELETE CASCADE".


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

       ,
        delete :  Key-set               ->  write ST.any, tbl, sqlCode
                                     Unit

        delete (kPmps) is        --  delete from ST where pump in :kPmps

              ST.delete(  {kPos | kPos: T.Key      :-
                                T.pump(ST.tbl(kPos)) isin kPmps
                          }
                      );


              hideDelete(kPmps)

    axiom


     Аксиома задает ограничение UNIQUE для поля uid.

      [uid_unique]
        unique (-\ (x,y): T.Pump >< T.Pump :- T.uid (x) = T.uid(y))
--        all x, y: Key :-
--                  {x,y} <<= dom tbl  /\ T.uid(tbl(x)) = T.uid(tbl(y))
--                      =>
--                        x = y
     ,


      [measure]
        check (-\ r: T.Pump :- T.measure(r) isin { "litre", "gallon"} )



    end




                                     37
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     2.2.6.4.  Описание таблицы типа TPosition.


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



T
,Relation
scheme TPosition ( R:  class type
                                record,
                                relation = Nat -m-> record
                             variable
                                tbl : relation
                       end
                 )
      =

    extend  Relation ( T {Position for record} ) with
                                -- запись record заменил на запись Pump
                                -- теперь можно редактировать поля
    class
    value
        uid    : Nat  >< Key-set -> write tbl, sqlCode Unit
        uid    (b, ks) is set_int  (b, ks, T.uid)
       ,
        price  : Real >< Key-set -> write tbl, sqlCode Unit
        price  (b, ks) is set_real (b, ks, T.price)
       ,
        mark  : Text >< Key-set -> write tbl, sqlCode Unit
        mark  (b, ks) is set_text (b, ks, T.mark)
       ,
        tank1   : T.TTank >< Key-set -> write tbl, sqlCode Unit
        tank1   (b, ks) is set_int (b, ks, T.tank1)
       ,
        tank2   : T.TTank >< Key-set -> write tbl, sqlCode Unit
        tank2   (b, ks) is set_int (b, ks, T.tank2)
       ,
        eog : Bool >< Key-set -> write tbl, sqlCode Unit
        eog (b, ks) is set_bool (b, ks, T.eog)
       ,
        proportion   : Nat >< Key-set -> write tbl, sqlCode Unit
        proportion   (b, ks) is set_int (b, ks, T.proportion)
       ,

--        это поле я не разрешаю редактировать после создания

--        pump   : Nat >< Key-set -> write tbl, sqlCode Unit
--        pump   (b, ks) is set_int (b, ks, T.pump)
--       ,

--        uid2id : Nat -> write tbl, sqlCode        -- лишняя функция
                                     38
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

--                        Key-set
--        uid2id ( u) is where ( -\p:T.Position:- T.uid(p) = u )
--       ,
        insert  : Nat >< Key -> write tbl, sqlCode, identity Unit
        insert  (uid, p) is
            insert ( T.mk_Position (
                           uid, 0.0, "", 0, 0, false, 0, p
                      )
                   )
       ,

        uid_pump2id : Nat >< Nat -> write tbl, sqlCode
                        Key-set
        uid_pump2id ( u, pmp) is
            where ( -\p:T.Position:-
                       T.uid(p) = u /\ T.pump(p) = pmp
                  )
       ,
        foo    : Nat -> write  tbl ,  sqlCode   Unit
    axiom

      [uid_pump_unique]   -- (uid, pump ) is unique
        unique (-\ (x,y): T.Position >< T.Position :-
                                 T.uid (x) = T.uid(y) /\
                                 T.pump(x) = T.pump(y)
                )

--        all x, y: Key :-
--                  {x,y} <<= dom tbl  /\
--                             T.uid(tbl(x)) = T.uid(tbl(y)) /\
--                             T.pump(tbl(x)) = T.pump(tbl(y))
--                        =>
--                        x = y
     ,




     Аксиома задает большую часть будущего DDL - оператора

        alter table Position
          add  constraint pos_pmp_fk
          foreign key (pump) references Pump(id)
          ON DELETE CASCADE;

В действительности она задает все кроме фразы "ON DELETE CASCADE".



      [primary_pump]      --  pump must be exist
      all pos  : T.Position :- pos isin rng tbl
                        =>
                        T.pump(pos) isin dom R.tbl

                                     39
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    end



     
     
     2.2.6.5.  Описание нового типа данных Relation.


     На  произвольном  типе  данных  (type  record)   задана   таблица   как
отображение из целых  чисел  в  record.  Введены  операции  insert,  delete,
select,  update.  Операция  update  изменяет  всю  запись  целиком.  Функции
set_xxxx будут использоваться в функциях обновления поля позже, когда запись
начнет иметь поля (то  есть  на  основе  абстрактного  типа  Relation  будет
построен конкретный тип для некоторой таблицы, например, TPump).

     Функции check и unique представляют собой аналоги соответствующих  фраз
CHECK и UNIQUE оператора CREATE TABLE.


db_start
--,rel

scheme Relation ( R:  class type record  end) =
    hide hDefined in
    extend db_start with
    class
        type
            record   = R.record,
            relation = Nat -m-> record
        variable
            tbl      : relation
        value
            garbage: record,
                                   -- функция для проверки ограничений
                                   -- целостности

            check : (record -> Bool) -> read tbl Bool
            check (p) is
               ( all x : Key :- x isin dom tbl => p(tbl(x)) )
           ,
                                   -- функция для проверки ограничения
                                   -- unique

            unique : ((record >< record) -> Bool) -> read tbl Bool
            unique (p) is
               ( all x, y  : Key :- {x,y} <<= dom tbl  =>
                         ( p(tbl(x), tbl(y)) => x = y )
               )
           ,

                                   -- аналог операции Insert

            insert :  Key >< record   ->  write tbl, sqlCode, identity
                                     40
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                                         Unit
            insert (k, r) is
                if ~hDefined(k) then
                    tbl := tbl !! [k +> r];
                    sqlCode  :=Ok;
                    identity := k
                else
                    sqlCode  := Err;
                    identity := k
                end
           ,
            insert :         record   ->  write tbl, sqlCode, identity
                                         Unit
            insert (   r) is  insert (autoInc(dom tbl), r)
           ,

                                   --  аналог операции Delete

            delete :  Key-set           ->  write tbl, sqlCode
                                         Unit
            delete (k) is
                if hDefined(k) then
                    tbl     := tbl \ k;
                    sqlCode :=  Ok
                else
                    sqlCode := notFound
                end
           ,

            delete :  Unit           ->     write tbl, sqlCode
                                         Unit
            delete () is
                delete (dom tbl)
           ,

                                   -- аналог  операции Update

            update :  Key >< record   -> write tbl, sqlCode Unit
            update (k, r)  is
                if hDefined(k) then
                    tbl := tbl !! [k +> r];
                    sqlCode  :=Ok
                else
                    sqlCode  := Err
                end
           ,
                                   -- аналог операции Select

            select:  Key               ->   read tbl
                                            write sqlCode
                                         record
            select (k)  is
                if hDefined (k) then
                    sqlCode := Ok;
                                     41
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                    tbl(k)
                else
                    sqlCode := notFound;
                    garbage
                end
           ,
                                   -- вспомогательная
                                   -- функция where используется для
                                   -- построения функций, отображающих
                                   -- некоторые наборы полей в первичные
                                   -- ключи. может использовться как
                                   -- фраза where языка SQL

            where: (record -> Bool)  -> read tbl
                                         Key-set
            where (p) is
                {x| x: Key :- p(tbl(x))}
           ,

            hDefined: Key             ->
                                         read tbl
                                         Bool
            hDefined (k) is k isin dom tbl
           ,
            hDefined: Key-set         ->
                                         read tbl
                                         Bool
            hDefined (k) is    k inter dom tbl  ~= {}
           ,


            set_text : Text >< Key >< (Text >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
                                            -- s_f - функция, которая
                                            --       меняет поле в записи
            set_text  (fld, k,  s_f)  is
                        update(k,           --  заменить запись на новую
                            s_f(fld,        --  изменить поле
                                select(k)   --  взять запись
                            )
                        )
           ,

            set_text : Text >< Key-set >< (Text >< record -> record)
                                            ->    write tbl, sqlCode
                                                  Unit
            set_text  (fld, ks, s_f)  is
                if ks ~= {} then
                  let k = hd ks in
                    set_text (fld, k, s_f);
                    set_text (fld, ks \ {k}, s_f)
                  end
                end
                                     42
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

           ,
            set_int : Int >< Key >< (Int >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
            set_int  (fld, k, s_f)  is
                        update(k, s_f(fld, select(k)))
           ,
            set_int : Int >< Key-set >< (Int >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
            set_int  (fld, ks, s_f) is
                if ks ~= {} then
                  let k = hd ks in
                    set_int (fld, k, s_f);
                    set_int (fld, ks \ {k}, s_f)
                  end
                end
           ,

            set_real : Real >< Key >< (Real >< record -> record)
                                      ->  write tbl, sqlCode
                                          Unit
            set_real  (fld, k, s_f)  is
                        update(k, s_f(fld, select(k)))
           ,
            set_real : Real >< Key-set >< (Real >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
            set_real  (fld, ks, s_f) is
                if ks ~= {} then
                  let k = hd ks in
                    set_real (fld, k, s_f);
                    set_real (fld, ks \ {k}, s_f)
                  end
                end
           ,
            set_char : Char >< Key >< (Char >< record -> record)
                                      ->  write tbl, sqlCode
                                          Unit
            set_char  (fld, k, s_f)  is
                        update(k, s_f(fld, select(k)))
           ,
            set_char : Char >< Key-set >< (Char >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
            set_char (fld, ks, s_f) is
                if ks ~= {} then
                    let k = hd ks in
                        set_char (fld, k, s_f);
                        set_char(fld, ks\{k}, s_f)
                    end
                end

           ,
                                     43
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

            set_bool : Bool >< Key >< (Bool >< record -> record)
                                      ->
                                        write tbl, sqlCode
                                        Unit
            set_bool  (fld, k, s_f)  is
                        update(k, s_f(fld, select(k)))
           ,
            set_bool : Bool >< Key-set >< (Bool >< record -> record)
                                      ->   write tbl, sqlCode
                                           Unit
            set_bool  (fld, ks, s_f) is
                if ks ~= {} then
                    let k = hd ks in
                        set_bool (fld, k, s_f);
                        set_bool(fld, ks\{k}, s_f)
                    end
                end
    end

     
     
     2.2.7.  Описание работы менеджера драйверов

not ready
     
     
     2.2.8.  Описание работы драйверов контроллеров

not ready
     
     
     2.2.9.  Описание работы имитатора контроллера

not ready
     
     
     2.2.10. Описание работы оператора

not ready

                                     44
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




                        3.  РУКОВОДСТВО ПРОГРАММИСТА


     
     
     
     
     3.1.  СХЕМА РЕЛЯЦИОННЫХ СВЯЗЕЙ GSAU




     Схема реляционных связей достаточно  проста.  Она  соединяет  две  пары
таблиц БД отношением один ко многим.

  Pump                             Position
   id     <-------                 id
   uid            |                 uid
   onLine         |                 price
   start          |                 mark
   total          |                 tank1
   measure        |                 tank2
   nPoss          |                 eog
   freeFill       |                 proportion
   button         \---------------  pump
   nozzleUp
   filling       one (Pump) to many (Position)
   filled
   cycleEnd
   paid
   fillStart
   setPos
   setLimit
   endWait
   freeze
   restart
   error
   query

     
     
     
     
     3.2.  ВНУТРЕННЯЯ СХЕМА БАЗЫ ДАННЫХ GSAU



     Таблицы Cmd4Pmp и Cmd4Pos, служащие для передачи команд от оператора  к
насосам, не включаются  в  документ,  так  как  они  полностью  совпадают  с
таблицами Pump и Position.

                                     45
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     3.2.1.  Based datatypes


     Don't pay attention to aux columns. It is only the technical  trick  to
avoid a blocking of a table during of a multyuser work in a LAN.
     
     
     3.2.1.1.  Meassure


     В специфакации было задано ограничение на единицу измерения бензина.



//drop table GSAU.TMeassure;

create                                      // short symonym
table GSAU.TMeassure (                            // tsz
  id       unsigned
             integer not null
                default _AUTOINCREMENT,     //
  aux    TAux,
  name   TName,  //unique,             // nm
  note   TNote,             //
  primary key (id)
);
//

//revoke all  on gsau.Meassure from GSAU;
grant all on gsau.TMeassure to GSAU;
revoke update on gsau.TMeassure from GSAU;
revoke delete, update on gsau.TMeassure from GSAU;
grant update(aux) on gsau.TMeassure to GSAU;


insert into gsau.TMeassure(id, name)
 values (0,  'gallon');
insert into gsau.TMeassure(id, name)
 values (1, 'litre');
commit;



     
     
     3.2.1.2.  Pump





//drop table GSAU.Pump;

                                     46
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

create
table GSAU.Pump (
  id        ulong not null
                default _AUTOINCREMENT,
  aux       TAux,
  uid       TUid,
  onLine    TNoYes,
  start_     datetime not null default timestamp,
  total     TQtty,
  meassure  TMeassure,   // it is not char(xx) type becouse
                        //  my interface library support only ulong
                        // as a foreign key
  nPoss     ulong not null default 0,
  freeFill  TNoYes,
  button    ulong not null default 0,
  nozzleUp  TNoYes,
  filling   TNoYes,
  filled    TNoYes,
  cycleEnd  TNoYes,
  paid      TNoYes,
  fillStart TNoYes,
  setPos    ulong not null default 0,
  setLimit  TQtty,
  endWait   TNoYes,
  freeze    TNoYes,
  restart   TNoYes,
  error     TNote,
  query     datetime default current timestamp,
  primary key (id)
);
//

//revoke all  on gsau.Pump from GSAU;
grant all on gsau.Pump to GSAU;
--revoke update on gsau.Pump from GSAU;
--revoke delete, update on gsau.Pump from GSAU;
--grant update(aux) on gsau.Pump to GSAU;



     
     
     3.2.1.3.  Position





//drop table GSAU.Position;

create
table GSAU.Position (
  id        ulong not null
                default _AUTOINCREMENT,
                                     47
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

  aux       TAux,
  uid       TUid,
  price     TQtty,
  mark      TSName,   // it is not char(xx) type becouse
                        //  my interface library support only ulong
                        // as a foreign key
  tank1     ulong not null default 0
      CHECK (tank1 >=0 and tank1 <= 2),
  tank2     ulong not null default 0
      CHECK (tank2 >=0 and tank2 <= 2),
  eog       TNoYes,
  proportion ulong not null default 0
      CHECK (proportion >=0 and proportion <= 100),
  pump      ulong not null, // you can't edit pump
  primary key (id),
  unique (uid, pump)

);
//

//revoke all  on gsau.Position from GSAU;
grant all on gsau.Position to GSAU;
revoke update on gsau.Position from GSAU;
grant update( aux, uid, price, mark, tank1, tank2, eog, proportion)
                     on gsau.Position to GSAU;
--revoke delete, update on gsau.Position from GSAU;

alter table gsau.Position
  add  constraint pos_pmp_fk
  foreign key (pump) references gsau.Pump(id)
  ON DELETE CASCADE;


     
     
     
     
     3.3.  MAKEFILEs



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

     Параметры для утилиты make задаются в  файле  gsau/pars.mk.  Переменные
среды для корректной работы утилиты  make,  в  случае  установленной  ViSual
Studio, в первых строчках скрипта gsau/mk.bat

     Для построения (перед выполнение бат файла надо зайти в соответствующий
каталог) :
        
     a) базы данных - gsau/main/db.mk. Вызов -
        
                                     48
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

        mk.bat foo
        
        Результат - построенная БД gsau/main/foo.db, промежуточные  файлы  -
        скрипты генерации в gsau/bld/*.sql;
        
     b) библиотеки - gsau/crtdll.mk. Вызов -
        
        mk.bat gsau
        
        Результат   -    построенные    библиотеки    gsau/bld/gsau.dll    и
        gsau/bld/gsau.lib, промежуточные файлы - структуры  обмена  (sde)  в
        gsau/bld/x/*.cpp и *.;
        
     c) выполняемого файла - gsau/t_x.mk. Вызов -
        
        mk.bat t_gsau
        
        Результат - построенный выполняемый файл gsau/bld/t_gsau.exe;
        
     d) документации - gsau/docs/ascii/ascii_doc.mk. Вызов -
        
        mk.bat
        
        Результат - построенная документация gsau/docs/ascii/bld/gsau.txt;


                                  Примечание
     
     Для  построения  скриптов  используется  утилита  sed.exe  (смотри
     каталог gsau/sed).
     
     Для построения библиотеки используется утилита u_mkSDE.exe
     
     Для  построения  документации  используется  форматер  plain  text
     файлов - rio.exe
     
     
     3.3.1.  Зависимости от других проектов


     Список хедеров и библиотек, от которых зависит данный проект  находится
в файле GSAU/cp_lib.bat.
     
     
     
     
     3.4.  ОПИСАНИЕ СТРУКТУР ОБМЕНА ГЕНЕРИРУЕМОГО ИНТЕРФЕЙСА



     Структура обмена данными (Structure of DataBase Exchange - sde )  между
приложением и БД есть ключевой обьект библиотеки  интерфейса  с  БД  -  ASAI
(старая версия - DBI3) [4]

                                     49
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     Эти обьекты позволяют

     - с одной стороны - выполнять все 4 операции над таблицей  SQL  сервера
(delete, insert, update, select) из приложения, написанного на C;

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

     Важным  свойством  библиотеки  является  наличие  генератора   структур
u_mkSDE.exe, который позволяет создавать структуры обмена для каждой таблицы
прямо из SQL - скриптов генерации БД.

     Для кажной таблицы (Foo - имя таблицы, содержится в файле gsau/src/Foo)
создается  своя  структура  обмена  (GSAU_RFoo  -  имя  структуры,   которая
содержится  в  файлах  gsau/bld/x/Foo.cpp  и  gsau/bld/x/Foo).  Каждое  поле
структуры (кроме ключевого) соответствует одноименной колонке таблицы.

     Хедеры с описанием структур обмена подключаются файлом gsau/mkSDE.h
     
     
     
     
     3.5.  ОПИСАНИЕ ВЫСОКОУРОВНЕГО ИНТЕРФЕЙСА С БД


     
     
     3.5.1.  Хедер макросов и констант




#include <stdio.h>

# ifndef  __GSAUDEF_H
# define  __GSAUDEF_H
//

#ifdef GSAUEXP
#define GSAU_API __declspec(dllexport)
#else
#define GSAU_API __declspec(dllimport)
#endif


# define GSAU_NAME    "gsau"

# define GSAU_VERSION  "gsau-00.90.07"


extern const char  * GSAU_version;

# define GSAU_UID_SZ 32
                                     50
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02



# include "put_get.h"
//# include "mkSDE.h"



     
     
     3.5.1.1.  Command/State Indicator


     Описание структуры подключается в файле mkSDE.h





struct GSAU_RIndicator;
typedef GSAU_RIndicator GSAU_StateIndicator;
typedef GSAU_RIndicator GSAU_CommandIndicator;


     
     
     3.5.1.2.  Command/State


     При  попытке  полностью  придерживаться  RSL-  метода   и   ДОКАЗЫВАНИЯ
корректности построенного приложения, для записей  Command/State  необходимо
было бы построить глубоко вложенные С++ обьекты и  написать  массу  программ
для конвертирования из одного обьекта в другой. Я не  вижу  никакого  резона
заниматься этим в данном проекте. Сложные структуры моделируются типом  char
* с "интуитивно - понятным" содержанием. ( ))))))))) )





typedef char * GSAU_State;
typedef char * GSAU_Command;




     Названия  макросов  отражают  слабую  попытку  помочь   "интуитивно   -
понятной"   интерпертации   конструирования   из    составных    частей    /
деконструирования на составные части обьектов State, Command.





#define GSAU_mk_State      "State"
                                     51
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


#define GSAU_mk_Online     "Online"
#define GSAU_mk_Start      "Start"
#define GSAU_mk_Total      "Total"
#define GSAU_mk_Meassure   "Meassure"
#define GSAU_mk_NPos       "NPos"
#define GSAU_mk_FreeFill   "FreeFill"
#define GSAU_mk_Button     "Button"
#define GSAU_mk_NozzleUp   "NozzleUp"
#define GSAU_mk_Filling    "Filling"
#define GSAU_mk_Filled     "Filled"
#define GSAU_mk_CycleEnd   "CycleEnd"
#define GSAU_mk_Paid       "Paid"
#define GSAU_mk_FillStart  "FillStart"
#define GSAU_mk_Limit      "Limit"
#define GSAU_mk_EndWait    "EndWait"
#define GSAU_mk_Freeze     "Freeze"
#define GSAU_mk_Restart    "Restart"
#define GSAU_mk_Error      "Error"
#define GSAU_mk_Position   "Position"
#define GSAU_get_set       "get_set"

#define GSAU_mk_Proportion "Proportion"
#define GSAU_mk_EOG        "EOG"
#define GSAU_mk_Mark       "Mark"
#define GSAU_mk_Price      "Price"

#define GSAU_tank1         "tank1"
#define GSAU_tank2         "tank2"
#define GSAU_pump          "pump"

# endif


     
     
     3.5.2.  Хедер основных обьектов системы



#include <stdio.h>

# ifndef  __GSAU_H
# define  __GSAU_H
//

# if !defined(__ASAI_H)
# include  "asai.h"
# endif

# if !defined(__DBI_U_H)
# include  "dbi_u.h"
# endif

                                     52
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

# if !defined(__GSAUDEF_H)
# include  "gsaudef.h"
# endif


typedef class GSAU_DBI {
    char             buf [_BIGBUF_SZ + 1];

public:
    ASAI_TDB *       database;
    x_bool   debug;

    GSAU_DBI (
       ASAI_TDB  *     db
    ) {
        database = db;
        debug    = false;
        *buf     = 0;
    }

    ~GSAU_DBI  (){
        database = 0;
        debug    = false;
        *buf     = 0;
    }

    inline int print(const char * _me, const char * format, ...) const {
        int rc = 0;
        if (debug)  {
            rc = x_printf ("\n++ %s: ",  _me );
            va_list ap;
            va_start (ap, format);
            rc += x_vprintf (format, ap);
        }
        return rc;
    }
                                                 // user - pump - direction


----

 get:        T.CommandIndicator      ->
                         write
                             Pump.any, Position.any,
                             Cmd4Pmp.any,  Cmd4Pos.any

                         T.Command
----




    friend GSAU_API const GSAU_Command
    GSAU_getCmd (
                                     53
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

        const GSAU_DBI              * db,
        const GSAU_CommandIndicator * ci
    )
    ;
    const GSAU_Command
    getCmd (
        const GSAU_CommandIndicator * ci
    )
    {
        return GSAU_getCmd(this, ci);
    }




----

 put:        T.Command >< Nat ->     -- client number
                         write  Pump.any, Position.any,
                                Cmd4Pmp.any,  Cmd4Pos.any
                         T.CommandIndicator

----



    friend GSAU_API  GSAU_CommandIndicator *
    GSAU_putCmd (
        const GSAU_DBI              * db,
        const GSAU_Command            c,
        const ulong                   n
    )
    ;
    GSAU_CommandIndicator *
    put (
        const GSAU_Command            c,
        const ulong                   clientNo = 0
    )
    {
        return GSAU_putCmd(this, c, clientNo);
    }
                                                 // pump - user - direction

----

 get:        T.StateIndicator      ->
                       write Pump.any,
                             Position.any
                       T.State

----


    friend GSAU_API const GSAU_State
                                     54
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    GSAU_getStt (
        const GSAU_DBI              * db,
        const GSAU_StateIndicator   * si
    )
    ;
    const GSAU_State
    getStt (
        const GSAU_StateIndicator * si
    )
    {
        return GSAU_getStt (this, si);
    }


----

 put:      Bool >< T.State  >< Nat
           ->               -- выводить состояние можно на всякий
                       write  --State.any,  -- надо изменить строчку либо в
                         Pump.any,
                         Position.any
                       T.StateIndicator  -- таблице Position, либо в Pump

----



    friend GSAU_API  GSAU_StateIndicator *
    GSAU_putStt (
        const GSAU_DBI              * db,
        const x_bool                  g_s,
        const GSAU_State              stt,
        const ulong                   cnt
    )
    ;
    GSAU_StateIndicator *
    put (
        const x_bool       g_s ,
        const GSAU_State   stt,
        const ulong        cnt  = 0
    )
    {
        return  GSAU_putStt (this, g_s, stt, cnt);
    }



}
GSAU_DBI;


# endif


                                     55
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     
     
     
     3.6.  ФУНКЦИИ КОНСТРУИРОВАНИЯ/ДЕКОНСТРУИРОВАНИЯ COMMAND/STATE


not ready



# ifndef  __GSAU_STT_H
# define  __GSAU_STT_H
//

# if !defined(__GSAU_H)
# include  "gsau.h"
# endif






# endif


                                     56
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




               4.  ИСПОЛЬЗОВАНИЕ И ПРОВЕРКА РАБОТОСПОСОБНОСТИ



     Все примеры подразумевают, что задачи будут  пытаться  присоединится  к
умолчательному серверу по любому доступному протоколу.

     пример запуска сервера (версия Sybase Anywhere 7.x) с именем fv:

dbeng7.exe -n fv c:\gsau/main/foo.db


     Подготовлен набор тестов для проверки всего пути преобразования данных:

     1) от    оператора    к    TCPSender-у:    команда     +>     индикатор
(bld/t_putCmd1.bat);

     2) от  TCPReciever-а  к   драйверу   насоса:   индикатор   +>   команда
(bld/t_getCmd2.bat);

     3) от  драйвера  насоса   к   UDPSender-у:   состояние   +>   индикатор
(bld/t_putStt3.bat);

     4) от   UPDReciever-а   к    оператору:    индикатор    +>    состояние
(bld/t_getStt4.bat).

     Батч - файлы содержат вызовы тестирующей  программы  с  подготовленными
параметрами в командной строке. В связи с большим  количеством  тестов,  там
могут  содержатся  неточности.  сорри.  Главная  идея  такая   -   результат
выполнения команды из нечетного (xxxx1.bat или xxxx3.bat) должен быть  подан
на  вход  к  команде  из  соответствующего  четного  файла  (xxxx2.bat   или
xxxx4.bat).
     
     
     
     
     4.1.  ВЫПОЛНЕНИЕ ТЕСТИРУЮЩЕЙ ПРОГРАММЫ


     
     
     4.1.1.  the put/get command/state/indicator

 the put/get command/state/indicator
usage:
t_put_get cnnParm;dbg cmd;record >output
	 whre
 cnnParm is like eng=outtrak;uid=dba;pwd=sql
 cmd isin {cmd, ci, stt, si}
 cmd : to pass command of client and to recieve command indicator
 ci  : to pass command indicator and to recieve command
                                     57
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

 stt : to pass state of pump and to recieve state indicator
 si  : to pass state indicator and to recieve state
	 and ci;record is like ci;index_=zzz;id_=yyy;set_get={false|true}
	 and si;record is like si;index_=zzz;id_=yyy;set_get={false|true}
     
     
     
     
     4.2.  ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ ВЫСОКОУРОВНЕВОГО ИНТЕРФЕЙСА С БД





#include <time.h>
#include "gsau.h"
#include "mkSDE.h"

# define _NM "t_put_get"
# define _FNM "the put/get command/state/indicator"

typedef enum rec {
    nothing,
    cmd   ,
    ci    ,
    stt   ,
    si
}
rec;

main(int argc, char * argv[])
{
long rc = 0;
char  *po = 0, *pars = 0;
char crtdef[_BUF_SZ+1];
strcpy(crtdef, ASAI_USER);
crtdef[strlen(crtdef)-1]=0;// to remove .

if (argc > 2) {
    clock_t st, fi;
    char separator = 0;
    char buf [_BUF_SZ + 1]  ;

    TBool  debug1, debug2, check;
    rec whatToDo = nothing;
    if (*argv[1] == '?')
        goto usage;
    if(x_parmValue (buf, _BUF_SZ, argv[1], "-?", ';')==_OK)
        goto usage;
      {
            TDouble foo;
            x_printf("\n %s, val=%s/%g", foo.toDbg(buf), foo.toStr(),
                                                                   foo.v);
            pars = argv[2];
                                     58
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


            foo.strTo(pars, _equalAdd(GSAU_mk_Total, buf));
            x_printf("\n %s, val=%s/%g", foo.toDbg(buf), foo.toStr(),
                                                                   foo.v);
            exit(1);
            }


    //pars
    pars = argv[1];
    debug1.strTo ( pars, "dbg");
    pars = argv[2];
    debug2.strTo ( pars, "dbg");
    if (check.isHere(pars,      "cmd", buf, _BUF_SZ) ==_OK)
        whatToDo = cmd;
    else if (check.isHere(pars, "ci",  buf, _BUF_SZ) ==_OK)
        whatToDo = ci;
    else if (check.isHere(pars, "stt", buf, _BUF_SZ) ==_OK)
        whatToDo = stt;
    else if (check.isHere(pars, "si",  buf, _BUF_SZ) ==_OK)
        whatToDo= si;
    check.strTo ( pars, GSAU_get_set); // i have to remove some records

    if (whatToDo != nothing) {
        printf("\n// %s have been started, debug1/debug2 is %s/%s",
                  _NM, x_bool((x_bool)debug1), x_bool((x_bool)debug2));
        st = clock();
        po = "init";
//
//        to initialize Sybase ASA Intreface
//
        ASAI_TDB  db (argv[1], (x_bool) debug1, (x_bool) debug1);
        rc = db.err;
        if (rc == _OK) {
//
//        to create object of high level access to database
//
            GSAU_DBI  gsau(&db);

            gsau.debug = debug2.v;
            GSAU_RIndicator * i = 0;
            switch (whatToDo) {
            case cmd:
                po = "cmd";
                if((x_bool) check ) {
//
//        to create SDE for usage of table  gsau.Cmd4Pmp
//
                    GSAU_RCmd4Pmp  Cmd4Pmp  ((ASAI_TDB *)gsau.database);
                    Cmd4Pmp.Delete();
                }
//
//        to put a command of operator into database and get command
//                                                             indicator
                                     59
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

//
                i = gsau.put(pars);
                if (i) {
                         // indicator o
                         //       include to exchange
                         //                  all the indicators
                    i->inds(true, SDE_A_fld);
//
//        to show a command indicator
//
                    i->toStr(buf, _BUF_SZ);
                    x_printf("\n// %s: command indicator is %s", _NM, buf);
                    delete i;
                }
                else {
                    rc = _ERR;
                    x_printf("\n// %s: command indicator is empty", _NM);
                }
                break;



            case ci :
                po = "ci";
//
//        in deed i don't use this SDE to exchage a data
//
                i = new GSAU_RIndicator();
                if (i) {
//
//        to get info for indicator from command line
//
                    i->strTo(pars);
//
//        to get a command from database
//
                    x_printf("\n// %s: command is %s", _NM,
                                                        gsau.getCmd(i));
                    delete i;
                }
                else {
                    rc = _ERR;
                    x_printf("\n// %s: command indicator is empty", _NM);
                }
                break;



            case stt:
                check.strTo ( pars, "get_set");
                po = "stt";
                i = gsau.put( (x_bool)check, pars);
                if (i) {
                         // indicator o
                                     60
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                         //       include to exchange
                         //                  all the indicators
                    i->inds(true, SDE_A_fld);
                    i->toStr(buf, _BUF_SZ);
                    x_printf("\n// %s: state indicator is %s", _NM, buf);
                    delete i;
                }
                else {
                    rc = _ERR;
                    x_printf("\n// %s: state indicator is empty", _NM);
                }
                break;



            case si :
                po = "si";
                i = new GSAU_RIndicator();
                if (i) {
                    i->strTo(pars);
                    x_printf("\n// %s: state is %s", _NM, gsau.getStt(i));
                    delete i;
                }
                else {
                    rc = _ERR;
                    x_printf("\n// %s: state indicator is empty", _NM);
                }
                break;
            default:
                po = "default";

            }
        }
        fi = clock();
        printf("\n// %s have been finished after %2.lf secs of work."
             " \n//\trc/position=%d/%s/%s",
                    _NM,
             (double)(fi-st)/ CLOCKS_PER_SEC, rc, ASAI_rc2Txt(rc),po);

        if (rc != _OK)
            fprintf(stderr,"\n// %s: rc/text/position=%d/%s/%s\n", _NM,
                                                  rc, ASAI_rc2Txt(rc), po);
    }
    else {
        printf("\n// %s : nothing to do", _NM);
    }
    return rc;
}
usage:

if (argc > 1 && *argv[1] == '?') {
    printf (
    "\n.3 %s"
    "\n.x SDE"
                                     61
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

    "\n.x %s"
    "\n.n", _FNM, _NM
    );
}



printf ("\n %s", _FNM);
printf ("\nusage:");
printf ("\n%s cnnParm;dbg cmd;record >output", _NM);
printf( "\n\t whre \n cnnParm is like eng=outtrak;uid=dba;pwd=sql" );
printf ("\n cmd isin {cmd, ci, stt, si}");
printf (
"\n cmd : to pass command of client and to recieve command indicator");
printf ("\n ci  : to pass command indicator and to recieve command" );
printf ("\n stt : to pass state of pump and to recieve state indicator");
printf ("\n si  : to pass state indicator and to recieve state");
printf (
"\n\t and ci;record is like ci;index_=zzz;id_=yyy;set_get={false|true}");
printf (
"\n\t and si;record is like si;index_=zzz;id_=yyy;set_get={false|true}");


if (argc > 1 && *argv[1] == '?'){
    printf (
    "\n.f"
    );
}
return -1;
}



                                     62
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




                            5.  НЕКОТОРЫЕ ВЫВОДЫ



     В завершение, поддерживая  тезис  о  том,  что  число  строк  исходного
текста, выдаваемое программистом в час, не зависит от языка программирования
(см. [9] ) , приведем некоторую информацию, о  количестве  строчек,  которое
было потрачено, что бы описать GSAU на языке формальных спецификаций  RSL  и
на языках реализации задачи: С++  и  SQL.  От  себя  хочется  добавить,  что
количество строчек, которое  необходимо  написать  для  решения  какой  либо
задачи, является важной характеристикой языка программирования.


                                  Примечание
     
     Если  наш  подход  по  поводу  использования  RSL   для   описания
     реляционных баз данных был бы  принят,  то  схемы  db_start.rsl  и
     Relation.rsl должны бы быть частью языка RSL. То есть, их не  надо
     было бы учитывать в общей  сумме  строчек.  Кроме  того,  так  как
     большая  часть  схемы  TPump.rsl,  TPosition.rsl  является  просто
     заданием  функций  доступа  к   полю   таблицы,   которые   должны
     существовать по умолчанию, то количество  строчек  в  этих  схемах
     было бы в два раза меньше.

RSL               клиентская      серверная         коментарии
                  часть (С++)     часть (SQL)


db_start.rsl:                      38               не имеет отношения
Relation.rsl:                      227              к текущей задаче

DB.rsl:            690             16
GSAU.rsl:          184
T.rsl:             38
t_GSAU.rsl:        11
TPosition.rsl:                     113
TPump.rsl:                         210
Types.rsl:         270
                   1193            604        1797

        1797 - 38 - 227 = 1532
              1532 - 150      = 1582                пересчитано в
        604  - 38 - 227 = 339                       соответствие с
              339  - 150      = 189                 замечанием 1


  скрипты генерации БД


Cmd4Pmp.sqs:                        50
Cmd4Pos.sqs:                        46
                                     63
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

CRT_ALL.SQS:                        20       +
DROP_STR.SQS:                       25       +
Indicator.sqs:                      29
inidata.sqs:                        45       +
Position.sqs:                       46
Pump.sqs:                           50
types.sqs:                          43



  C++ код, написанный вручную


t_put_get.cpp:     217
dllstart.cpp:      25
gsau_pu.cpp:       438
gsau_up.cpp:       501
gsaugsau.h:        26
include2.c:        4
uid.cpp:           32
gsau.h:            146
gsau_stt.h:        15
gsaudef.h:         96
mkSDE.h:           17
put_get.h:         9
                   1526             354      1880

  С++ код, выход утилиты генерации структур обмена

Cmd4Pmp:           45
Cmd4Pmp.cpp:       128
Cmd4Pos:           32
Cmd4Pos.cpp:       63
Indicator:         29
Indicator.cpp:     47
Position:          32
Position.cpp:      63
Pump:              45
Pump.cpp:          128
                   612                       2492    всего
                   612 + 1526 =              2138    только клиентская часть



                                  Примечание
     
     Далее, необходимо отметить, что в решении задачи GSAU существенную
     роль играет уникальная высокоуровневая библиотека обмена  с  базой
     данных. В  случае  использования  других  интерфейсных  библиотек,
     таких как ODBC или Embedde SQL, размер кода вырос бы существенно.

                                     64
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


     Итак получаем

               RSL               реализация

всего          1522              2492


серверная      189               354
часть

клиентская     1193              2138
часть


     Даже  в  условиях  использования  библиотеки  обмена  с  базой   данных
соотношение строчек С++ / RSL приблизительно равно 2.

     В тоже время соотнешение  SQL  /  RSL  практически  равно  1,  так  как
скрипты, отмеченные знаком  +,  в  действительности  не  имеют  отношения  к
задаче,  я  есть,  так  сказать,  накладным  расходом  на  создание/удаление
структуры БД и ввод начальных значений.

     Отсюда  можно  сделать  (вполне  очевидный)  вывод,  что  SQL,   являсь
специализированным  языком  весьма  высокого  уровня  и  позволяющий  писать
эффективные   приложения,    является    уникальным    явлением    в    мире
программирования.

     В  качестве  второго  примера  приведем   статистику   полученную   при
реализации проекта Harbour (cm. [5] )

     Этот пример является образцом гораздо более  абстрактной  спецификации,
которая не учитывает особенности проектирования БД для РСУБД и  не  отвечает
на вопросы, интересующие SQL - программиста.  Какие  алгоритмы  относятся  к
серверной части (SQL- скриптам) какие к клиентской части (C++) и т.д.

     Спецификация (rsl - код) - 147 строчек, реализация клиента (с-  код)  -
799 строчек + (хедеры) 207 строчек, реализация сервера ( SQL скрипты) -  482
строчки;

     итого 1488 строчек кода. Получаем соотношение приблизительно 1 к 10.

                                     65
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


                       ПЕРЕЧЕНЬ ТЕРМИНОВ И СОКРАЩЕНИЙ

                                      A
                                      B
                                      C

connection
     см. соединение
                                      D
                                      E
                                      F
                                      G
                                      H
                                      I
                                      J
                                      K
                                      L

lambda abstration
     см. лямбда абстракция
                                      M
                                      N
                                      O

operator
     пользователь ЭВМ, управляющий приложением
                                      P
                                      Q
                                      R
                                      S
                                      T
                                      U
                                      V
                                      W
                                      X
                                      Y
                                      Z
                                      A

администратор
     оператор с  расширенным  набором  привилегий  и  обязанностей  в  "Gass
     Station Advanced Utilities".
                                      Б
                                      В
                                      Г
                                      Д

деление на цело
     для деления на цело используется символ '%'
                                      Е
                                      Ё
                                      Ж
                                      З
                                     66
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

                                      И
                                      Й
                                      К
                                      Л

лямбда абстракция
     следующее выражение, называемое лямбда абстракцие,
     
     - binding :  type_expr :- value_expr
     
     представляет функцию типа
     
     type_expr -~-> T
     
     где T есть типа выражения value_expr.  Рассмотрим  как  можно  записать
     функцию инкремент:
     
     value
       incr : Int -> Int
     
     axiom
       incr  is - x: Int :- x+1
     
     
                                      М
                                      Н
                                      О

оператор
     
          - (operator) человек, выполняющий различные действия на компьютере
     с запущенным приложением GSAU,
     
          - лицо с минимальным набором привилегий в "Gass  Station  Advanced
     Utilities".
                                      П

печатный документ
                                      Р
                                      С

соединение
     пронумерованный сеанс связи на уровне приложения между  SQL-клиентом  и
     SQL-сервером.
                                      Т

таймер
     процесс,  регулярно  выполняющий  некоторые  действия  через   заданный
     интервал времени
                                        У
                                        Ф
                                        Х


                                     67
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

хранимая процедура
     выполняется не на SQL -  клиенте,  а  на  SQL  -  сервере,  где  она  и
     хранится.
                                      Ц
                                      Ч
                                      Ш
                                      Щ
                                      Ъ
                                      Ы
                                      Ь
                                      Э
                                      Ю
                                      Я

                                     68
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


                                    INDEX


"Gass Station Advanced Utilities . . . . . . . . . . . . . . . . . . . .   0
драйвер контроллера. . . . . . . . . . . . . . . . . . . . . . . . . . .   9
деление на цело. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  65
умолчательные значения поля. . . . . . . . . . . . . . . . . . . . . . .  35
исполнитель. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
ссылочная целостность. . . . . . . . . . . . . . . . . . . . . . . . . .   8
ссылочная целостность. . . . . . . . . . . . . . . . . . . . . . . . . .  33
ссылочное ограничение целостности. . . . . . . . . . . . . . . . . . . .  21
структур обмена. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  10
структура обмана данными . . . . . . . . . . . . . . . . . . . . . . . .  22
схема. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  15
триггер. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
триггеры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  36
хранимая процедура . . . . . . . . . . . . . . . . . . . . . . . . . . .  66
таймер . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  66
соединение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  66
функции высокоуровневого интерфейса. . . . . . . . . . . . . . . . . . .  20
генератор структур обмена данными. . . . . . . . . . . . . . . . . . . .  49
библиотека обмена с базой данных . . . . . . . . . . . . . . . . . . . .   8
каскадное удаление . . . . . . . . . . . . . . . . . . . . . . . . . . .  35
бак. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
бачок. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
кнопка . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
администратор. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  65
ограничения целостности. . . . . . . . . . . . . . . . . . . . . . . . .   7
ограничения целостности. . . . . . . . . . . . . . . . . . . . . . . . .   8
оператор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  66
перегруженная функция insert . . . . . . . . . . . . . . . . . . . . . .  35
нуль - модем . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
выполняемый файл . . . . . . . . . . . . . . . . . . . . . . . . . . . .  20
насос. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
наблюдатель состояний. . . . . . . . . . . . . . . . . . . . . . . . . .   9
шланг насоса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
agent. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
check. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
check. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  36
check. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  39
com - порт . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
com port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  65
Delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  23
driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
GSA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   5
GSAU_Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  50
GSAU_RIndicator. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  50
GSAU_State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  50
Indicator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  11
Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  25
                                     69
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

Meassure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  45
nozzle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  65
position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
Position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  46
pump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
Pump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  45
pump monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
RAISE Development Method . . . . . . . . . . . . . . . . . . . . . . . .   8
referencial integrity. . . . . . . . . . . . . . . . . . . . . . . . . .  21
referential integrity. . . . . . . . . . . . . . . . . . . . . . . . . .   8
Relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  10
rio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  48
sde. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  48
SDE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  56
sed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  22
sed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  48
Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  22
State. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  10
Structure of DataBase Exchange . . . . . . . . . . . . . . . . . . . . .  48
t_put_get. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  56
tank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
TCP/UDP reciever . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
TCP/UDP sender . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
TPosition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  37
u_mkSDE    (смотри бат файл u_bgnSDE1.bat) . . . . . . . . . . . . . . .  48
u_mkSDE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  49
unique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
unique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  36
unique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  39
Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  25
UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  32
where. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
where. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  39


                                     70
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02


                        ПЕРЕЧЕНЬ ССЫЛОЧНЫХ ДОКУМЕНТОВ


     1) C.J. Date. An  intpoduction  to  database  systems.  Sixth  edition.
Addison-Wesley Publishing Company.

     2) The RAISE Language Group. The  RAISE  SPECIFICATION  LANGUAGE.  ISBN
0-13-752833-7. Denmark, Herdfordshire, Prentice Hall Europe, 1992.- 396;

     3) Hung Dang Van, Chris George, Tomasz Janovwski,  and  Richard  Moore.
Specification Case Studies in RAISE. ISBN 1-85233-359-6 Springer, 2002;

     4) O.G.Piskunov, O. Golovko. Application  -  SQL  server  data  echange
tools. Canadian Intellectual Property Office. Order # 102928, transaction  #
250023, 2001;

     5) O.G.Piskunov. Harbour - Example of usage RAISE specification  method
to     develop      SQL      -      based      application,      10.12.2001,
www.i.com.ua/~agp1/software/hrb1.0.tar.gz.

     6) Г.  Майерс.   Надежность   программного   обеспечения.   Перевод   с
английского Ю.Ю. Галимова, Под редакцией В.Ш. Кауфмана, Издательство  "Мир",
Москва, 1980.

     7) C.B.  Jones.  Systematic  Software  Development  -  Using  VDM,  2nd
Edition. Prentice-Hall International 1989

     8) O.G.Piskunov,   V.Ilyuhin.   Коммуникационная   Компонента   Системы
Управления           Заправочной            Станцией,            22.11.2002,
www.i.com.ua/~agp1/software/gsau0.90.tar.gz.

     9) B.W. Boehm, Software Engineering Economics, Prentice Hall, Englewood
Cliffs, N.J., 1981

     10) Лутц Прехельт, Эмпирическое сравнение семи языков программирования,
Журнал "Открытые системы", #12, 2000,  http://www.osp.ru/os/2000/12/045.htm 

     11) L. Prechelt and B. Unger, A Controlled Experiment on the Effects of
PSP Trimming: Detailed  Description  and  Evaluation,  Tech  Report  1/1999,
Fakultat fur Informattik, Universitat Karlsruhe, Germany, Mar. 1999

                                      2
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02




                                 СОДЕРЖАНИЕ
     
     
     
     1.  ОБЩИЕ СВЕДЕНИЯ О "Gass Station Advanced Utilities" . . .    5
     1.1.  НАЗНАЧЕНИЕ "Gass Station Advanced Utilities" . . . . .    5
     1.2.  МИНИМАЛЬНАЯ КОНФИГУРАЦИЯ ТЕХНИЧЕСКИХ И ПРОГРАММНЫХ
           СРЕДСТВ  . . . . . . . . . . . . . . . . . . . . . . .    6
     1.3.  ПРОЦЕДУРА УСТАНОВКИ GSAU . . . . . . . . . . . . . . .    6
     1.4.  ЗАПУСК И ОСТАНОВ GSAU  . . . . . . . . . . . . . . . .    6
     2.  ОПИСАНИЕ "Gass Station Advanced Utilities" . . . . . . .    7
     2.1.  ВВЕДЕНИЕ . . . . . . . . . . . . . . . . . . . . . . .    7
     2.2.  ОБЩАЯ СХЕМА КОМПОНЕНТ GSAU И ИНТЕРФЕЙСОВ МЕЖДУ НИМИ  .    8
     2.2.1.  Описание взаимодействия GSAU- сервера и GSAU- клиента   10
     2.2.2.  Типы основных потоков данных между GSAU-сервером и
             GSAU- клиентом . . . . . . . . . . . . . . . . . . .   10
     2.2.3.  Глобальные обьекты проекта . . . . . . . . . . . . .   15
     2.2.4.  Cхема взаимодействия между GSAU-сервером и GSAU
             клиентом . . . . . . . . . . . . . . . . . . . . . .   16
     2.2.5.  Описание БД и операторов языка манипулирования
             данными DML  . . . . . . . . . . . . . . . . . . . .   20
     2.2.6.  Функции высокоуровневого интерфейса  . . . . . . . .   20
     2.2.6.1.  Определение таблиц базы данных GSAU  . . . . . . .   21
     2.2.6.2.  Определение функций интерфейса с базой данных GSAU   21
     2.2.6.2.1.  Использование оператора SELECT . . . . . . . . .   22
     2.2.6.2.2.  Использование оператора DELETE . . . . . . . . .   23
     2.2.6.2.3.  Использование оператора INSERT . . . . . . . . .   25
     2.2.6.2.4.  Использование оператора UPDATE . . . . . . . . .   25
     2.2.6.2.5.  Использование оператора UPDATE #2  . . . . . . .   32
     2.2.6.3.  Описание таблицы типа TPump. . . . . . . . . . . .   33
     2.2.6.4.  Описание таблицы типа TPosition. . . . . . . . . .   37
     2.2.6.5.  Описание нового типа данных Relation.  . . . . . .   39
     2.2.7.  Описание работы менеджера драйверов  . . . . . . . .   43
     2.2.8.  Описание работы драйверов контроллеров . . . . . . .   43
     2.2.9.  Описание работы имитатора контроллера  . . . . . . .   43
     2.2.10. Описание работы оператора  . . . . . . . . . . . . .   43
     3.  РУКОВОДСТВО ПРОГРАММИСТА . . . . . . . . . . . . . . . .   44
     3.1.  СХЕМА РЕЛЯЦИОННЫХ СВЯЗЕЙ GSAU  . . . . . . . . . . . .   44
     3.2.  ВНУТРЕННЯЯ СХЕМА БАЗЫ ДАННЫХ GSAU  . . . . . . . . . .   44
     3.2.1.  Based datatypes  . . . . . . . . . . . . . . . . . .   45
     3.2.1.1.  Meassure . . . . . . . . . . . . . . . . . . . . .   45
     3.2.1.2.  Pump . . . . . . . . . . . . . . . . . . . . . . .   45
     3.2.1.3.  Position . . . . . . . . . . . . . . . . . . . . .   46
     3.3.  MAKEFILEs  . . . . . . . . . . . . . . . . . . . . . .   47
     3.3.1.  Зависимости от других проектов . . . . . . . . . . .   48
     3.4.  ОПИСАНИЕ СТРУКТУР ОБМЕНА ГЕНЕРИРУЕМОГО ИНТЕРФЕЙСА  . .   48
     3.5.  ОПИСАНИЕ ВЫСОКОУРОВНЕГО ИНТЕРФЕЙСА С БД  . . . . . . .   49
     3.5.1.  Хедер макросов и констант  . . . . . . . . . . . . .   49
     3.5.1.1.  Command/State Indicator  . . . . . . . . . . . . .   50
     3.5.1.2.  Command/State  . . . . . . . . . . . . . . . . . .   50
     3.5.2.  Хедер основных обьектов системы  . . . . . . . . . .   51
                                      3
                   UA.'agp1@smtp.ru'.GSAU-0.90/0.12 13 02

     3.6.  ФУНКЦИИ КОНСТРУИРОВАНИЯ/ДЕКОНСТРУИРОВАНИЯ COMMAND/STATE   55
     4.  ИСПОЛЬЗОВАНИЕ И ПРОВЕРКА РАБОТОСПОСОБНОСТИ . . . . . . .   56
     4.1.  ВЫПОЛНЕНИЕ ТЕСТИРУЮЩЕЙ ПРОГРАММЫ . . . . . . . . . . .   56
     4.1.1.  the put/get command/state/indicator  . . . . . . . .   56
     4.2.  ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ ВЫСОКОУРОВНЕВОГО ИНТЕРФЕЙСА С БД   57
     5.  НЕКОТОРЫЕ ВЫВОДЫ . . . . . . . . . . . . . . . . . . . .   62
     ПЕРЕЧЕНЬ ТЕРМИНОВ И СОКРАЩЕНИЙ . . . . . . . . . . . . . . .   65
     INDEX  . . . . . . . . . . . . . . . . . . . . . . . . . . .   68
     ПЕРЕЧЕНЬ ССЫЛОЧНЫХ ДОКУМЕНТОВ  . . . . . . . . . . . . . . .   70


в аттаче повербилдер, отображение числа в слово
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429732
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вспомнил язык graphviz

офисная репликация

Код: 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.
digraph world {
//orientation=landscape;

subgraph  clusterRepli {
{rank=same;   name }  //---------------------------
    name      [color=white,  label="Soft replication. \n succsess mail \n every M,Th,Su at 8:00 \n ! deployment at 02:00"];
    name -> BE10 ;
    BE10 -> LasVegas[  label=" \n03:00 !  \n08:00 \n11:00 \n14:00 \n17:00 \n20:00"];
{rank=same;   BE10; mirror2 }  //---------------------------
  mirror2[label="www.comvu.com/Http_Backup/stage/mirror/fs"]
            LasVegas [label="Bavarian(Replication)"];
            LasVegas -> BE10[ style=bold,  label="d6: 04:00  \nd1: 10:00 \nd2: 13:00 \nd3: 16:00 \nd4: 19:00 \nd5: 22:00  \n"];
                        BE10 -> mirror2;
{rank=same;   LasVegas; foo1; ini }  //---------------------------
foo1 [color=black, label="LasVegas(Deployment)"] ;
//LasVegas -> foo1 ;
foo1 -> input:po2[ label="depl_work: 01:00"];
foo1 -> ini:i3 [dir=back];
  ini[shape=record, label="{{<i3> |  C:/hbcp/hbcp/run/deplm_pkg.LasVegas-BE10.ini    | <o3>} }"];
{rank=same;   input; foo }  //---------------------------
    LasVegas -> input:pi2[dir=back];
  input[shape=record, label="{{<pi2> |  //LasVegas/comvu ~= C:/Inetpub/wwwroot/uniclient/$ysadminONLY   | <po2>} }"];
   foo [color=black, label="Users"];
     input:po2 -> foo[color = black, dir=back];  //---------------------------

}




}
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429830
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAponuch, хотя бы один тынц дайте, хочется посмотреть на "и далее"

тынц1

тынц2
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429863
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tchingizponuch,

здравствуйте, это я
правда проектов на гитхабе нет

то есть вы знаете несколько технологий с большинством фреймворков и постоянно их используете ? как получается совмещать ?
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429898
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch тынц1

Вижу в основном только Scala, и да чувак в этом направлении крутой


ponuch тынц2

Тоже самое.

Примеры не поясняют твой изначальный вопрос.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39429967
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

Scala, Python, Ruby, JavaScript. Мне думается, что совмещать несколько технологий сейчас на достаточном уровне просто нереально или нужно какую-то особенную голову иметь. Берём для примера яву. По - хорошему нужно знать особенности сборки мусора, виды ссылок, спринги и/или java ee , иметь представление о серверах приложений, худо-бедно разбираться в бд, яваскрипте. И при этом библиотеки развиваются, появляются новые, за этим всем нужно следить. Я не знаю что там в руби или питоне, но глубоко в них погружаться без отрыва от текущёй специализации просто времени не хватит. Вот мой основной вопрос - кто это и есть ли такие вообще - чтобы был крут в 2-3-х технологиях одновременно.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39430017
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchtchingizponuch,

здравствуйте, это я
правда проектов на гитхабе нет

то есть вы знаете несколько технологий с большинством фреймворков и постоянно их используете ? как получается совмещать ?
Я не понимаю, что Вы спрашиваете во втором вопросе
Слово "большиноством" в первом вопросе - бессмысленно.

парадокс использовал -- с 94 по 98
разные скл с 88- 90, с 96 по 2004
rsl c 2000 по 2005й
graphiz когда надо схемы рисовать
сшарп с 2005 по сейчас.

си с 86 по сейчас
фортран с 84 по 88
zsh с 2004 по 2009й
java + javascript с 2010 по 2011
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39430027
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchtchingizponuch,

здравствуйте, это я
правда проектов на гитхабе нет

то есть вы знаете несколько технологий с большинством фреймворков и постоянно их используете ? как получается совмещать ?
если в этот вопрос вставить плавание, стрельбу из пистолета, езду на велосипеде и езду на автомобиле и еще раз его сформулировать, что получиться?
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39430080
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchScala, Python, Ruby, JavaScript.

Там over 90% Scala. JavaScript так или иначе знают большинство, кто имеет хоть какое-то отношение к веб разработке. Знания Python не будут лишними никому, ни разработчику на плюсах, шапра, джавы, или ещё чего-то. Ruby там кот наплакал, да не особо это сложная платформа.


ponuchЯ не знаю что там в руби или питоне, но глубоко в них погружаться без отрыва от текущёй специализации просто времени не хватит. Вот мой основной вопрос - кто это и есть ли такие вообще - чтобы был крут в 2-3-х технологиях одновременно.

Приведённые по твоим ссылкам круты в Scala. По остальным там ничего особенного. С питоном можно за день разобраться и научиться его использовать. JS вообще не в счёт, это язык с бесконечной глубиной погружения
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39430097
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchкто это и есть ли такие вообще - чтобы был крут в 2-3-х технологиях одновременно.
Для того, чтобы клонировать чужой репозиторий ради фикса пары тривиальных багов с последующим пулл-реквестом, не нужно быть крутым.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39431322
Common Lisp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Какую голову нужно иметь ?
Самую обычную.

> в яве одной с её фреймворками можно заковыряться на годы
Вот для того, чтобы ковыряться во фреймворках, нужно иметь больную голову.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39431361
Фотография Areostar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuch,

Голову программиста!
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39435506
Cadil
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TВсякие люди бывают, есть акыны: что вижу - то пою. Поизучал одно чуть-чуть - залил, второе - залил. Вершков насобирал, вроде всего много, а серьезно ни в чем не разбирается.

Не могу согласиться. Посмотрите, например, эту работу - https://geektimes.ru/post/284994/
Знания вершков тут маловато ... Повторить со знанием вершков не каждый сможет.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39435512
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CadilНе могу согласиться. Посмотрите, например, ...
Знания вершков тут маловато ... Повторить со знанием вершков не каждый сможет.
Прочитал, не вижу там знания множества ЯП, которое тут обсуждается.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39437309
Фотография FishHook
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchScala, Python, Ruby, JavaScript. Мне думается, что совмещать несколько технологий сейчас на достаточном уровне просто нереально или нужно какую-то особенную голову иметь. Берём для примера яву. По - хорошему нужно знать особенности сборки мусора, виды ссылок, спринги и/или java ee , иметь представление о серверах приложений, худо-бедно разбираться в бд, яваскрипте. И при этом библиотеки развиваются, появляются новые, за этим всем нужно следить. Я не знаю что там в руби или питоне, но глубоко в них погружаться без отрыва от текущёй специализации просто времени не хватит. Вот мой основной вопрос - кто это и есть ли такие вообще - чтобы был крут в 2-3-х технологиях одновременно.

Вы рассуждаете не как программист, а как студент четвертого курса, который вызубрил материал, но на "зачем" и "почему" у него не хватает ума и времени. Если вы понимаете, для чего новые технологии придумываются, какие проблемы решают им каким способом, то вам не нужно досконально изучать каждый отдельный копеечный фреймворк - когда у вас появится потребность в нем (то есть будет задача, для которой вы выберете конкретный инструментарий) вам нужно будет затратить минимум усилий для того, чтобы изучить матчасть нужной тулзы.
Если новый незнакомый язык программирования для вас проблема, вам не нужно заниматься программированием. Есть куча профессий, где применяется другой подход к изучению мира, например, вы могли бы водить трамвай или пасти овец.
...
Рейтинг: 0 / 0
Кто все эти люди ?
    #39440813
da17
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ponuchЧастенько захожу на гитхаб и вижу у людей проекты на C++, Scala, TypeScript, JavaScript и далее. Как они всё это совмещают ? Какую голову нужно иметь ? Тут в яве одной с её фреймворками можно заковыряться на годы, а люди кучу языков используют. У меня было так C# -> плюсы + питон -> C# + C++ - >C# -> Java + JavaScript. Причём плюсы я практически забыл, за шарпом не слежу, в яве столько всего что на что-то ещё просто времени нет ковыряться.
В настоящий момент использую языки(за которые мне деньги платят) c++, perl, php, js иногда си. Проблем много, когда несколько месяцев не пишешь на одном из них, приходится с трудом переключаться, забываются тонкости, функционал реализуется значительно дольше т.к. постоянно подсматриваешь библиотеченые функции и узкие места. Месяцев через шесть разработки на одной технологии начинаешь глубоко уходить в детали. Вообще я встречал много людей, которые говорили, что они знают, пусть к примеру это будет js, но при простейших вопросах плавали.
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Кто все эти люди ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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