2021-04-26 20:07:00 +02:00
|
|
|
#coding:utf-8
|
|
|
|
#
|
|
|
|
# id: bugs.core_4470
|
|
|
|
# title: gbak fails to restore database containing dependency between views and packaged functions
|
2021-11-26 19:20:43 +01:00
|
|
|
# decription:
|
2021-04-26 20:07:00 +02:00
|
|
|
# Confirmed on WI-T3.0.0.30809 Firebird 3.0 Alpha 2:
|
|
|
|
# gbak: ERROR:action cancelled by trigger (0) to preserve data integrity
|
|
|
|
# gbak: ERROR: could not find object for GRANT
|
|
|
|
# gbak:Exiting before completion due to errors
|
|
|
|
# ============================================
|
|
|
|
# 28.10.2019:
|
|
|
|
# 1. Replaced PSQL function name 'localtime()' with 'fn_local_time()': first of them became keyword in FB 4.0
|
|
|
|
# 2.Checked on:
|
|
|
|
# 4.0.0.1635 SS: 3.384s.
|
|
|
|
# 4.0.0.1633 CS: 3.438s.
|
|
|
|
# 3.0.5.33180 SS: 2.137s.
|
|
|
|
# 3.0.5.33178 CS: 2.490s.
|
2021-11-26 19:20:43 +01:00
|
|
|
#
|
2021-04-26 20:07:00 +02:00
|
|
|
# tracker_id: CORE-4470
|
|
|
|
# min_versions: ['3.0']
|
|
|
|
# versions: 3.0
|
|
|
|
# qmid: None
|
|
|
|
|
|
|
|
import pytest
|
2021-11-26 19:20:43 +01:00
|
|
|
from pathlib import Path
|
|
|
|
from firebird.qa import db_factory, python_act, Action, temp_file
|
|
|
|
from firebird.driver import SrvRestoreFlag
|
2021-04-26 20:07:00 +02:00
|
|
|
|
|
|
|
# version: 3.0
|
|
|
|
# resources: None
|
|
|
|
|
|
|
|
substitutions_1 = []
|
|
|
|
|
|
|
|
init_script_1 = """
|
|
|
|
set bail on;
|
|
|
|
set autoddl on;
|
|
|
|
|
|
|
|
create domain dbigint as bigint;
|
|
|
|
create domain dblob as blob sub_type 0 segment size 80;
|
|
|
|
create domain did as bigint not null;
|
|
|
|
create domain dinteger as integer;
|
|
|
|
create domain dn31 as numeric(3, 1);
|
|
|
|
create domain dn41 as numeric(4, 1);
|
|
|
|
create domain dn51 as numeric(5, 1);
|
|
|
|
create domain dreal as double precision;
|
|
|
|
create domain dsmallint as smallint;
|
|
|
|
create domain dtime as timestamp;
|
|
|
|
create domain dvc255 as varchar(255);
|
|
|
|
create domain dvc512 as varchar(512);
|
|
|
|
commit;
|
|
|
|
set autoddl off;
|
|
|
|
|
|
|
|
set term ^;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create package wf as
|
|
|
|
begin
|
|
|
|
function cest (t dtime) returns dtime;
|
|
|
|
function cet (t dtime) returns dtime;
|
|
|
|
function fn_local_time (t dtime) returns dtime;
|
|
|
|
function dewpoint (temp dreal, hum dsmallint) returns dreal;
|
|
|
|
function yesterday returns dtime;
|
|
|
|
function altitude returns dreal;
|
|
|
|
function current_xml returns dvc512;
|
|
|
|
function relpressure(airpressureabsolute dreal,temperature dreal,altitude dreal, humidity dreal) returns dreal;
|
|
|
|
end^
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
set term ;^
|
|
|
|
commit work;
|
|
|
|
|
|
|
|
set autoddl on;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create table constants (id did generated by default as identity not null,
|
|
|
|
typ dvc255,
|
|
|
|
val dvc255,
|
|
|
|
keys dbigint,
|
|
|
|
primary key (id));
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create table raw (id did generated by default as identity not null,
|
|
|
|
readtime dtime not null,
|
|
|
|
delay dsmallint,
|
|
|
|
hum_in dsmallint,
|
|
|
|
temp_in dreal,
|
|
|
|
hum_out dsmallint,
|
|
|
|
temp_out dreal,
|
|
|
|
abs_pressure dreal,
|
|
|
|
wind_ave dreal,
|
|
|
|
wind_gust dreal,
|
|
|
|
wind_dir dsmallint,
|
|
|
|
rain dreal,
|
|
|
|
status dsmallint,
|
|
|
|
illuminance dreal,
|
|
|
|
uv dsmallint,
|
|
|
|
primary key (id),
|
|
|
|
constraint unq1_raw unique (readtime));
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create table timezone (jahr dsmallint not null,
|
|
|
|
gmt_from dtime,
|
|
|
|
gmt_thru dtime,
|
|
|
|
constraint pk_timezone primary key (jahr));
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create index raw_idx1 on raw (hum_in);
|
|
|
|
create descending index raw_idx10 on raw (abs_pressure);
|
|
|
|
create descending index raw_idx11 on raw (readtime);
|
|
|
|
create descending index raw_idx12 on raw (rain);
|
|
|
|
create index raw_idx2 on raw (temp_in);
|
|
|
|
create index raw_idx3 on raw (hum_out);
|
|
|
|
create index raw_idx4 on raw (temp_out);
|
|
|
|
create index raw_idx5 on raw (abs_pressure);
|
|
|
|
create index raw_idx6 on raw (wind_ave);
|
|
|
|
create index raw_idx7 on raw (wind_gust);
|
|
|
|
create index raw_idx8 on raw (wind_dir);
|
|
|
|
create index raw_idx9 on raw (rain);
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create view meteo (timestamp_utc, timestamp_local, tempint, humint, temp, hum, wind, wind_dir, wind_gust, wind_gust_dir, dew_point, rain, rain_rate, pressure, uv_index, solar_rad) as
|
|
|
|
select readtime, wf.fn_local_time(readtime), temp_in, hum_in, temp_out, hum_out, wind_ave / 3.6 , 22.5 * wind_dir, wind_gust / 3.6 ,
|
|
|
|
22.5 * wind_dir, wf.dewpoint(temp_out, hum_out), cast(rain - lead(rain) over(order by readtime desc) as numeric (6,3)) , 0,
|
|
|
|
2.8+wf.relpressure(abs_pressure, temp_out, wf.altitude(), hum_out), 0, 0
|
|
|
|
from raw;
|
|
|
|
commit;
|
|
|
|
|
|
|
|
set autoddl off;
|
|
|
|
set term ^;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
create package body wf as
|
|
|
|
begin
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function CEST (T dtime)returns dtime
|
|
|
|
AS
|
|
|
|
begin
|
|
|
|
return dateadd (2 hour to t);
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function CET (T dtime)returns dtime
|
|
|
|
AS
|
|
|
|
begin
|
|
|
|
return dateadd (1 hour to t);
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function altitude returns dreal
|
|
|
|
as
|
|
|
|
begin
|
|
|
|
return (select c.val from constants c where c.typ='Altitude');
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function fn_local_time (t dtime)returns dtime
|
|
|
|
as
|
|
|
|
declare variable jahr dsmallint;
|
|
|
|
declare variable gmt_from dtime;
|
|
|
|
declare variable gmt_thru dtime;
|
|
|
|
begin
|
|
|
|
select tz.gmt_from, tz.gmt_thru
|
|
|
|
from timezone tz where tz.jahr=extract(year from :t)
|
|
|
|
into :gmt_from, :gmt_thru;
|
|
|
|
if (t between :gmt_from and :gmt_thru) then
|
|
|
|
begin
|
|
|
|
return dateadd (2 hour to t);
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return dateadd (1 hour to t);
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function relpressure (airpressureabsolute dreal, temperature dreal, altitude dreal, humidity dreal) returns dreal
|
|
|
|
as
|
|
|
|
declare variable g_n dreal;
|
|
|
|
declare variable gam dreal;
|
|
|
|
declare variable r dreal;
|
|
|
|
declare variable m dreal;
|
|
|
|
declare variable r_0 dreal;
|
|
|
|
declare variable t_0 dreal;
|
|
|
|
declare variable c dreal;
|
|
|
|
declare variable e_0 dreal;
|
|
|
|
declare variable f_rel dreal;
|
|
|
|
declare variable e_d dreal;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
begin
|
|
|
|
g_n = 9.80665;-- erdbeschleunigung (m/s^2)
|
|
|
|
gam = 0.0065;--temperaturabnahme in k pro geopotentiellen metern (k/gpm)
|
|
|
|
r = 287.06;--gaskonstante fur trockene luft (r = r_0 / m)
|
|
|
|
m = 0.0289644;--molare masse trockener luft (j/kgk)
|
|
|
|
r_0 = 8.314472;--allgemeine gaskonstante (j/molk)
|
|
|
|
t_0 = 273.15;--umrechnung von c in k
|
|
|
|
c = 0.11;--dwd-beiwert fur die berucksichtigung der luftfeuchte
|
|
|
|
e_0 = 6.11213;-- (hpa)
|
|
|
|
f_rel = humidity / 100;--relative luftfeuchte (0-1.0)
|
|
|
|
e_d = f_rel * e_0 * exp((17.5043 * temperature) / (241.2 + temperature));--momentaner stationsdampfdruck (hpa)
|
|
|
|
return airpressureabsolute * exp((g_n * altitude) / (r * (temperature + t_0 + c * e_d + ((gam * altitude) / 2))));
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function yesterday returns dtime
|
|
|
|
as
|
|
|
|
begin
|
|
|
|
return dateadd (-1 day to current_date);
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function dewpoint (temp dreal, hum dsmallint)
|
|
|
|
returns dreal
|
|
|
|
as
|
|
|
|
declare variable gamma dreal;
|
|
|
|
declare variable a dreal;
|
|
|
|
declare variable b dreal;
|
|
|
|
begin
|
|
|
|
if ((coalesce(temp,0)=0) or (coalesce(hum,0)=0)) then
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
return temp - ((100 - hum) / 5.0);
|
|
|
|
end
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
function current_xml returns dvc512
|
|
|
|
as
|
|
|
|
declare variable timestamp_utc type of column meteo.timestamp_utc;
|
|
|
|
declare variable timestamp_local type of column meteo.timestamp_local;
|
|
|
|
declare variable tempint type of column meteo.tempint;
|
|
|
|
declare variable humint type of column meteo.humint;
|
|
|
|
declare variable temp type of column meteo.temp;
|
|
|
|
declare variable hum type of column meteo.hum;
|
|
|
|
declare variable wind type of column meteo.wind;
|
|
|
|
declare variable wind_dir type of column meteo.wind_dir;
|
|
|
|
declare variable wind_gust type of column meteo.wind_gust;
|
|
|
|
declare variable wind_gust_dir type of column meteo.wind_gust_dir;
|
|
|
|
declare variable dew_point type of column meteo.dew_point;
|
|
|
|
declare variable rain type of column meteo.rain;
|
|
|
|
declare variable rain_rate type of column meteo.rain_rate;
|
|
|
|
declare variable pressure type of column meteo.pressure;
|
|
|
|
declare variable uv_index type of column meteo.uv_index;
|
|
|
|
declare variable solar_rad type of column meteo.solar_rad;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
begin
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
select first 1 timestamp_utc,timestamp_local, tempint, humint, temp, hum, wind, wind_dir, wind_gust, wind_gust_dir, dew_point,
|
|
|
|
rain, rain_rate, pressure, uv_index, solar_rad
|
|
|
|
from meteo order by timestamp_utc desc
|
|
|
|
into :timestamp_utc, :timestamp_local, :tempint, :humint, :temp, :hum, :wind, :wind_dir, :wind_gust, :wind_gust_dir,
|
|
|
|
:dew_point, :rain, :rain_rate, :pressure, :uv_index, :solar_rad;
|
2021-11-26 19:20:43 +01:00
|
|
|
|
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
return '<current><thInt><temp>'||
|
|
|
|
tempint||
|
|
|
|
'</temp><humidity>'||
|
|
|
|
humint||
|
|
|
|
'</humidity></thInt><th1><temp>'||
|
|
|
|
temp||
|
|
|
|
'</temp><humidity>'||
|
|
|
|
hum||
|
|
|
|
'</humidity></th1><rain><rate>'||
|
|
|
|
rain_rate||
|
|
|
|
'</rate></rain><wind><avgSpeed>'||
|
|
|
|
wind||
|
|
|
|
'</avgSpeed><dirDeg>'||
|
|
|
|
wind_dir||
|
|
|
|
'</dirDeg><gustSpeed>'||
|
|
|
|
wind_gust||
|
|
|
|
'</gustSpeed></wind><barometer><pressure>'||
|
|
|
|
pressure||
|
|
|
|
'</pressure></barometer><time>'||
|
|
|
|
substring (timestamp_local from 1 for 19)||
|
|
|
|
'</time></current>';
|
|
|
|
end
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
end^
|
2021-11-26 19:20:43 +01:00
|
|
|
|
2021-04-26 20:07:00 +02:00
|
|
|
set term ;^
|
2021-11-26 19:20:43 +01:00
|
|
|
commit;
|
|
|
|
"""
|
2021-04-26 20:07:00 +02:00
|
|
|
|
|
|
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
|
|
|
|
|
|
|
# test_script_1
|
|
|
|
#---
|
|
|
|
# import os
|
2021-11-26 19:20:43 +01:00
|
|
|
#
|
2021-04-26 20:07:00 +02:00
|
|
|
# fbk = os.path.join(context['temp_directory'],'core_4470-backup.fbk')
|
|
|
|
# fbn = os.path.join(context['temp_directory'],'core_4470-restored.fdb')
|
|
|
|
# print('Creating backup...')
|
|
|
|
# runProgram('gbak',['-b','-user',user_name,'-password',user_password,dsn,fbk])
|
|
|
|
# print('Creating restore...')
|
|
|
|
# runProgram('gbak',['-rep','-user',user_name,'-password',user_password,fbk,fbn])
|
|
|
|
# script = '''show view; show package;'''
|
|
|
|
# runProgram('isql',[fbn,'-q','-user',user_name,'-password',user_password],script)
|
|
|
|
# if os.path.isfile(fbk):
|
|
|
|
# os.remove(fbk)
|
|
|
|
# if os.path.isfile(fbn):
|
|
|
|
# os.remove(fbn)
|
2021-11-26 19:20:43 +01:00
|
|
|
#
|
2021-04-26 20:07:00 +02:00
|
|
|
#---
|
2021-11-26 19:20:43 +01:00
|
|
|
|
|
|
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
2021-04-26 20:07:00 +02:00
|
|
|
|
|
|
|
expected_stdout_1 = """
|
|
|
|
METEO
|
|
|
|
WF
|
2021-11-26 19:20:43 +01:00
|
|
|
"""
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2021-11-26 19:20:43 +01:00
|
|
|
fbk_file_1 = temp_file('test.fbk')
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2021-11-26 19:20:43 +01:00
|
|
|
@pytest.mark.version('>=3.0')
|
|
|
|
def test_1(act_1: Action, fbk_file_1: Path):
|
|
|
|
with act_1.connect_server() as srv:
|
2021-12-07 13:36:20 +01:00
|
|
|
srv.database.backup(database=act_1.db.db_path, backup=fbk_file_1)
|
2021-11-26 19:20:43 +01:00
|
|
|
srv.wait()
|
2021-12-07 13:36:20 +01:00
|
|
|
srv.database.restore(backup=fbk_file_1, database=act_1.db.db_path,
|
2021-11-26 19:20:43 +01:00
|
|
|
flags=SrvRestoreFlag.REPLACE)
|
|
|
|
srv.wait()
|
|
|
|
act_1.expected_stdout = expected_stdout_1
|
|
|
|
act_1.isql(switches=['-q'], input='show view; show package;')
|
|
|
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|