Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a1b4c64

Browse files
committed
Merge branch 'PGPROEE9_6_scheduler' into PGPROEE9_6
2 parents 71ebaab + 9e826fc commit a1b4c64

32 files changed

+2094
-27
lines changed

contrib/pgpro_scheduler/pgpro_scheduler--2.0.sql

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ LANGUAGE plpgsql set search_path FROM CURRENT;
338338
CREATE FUNCTION _possible_args() RETURNS jsonb AS
339339
$BODY$
340340
BEGIN
341-
RETURN json_build_object(
341+
RETURN jsonb_build_object(
342342
'node', 'node name (default: master)',
343343
'name', 'job name',
344344
'comments', 'some comments on job',
@@ -396,34 +396,43 @@ END
396396
$BODY$
397397
LANGUAGE plpgsql set search_path FROM CURRENT;
398398

399-
CREATE FUNCTION _get_cron_from_attrs(params jsonb) RETURNS jsonb AS
399+
CREATE FUNCTION _get_cron_from_attrs(params jsonb, prev jsonb) RETURNS jsonb AS
400400
$BODY$
401401
DECLARE
402402
dates text[];
403403
cron jsonb;
404+
rule jsonb;
404405
clean_cron jsonb;
405406
N integer;
406407
name text;
408+
updatePrev boolean;
407409
BEGIN
408410

411+
updatePrev := true;
412+
413+
IF NOT params?'cron' AND NOT params?'rule' AND NOT params?'date' AND NOT params?'dates' THEN
414+
RAISE EXCEPTION 'There is no information about job''s schedule'
415+
USING HINT = 'Use ''cron'' - cron string, ''rule'' - json to set schedule rules or ''date'' and ''dates'' to set exact date(s)';
416+
END IF;
417+
409418
IF params?'cron' THEN
410419
EXECUTE 'SELECT cron2jsontext($1::cstring)::jsonb'
411420
INTO cron
412421
USING params->>'cron';
413-
ELSIF params?'rule' THEN
414-
cron := params->'rule';
415-
ELSIF NOT params?'date' AND NOT params?'dates' THEN
416-
RAISE EXCEPTION 'There is no information about job''s schedule'
417-
USING HINT = 'Use ''cron'' - cron string, ''rule'' - json to set schedule rules or ''date'' and ''dates'' to set exact date(s)';
418422
END IF;
419423

420-
IF cron IS NOT NULL THEN
421-
IF cron?'date' THEN
422-
dates := _get_array_from_jsonb(dates, cron->'date');
423-
END IF;
424-
IF cron?'dates' THEN
425-
dates := _get_array_from_jsonb(dates, cron->'dates');
426-
END IF;
424+
IF params?'rule' THEN
425+
rule := params->'rule';
426+
updatePrev := false;
427+
END IF;
428+
429+
cron := coalesce(cron, '{}'::jsonb) || coalesce(rule, '{}'::jsonb);
430+
431+
IF cron?'date' THEN
432+
dates := _get_array_from_jsonb(dates, cron->'date');
433+
END IF;
434+
IF cron?'dates' THEN
435+
dates := _get_array_from_jsonb(dates, cron->'dates');
427436
END IF;
428437

429438
IF params?'date' THEN
@@ -437,9 +446,13 @@ BEGIN
437446
IF N > 0 THEN
438447
EXECUTE 'SELECT array_agg(lll) FROM (SELECT distinct(date_trunc(''min'', unnest::timestamp with time zone)) as lll FROM unnest($1) ORDER BY date_trunc(''min'', unnest::timestamp with time zone)) as Z'
439448
INTO dates USING dates;
440-
cron := COALESCE(cron, '{}'::jsonb) || json_build_object('dates', array_to_json(dates))::jsonb;
449+
cron := cron || jsonb_build_object('dates', array_to_json(dates));
441450
END IF;
442-
451+
452+
IF updatePrev AND prev IS NOT NULL THEN
453+
cron := prev || cron;
454+
END IF;
455+
443456
clean_cron := '{}'::jsonb;
444457
FOR name IN SELECT * FROM unnest('{dates, crontab, onstart, days, hours, wdays, months, minutes}'::text[])
445458
LOOP
@@ -564,7 +577,7 @@ BEGIN
564577
RAISE WARNING 'You used excess keys in params: %.', array_to_string(excess, ', ');
565578
END IF;
566579

567-
cron := _get_cron_from_attrs(params);
580+
cron := _get_cron_from_attrs(params, NULL);
568581
commands := _get_commands_from_attrs(params);
569582
executor := _get_executor_from_attrs(params);
570583
node := 'master';
@@ -635,7 +648,7 @@ LANGUAGE plpgsql
635648
CREATE FUNCTION create_job(cron text, command text, node text DEFAULT NULL) RETURNS integer AS
636649
$BODY$
637650
BEGIN
638-
RETURN create_job(json_build_object('cron', cron, 'command', command, 'node', node)::jsonb);
651+
RETURN create_job(jsonb_build_object('cron', cron, 'command', command, 'node', node));
639652
END
640653
$BODY$
641654
LANGUAGE plpgsql
@@ -644,7 +657,7 @@ LANGUAGE plpgsql
644657
CREATE FUNCTION create_job(dt timestamp with time zone, command text, node text DEFAULT NULL) RETURNS integer AS
645658
$BODY$
646659
BEGIN
647-
RETURN create_job(json_build_object('date', dt::text, 'command', command, 'node', node)::jsonb);
660+
RETURN create_job(jsonb_build_object('date', dt::text, 'command', command, 'node', node));
648661
END
649662
$BODY$
650663
LANGUAGE plpgsql
@@ -653,7 +666,7 @@ LANGUAGE plpgsql
653666
CREATE FUNCTION create_job(dts timestamp with time zone[], command text, node text DEFAULT NULL) RETURNS integer AS
654667
$BODY$
655668
BEGIN
656-
RETURN create_job(json_build_object('dates', array_to_json(dts), 'command', command, 'node', node)::jsonb);
669+
RETURN create_job(jsonb_build_object('dates', array_to_json(dts), 'command', command, 'node', node));
657670
END
658671
$BODY$
659672
LANGUAGE plpgsql
@@ -662,7 +675,7 @@ LANGUAGE plpgsql
662675
CREATE FUNCTION create_job(cron text, commands text[], node text DEFAULT NULL) RETURNS integer AS
663676
$BODY$
664677
BEGIN
665-
RETURN create_job(json_build_object('cron', cron, 'commands', array_to_json(commands), 'node', node)::jsonb);
678+
RETURN create_job(jsonb_build_object('cron', cron, 'commands', array_to_json(commands), 'node', node));
666679
END
667680
$BODY$
668681
LANGUAGE plpgsql
@@ -671,7 +684,7 @@ LANGUAGE plpgsql
671684
CREATE FUNCTION create_job(dt timestamp with time zone, commands text[], node text DEFAULT NULL) RETURNS integer AS
672685
$BODY$
673686
BEGIN
674-
RETURN create_job(json_build_object('date', dt::text, 'commands', array_to_json(commands), 'node', node)::jsonb);
687+
RETURN create_job(jsonb_build_object('date', dt::text, 'commands', array_to_json(commands), 'node', node));
675688
END
676689
$BODY$
677690
LANGUAGE plpgsql
@@ -680,7 +693,7 @@ LANGUAGE plpgsql
680693
CREATE FUNCTION create_job(dts timestamp with time zone[], commands text[], node text DEFAULT NULL) RETURNS integer AS
681694
$BODY$
682695
BEGIN
683-
RETURN create_job(json_build_object('dates', array_to_json(dts), 'commands', array_to_json(commands), 'node', node)::jsonb);
696+
RETURN create_job(jsonb_build_object('dates', array_to_json(dts), 'commands', array_to_json(commands), 'node', node));
684697
END
685698
$BODY$
686699
LANGUAGE plpgsql
@@ -711,7 +724,7 @@ BEGIN
711724

712725
IF attrs?'cron' OR attrs?'date' OR attrs?'dates' OR attrs?'rule' THEN
713726
cmd := cmd || 'rule = ' ||
714-
quote_literal(_get_cron_from_attrs(attrs)) || '::jsonb, ';
727+
quote_literal(_get_cron_from_attrs(attrs, job.rule)) || '::jsonb, ';
715728
END IF;
716729

717730
IF attrs?'command' OR attrs?'commands' THEN
@@ -796,14 +809,27 @@ $BODY$
796809
LANGUAGE plpgsql
797810
SECURITY DEFINER set search_path FROM CURRENT;
798811

812+
CREATE FUNCTION set_job_attribute(jobId integer, name text, value jsonb) RETURNS boolean AS
813+
$BODY$
814+
BEGIN
815+
IF name <> 'rule' THEN
816+
RAISE EXCEPTION 'key % cannot have a jsonb value. Only "rule" allowed', name;
817+
END IF;
818+
819+
RETURN set_job_attributes(jobId, jsonb_build_object(name, value));
820+
END
821+
$BODY$
822+
LANGUAGE plpgsql
823+
SECURITY DEFINER set search_path FROM CURRENT;
824+
799825
CREATE FUNCTION set_job_attribute(jobId integer, name text, value anyarray) RETURNS boolean AS
800826
$BODY$
801827
BEGIN
802828
IF name <> 'dates' AND name <> 'commands' THEN
803829
RAISE EXCEPTION 'key % cannot have an array value. Only dates, commands allowed', name;
804830
END IF;
805831

806-
RETURN set_job_attributes(jobId, json_build_object(name, array_to_json(value))::jsonb);
832+
RETURN set_job_attributes(jobId, jsonb_build_object(name, array_to_json(value)));
807833
END
808834
$BODY$
809835
LANGUAGE plpgsql
@@ -815,9 +841,11 @@ DECLARE
815841
attrs jsonb;
816842
BEGIN
817843
IF name = 'dates' OR name = 'commands' THEN
818-
attrs := json_build_object(name, array_to_json(value::text[]));
844+
attrs := jsonb_build_object(name, array_to_json(value::text[]));
845+
ELSIF name = 'rule' THEN
846+
attrs := jsonb_build_object('rule', value::jsonb);
819847
ELSE
820-
attrs := json_build_object(name, value);
848+
attrs := jsonb_build_object(name, value);
821849
END IF;
822850
RETURN set_job_attributes(jobId, attrs);
823851
END
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/perl
2+
use strict;
3+
no warnings;
4+
use Test::Harness;
5+
use DBI;
6+
use Getopt::Long;
7+
8+
my $dbname;
9+
my $username;
10+
my $password;
11+
my $host;
12+
GetOptions ( "--host=s" => \$host,
13+
"--dbname=s" => \$dbname,
14+
"--username=s" => \$username,
15+
"--password=s" => \$password);
16+
17+
print "Prepare test enviroment\n";
18+
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname; host=$host", "$username", "$password",
19+
{PrintError => 0});
20+
if($dbh->err != 0){
21+
print $DBI::errstr . "\n";
22+
exit(-1);
23+
}
24+
25+
my $query = "DROP TABLE IF EXISTS test_results;";
26+
$dbh->do($query);
27+
if($dbh->err != 0){
28+
print $DBI::errstr . "\n";
29+
exit(-1);
30+
}
31+
32+
$query = "CREATE TABLE test_results( time_mark timestamp, commentary text );";
33+
$dbh->do($query);
34+
if($dbh->err != 0){
35+
print $DBI::errstr . "\n";
36+
exit(-1);
37+
}
38+
39+
$query = "DROP ROLE IF EXISTS tester;";
40+
$dbh->do($query);
41+
if($dbh->err != 0){
42+
print $DBI::errstr . "\n";
43+
exit(-1);
44+
}
45+
46+
$query = "CREATE ROLE tester;";
47+
$dbh->do($query);
48+
if($DBI::err != 0){
49+
print $DBI::errstr . "\n";
50+
exit(-1);
51+
}
52+
53+
$query = "GRANT INSERT ON test_results TO tester;";
54+
$dbh->do($query);
55+
if($dbh->err != 0){
56+
print $DBI::errstr . "\n";
57+
exit(-1);
58+
}
59+
60+
$dbh->disconnect();
61+
62+
print "Run tests\n";
63+
my @db_param = ["--host=$host", "--dbname=$dbname", "--username=$username", "--password=$password"];
64+
my %args = (
65+
verbosity => 1,
66+
test_args => @db_param
67+
);
68+
my $harness = TAP::Harness->new( \%args );
69+
my @tests = glob( 't/*.t' );
70+
$harness->runtests(@tests );
71+
72+
73+
74+
75+
76+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/perl
2+
use strict;
3+
no warnings;
4+
use Test::More;
5+
use DBI;
6+
use Getopt::Long;
7+
8+
my $dbname;
9+
my $username;
10+
my $password;
11+
my $host;
12+
GetOptions ( "--host=s" => \$host,
13+
"--dbname=s" => \$dbname,
14+
"--username=s" => \$username,
15+
"--password=s" => \$password);
16+
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname; host=$host", "$username", "$password",
17+
{PrintError => 0});
18+
ok($dbh->err == 0) or (print $DBI::errstr and BAIL_OUT);
19+
20+
my $query = "DELETE FROM test_results;";
21+
$dbh->do($query);
22+
ok($dbh->err == 0) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
23+
24+
$query = "SELECT schedule.create_job(NULL, '');";
25+
my $sth = $dbh->prepare($query);
26+
$sth->execute();
27+
ok($dbh->err == 0) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
28+
my $job_id = $sth->fetchrow_array() and $sth->finish();
29+
$sth->finish();
30+
31+
$query = "SELECT schedule.deactivate_job(?)";
32+
$sth = $dbh->prepare($query);
33+
$sth->bind_param(1, $job_id);
34+
ok($sth->execute()) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
35+
$sth->finish();
36+
37+
$query = "SELECT schedule.set_job_attributes(?, \'{ \"name\": \"Test\",
38+
\"cron\": \"* * * * *\",
39+
\"commands\": [\"INSERT INTO test_results (time_mark, commentary) VALUES(now(), ''createJob'')\",
40+
\"INSERT INTO test_results (time_mark, commentary) VALUES(now(), ''createJob'')\"],
41+
\"run_as\": \"tester\",
42+
\"use_same_transaction\": \"true\"
43+
}\')";
44+
$sth = $dbh->prepare($query);
45+
$sth->bind_param(1, $job_id);
46+
ok($sth->execute()) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
47+
$sth->finish();
48+
49+
$query = "SELECT schedule.activate_job(?)";
50+
$sth = $dbh->prepare($query);
51+
$sth->bind_param(1, $job_id);
52+
ok($sth->execute()) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
53+
$sth->finish();
54+
55+
sleep 120;
56+
$query = "SELECT count(*) FROM test_results";
57+
$sth = $dbh->prepare($query);
58+
ok($sth->execute()) or (print $DBI::errstr and $dbh->disconnect() and BAIL_OUT);
59+
60+
my $result = $sth->fetchrow_array() and $sth->finish();
61+
ok ($result > 1) or print "Count == 0\n";
62+
63+
$query = "SELECT schedule.deactivate_job(?)";
64+
$sth = $dbh->prepare($query);
65+
$sth->bind_param(1, $job_id);
66+
ok($sth->execute()) or print $DBI::errstr ;
67+
$sth->finish();
68+
69+
$query = "DELETE FROM test_results;";
70+
$dbh->do($query);
71+
ok($dbh->err == 0) or print $DBI::errstr;
72+
73+
$query = "SELECT schedule.drop_job(?)";
74+
$sth = $dbh->prepare($query);
75+
$sth->bind_param(1, $job_id);
76+
ok($sth->execute()) or print $DBI::errstr;
77+
$sth->finish();
78+
79+
$dbh->disconnect();
80+
81+
done_testing();

0 commit comments

Comments
 (0)