source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/upgrade.pm @ 2474

Last change on this file since 2474 was 2428, checked in by latmossys, 4 years ago
  • 6.1.2
File size: 59.0 KB
Line 
1package LATMOS::Accounts::Bases::Sql::upgrade;
2
3package LATMOS::Accounts::Bases::Sql;
4
5use strict;
6use warnings;
7use LATMOS::Accounts::Log;
8
9=head1 NAME
10
11    LATMOS::Accounts::Bases::Sql::upgrade
12
13=head1 DESCRIPTION
14
15Upgrade the SQL schema for SQL Base
16
17=head1 FUNCTIONS
18
19=cut
20
21sub _SqlSchemaUpgrade {
22    my ($self) = @_;
23
24    my $rev = $self->get_global_value('schema_version') || 1;
25
26    my @updates = (
27        {
28            ver => 3,
29            sql => [
30                q{ALTER TABLE nethost_attributes_ips DROP CONSTRAINT
31                nethost_is_single_ip},
32                q{DROP TRIGGER IF EXISTS check_zone_name_unity_tg ON nethost},
33                q{DROP TRIGGER IF EXISTS check_zone_name_unity_tg ON netzone},
34                q{DROP FUNCTION IF EXISTS check_zone_name_unity()},
35                q{ALTER TABLE nethost_attributes_ips DROP CONSTRAINT
36                nethost_is_single_ip},
37                q{INSERT INTO settings(varname, val) VALUES ('schema_version', 3)},
38            ],
39        },
40        {
41            ver => 4,
42            sql => [
43                q{
44                CREATE OR REPLACE FUNCTION nethost_sort_fields()
45                RETURNS trigger AS
46                $BODY$BEGIN
47
48                IF (TG_OP='INSERT') then
49                IF (new.attr='ip') THEN
50                insert into nethost_attributes_ips VALUES (new.*);
51                RETURN NULL;
52                END IF;
53
54                IF (new.attr='macaddr') THEN
55                insert into nethost_attributes_macs VALUES (new.*);
56                RETURN NULL;
57                END IF;
58
59                IF (new.attr='owner') THEN
60                insert into nethost_attributes_users VALUES (new.*);
61                RETURN NULL;
62                END IF;
63
64                IF (new.attr='user') THEN
65                insert into nethost_attributes_users VALUES (new.*);
66                RETURN NULL;
67                END IF;
68                end if;
69
70
71                if (TG_OP='DELETE') THEN
72                RETURN old;
73                else
74                RETURN new;
75                end if;
76                END;$BODY$
77                LANGUAGE plpgsql VOLATILE
78                COST 100;
79                },
80            ],
81        },
82        {
83            ver => 5,
84            sql => [
85                q{
86                CREATE OR REPLACE VIEW address_attributes AS
87                ( ( SELECT address."user" AS value, 'user' AS attr, address.rev AS attr_key, address.ikey AS okey
88                FROM address
89                UNION ALL
90                SELECT address.name AS value, 'name' AS attr, address.rev AS attr_key, address.ikey AS okey
91                FROM address )
92                UNION ALL
93                SELECT address_attributes.value, address_attributes.attr, address_attributes.attr_key, address_attributes.okey
94                FROM address_attributes_base address_attributes )
95                UNION ALL
96                SELECT '1' AS value, 'active' AS attr, address.rev AS attr_key, address.ikey AS okey
97                FROM "user" JOIN address ON "user".name = address."user"
98                WHERE "user".exported AND address.exported and
99                ("user".expire IS NULL or "user".expire > now())
100                }
101            ],
102        },
103        {
104            ver => 6,
105            sql => [
106                q{
107                CREATE TABLE request
108                (
109                id serial NOT NULL,
110                "create" timestamp with time zone NOT NULL DEFAULT now(),
111                name text NOT NULL,
112                object text,
113                apply timestamp with time zone NOT NULL DEFAULT now(),
114                done timestamp with time zone,
115                "user" text,
116                CONSTRAINT request_pkey PRIMARY KEY (id ),
117                CONSTRAINT request_name_fkey FOREIGN KEY (name)
118                REFERENCES accreq (name) MATCH SIMPLE
119                ON UPDATE CASCADE ON DELETE CASCADE,
120                CONSTRAINT request_user_fkey FOREIGN KEY ("user")
121                REFERENCES "user" (name) MATCH SIMPLE
122                ON UPDATE CASCADE ON DELETE SET NULL
123                )
124                },
125                q{
126                CREATE INDEX fki_request_name_fkey ON request
127                USING btree (name )
128                },
129                q{
130                CREATE INDEX fki_request_user_fkey ON request
131                USING btree ("user" )
132                },
133                q{
134                CREATE TABLE request_attributes
135                (
136                reqid bigint,
137                attribute text NOT NULL,
138                value text,
139                CONSTRAINT request_id_fkey FOREIGN KEY (reqid)
140                REFERENCES request (id) MATCH SIMPLE
141                ON UPDATE CASCADE ON DELETE CASCADE
142                )
143                },
144                q{
145                CREATE INDEX fki_request_id_fkey ON request_attributes
146                USING btree (reqid )
147                },
148                q{
149                delete from accreq_attributes_list
150                }
151            ],
152        },
153        {
154            ver => 7,
155            sql => [
156                q{
157                ALTER TABLE request ADD COLUMN automated boolean NOT NULL DEFAULT false;
158                },
159                q{
160                ALTER TABLE request ADD COLUMN objrev bigint;
161                },
162                q{
163                ALTER TABLE aliases ADD COLUMN description text;
164                },
165                q{
166                ALTER TABLE revaliases ADD COLUMN description text;
167                },
168                q{
169                CREATE OR REPLACE FUNCTION group_sort_fields()
170                RETURNS trigger AS
171                $BODY$BEGIN
172
173                IF (TG_OP='INSERT') then
174                IF (new.attr='managedBy'
175                OR  new.attr='managedAlsoBy'
176                OR  new.attr='member'
177                OR  new.attr='memberUID') THEN
178                insert into group_attributes_users VALUES (new.*);
179                RETURN NULL;
180                END IF;
181
182                IF (new.attr='sutype') THEN
183                insert into group_attributes_sutypes VALUES (new.*);
184                RETURN NULL;
185                END IF;
186                end if;
187
188
189                IF (TG_OP = 'UPDATE') THEN
190                IF (new.attr='gidNumber') then
191                update "group" set gidnumber = new.value::integer where
192                "group".ikey = new.okey;
193                RETURN NULL;
194                END IF;
195                END IF;
196
197                IF (TG_OP = 'DELETE') THEN
198                IF (old.attr='exported') then
199                update "group" set exported = false where "group".ikey = old.okey;
200                return null;
201                end if;
202                else
203                IF (new.attr='exported') then
204                update "group" set exported = true where "group".ikey = new.okey;
205                RETURN NULL;
206                end if;
207                END IF;
208
209                if (TG_OP='DELETE') THEN
210                RETURN old;
211                else
212                RETURN new;
213                end if;
214                END;$BODY$
215                LANGUAGE plpgsql VOLATILE
216                COST 100;
217                },
218            ],
219        },
220        {
221            ver => 8,
222            sql => [
223                q{
224                CREATE TABLE objectslogs
225                (
226                logkey SERIAL NOT NULL,
227                ikey bigint NOT NULL,
228                irev bigint,
229                otype text NOT NULL,
230                name text NOT NULL,
231                changetype text NOT NULL,
232                username text NOT NULL,
233                message text NOT NULL,
234                logdate timestamp with time zone NOT NULL DEFAULT now(),
235                CONSTRAINT objectlogs_pkey PRIMARY KEY (logkey)
236                );},
237                q{
238                CREATE INDEX objectlogs_name_idx
239                ON objectslogs
240                USING btree
241                (name);
242                },
243                q{
244                CREATE INDEX objectslogs_ikey_idx
245                ON objectslogs
246                USING btree
247                (ikey);
248                },
249                q{
250                CREATE INDEX objectslogs_otype_idx
251                ON objectslogs
252                USING btree
253                (otype);
254                }
255            ],
256        },
257        {
258            ver => 9,
259            sql => [
260                q{
261                CREATE TABLE nethost_attributes_nethosts
262                (
263                CONSTRAINT nethost_attributes_nethosts_pkey PRIMARY KEY (attr_key),
264                CONSTRAINT nethost_attr_nethosts_fkey FOREIGN KEY (okey)
265                REFERENCES nethost (ikey) MATCH SIMPLE
266                ON UPDATE CASCADE ON DELETE CASCADE,
267                CONSTRAINT nethost_attr_nethosts_nethosts FOREIGN KEY ("value")
268                REFERENCES nethost (name) MATCH SIMPLE
269                ON UPDATE CASCADE ON DELETE CASCADE
270                )
271                INHERITS (nethost_attributes);
272
273                CREATE INDEX fki_nethost_attr_nethosts_fkey
274                ON nethost_attributes_nethosts
275                USING btree
276                (okey);
277
278                CREATE TRIGGER nethost_attr_nethosts_update
279                AFTER INSERT OR UPDATE OR DELETE
280                ON nethost_attributes_nethosts
281                FOR EACH ROW
282                EXECUTE PROCEDURE nethost_attr_update_ref();
283
284
285                CREATE OR REPLACE FUNCTION nethost_sort_fields()
286                RETURNS trigger AS
287                $BODY$BEGIN
288
289                IF (TG_OP='INSERT') then
290                IF (new.attr='ip') THEN
291                insert into nethost_attributes_ips VALUES (new.*);
292                RETURN NULL;
293                END IF;
294
295                IF (new.attr='macaddr') THEN
296                insert into nethost_attributes_macs VALUES (new.*);
297                RETURN NULL;
298                END IF;
299
300                IF (new.attr='owner') THEN
301                insert into nethost_attributes_users VALUES (new.*);
302                RETURN NULL;
303                END IF;
304
305                IF (new.attr='user') THEN
306                insert into nethost_attributes_users VALUES (new.*);
307                RETURN NULL;
308                END IF;
309
310                IF (new.attr='related') THEN
311                insert into nethost_attributes_nethosts VALUES (new.*);
312                RETURN NULL;
313                END IF;
314                end if;
315
316                if (TG_OP='DELETE') THEN
317                RETURN old;
318                else
319                RETURN new;
320                end if;
321                END;$BODY$
322                LANGUAGE plpgsql VOLATILE
323                COST 100;
324
325                }
326            ],
327        },
328        {
329            ver => 10,
330            sql => [
331                q{
332                CREATE OR REPLACE FUNCTION service_attr_update_ref()
333                RETURNS trigger AS
334                $BODY$begin
335
336                IF (TG_OP != 'INSERT') then
337                update "service" set date = now() where "service".ikey = old.okey;
338                end if;
339                IF (TG_OP != 'DELETE') then
340                update "service"  set date = now() where "service".ikey = new.okey;
341                end if;
342
343                IF (TG_OP = 'DELETE') then
344                return old;
345                ELSE
346                return new;
347                END IF;
348
349                END;$BODY$
350                LANGUAGE plpgsql VOLATILE
351                COST 100;
352                },
353                q{
354
355                CREATE TABLE service
356                (
357                "start" date,
358                "end" date,
359                CONSTRAINT service_pkey PRIMARY KEY (name),
360                CONSTRAINT service_ikey_uniq UNIQUE (ikey)
361                )
362                INHERITS (objects);
363                },
364                q{
365                CREATE TABLE service_attributes_list
366                (
367                ikey integer NOT NULL DEFAULT nextval('ikey_seq'::regclass),
368                canonical text NOT NULL,
369                description text,
370                CONSTRAINT service_attributes_list_pkey PRIMARY KEY (ikey),
371                CONSTRAINT g_attr_l_service_uniq UNIQUE (canonical)
372                )
373                INHERITS (revisions, attributes_list)
374                WITH (
375                OIDS=FALSE
376                );
377
378                CREATE TABLE service_attributes
379                (
380                CONSTRAINT service_attributes_pkey PRIMARY KEY (attr_key),
381                CONSTRAINT service_attr_users_okey_fkey FOREIGN KEY (okey)
382                REFERENCES service (ikey) MATCH SIMPLE
383                ON UPDATE CASCADE ON DELETE CASCADE,
384                CONSTRAINT service_attributes_attr_fkey FOREIGN KEY (attr)
385                REFERENCES service_attributes_list (canonical) MATCH SIMPLE
386                ON UPDATE CASCADE ON DELETE NO ACTION
387                )
388                INHERITS (attributes)
389                WITH (
390                OIDS=FALSE
391                );
392
393                CREATE INDEX fki_service_attributes_attr_fkey
394                ON nethost_attributes
395                USING btree
396                (attr);
397
398                CREATE INDEX service_attr_value_idx
399                ON nethost_attributes
400                USING btree
401                (value);
402
403                CREATE TRIGGER serivce_attr_update
404                AFTER INSERT OR UPDATE OR DELETE
405                ON service_attributes
406                FOR EACH ROW
407                EXECUTE PROCEDURE service_attr_update_ref();
408                },
409                q{
410                CREATE TABLE service_attributes_users
411                (
412                CONSTRAINT service_attributes_user_pkey PRIMARY KEY (attr_key),
413                CONSTRAINT service_attr_users_okey_fkey FOREIGN KEY (okey)
414                REFERENCES service (ikey) MATCH SIMPLE
415                ON UPDATE CASCADE ON DELETE CASCADE,
416                CONSTRAINT service_attributes_users_attr_fkey FOREIGN KEY (attr)
417                REFERENCES service_attributes_list (canonical) MATCH SIMPLE
418                ON UPDATE CASCADE ON DELETE NO ACTION,
419                CONSTRAINT service_attributes_users_user_fkey FOREIGN KEY (value)
420                REFERENCES "user" (name) MATCH SIMPLE
421                ON UPDATE CASCADE ON DELETE CASCADE,
422                CONSTRAINT service_attributes_users_uniq UNIQUE (okey, attr, value)
423                )
424                INHERITS (service_attributes);
425
426                CREATE INDEX fki_service_attr_users_okey_fkey
427                ON service_attributes_users
428                USING btree
429                (okey);
430
431                CREATE INDEX fki_service_attributes_users_attr_fkey
432                ON service_attributes_users
433                USING btree
434                (attr);
435
436                CREATE INDEX fki_service_attributes_users_user_fkey
437                ON service_attributes_users
438                USING btree
439                (value);
440
441                CREATE TRIGGER service_attributes_users_update_ref
442                AFTER INSERT OR UPDATE OR DELETE
443                ON service_attributes_users
444                FOR EACH ROW
445                EXECUTE PROCEDURE service_attr_update_ref();
446
447                CREATE OR REPLACE FUNCTION service_sort_fields()
448                RETURNS trigger AS
449                $BODY$BEGIN
450
451                if (TG_OP='INSERT' or TG_OP='UPDATE') THEN
452                IF (new.attr='manager') THEN
453                insert into service_attributes_users VALUES (new.*);
454                RETURN NULL;
455                END IF;
456                END IF;
457
458                if (TG_OP='DELETE') THEN
459                RETURN old;
460                else
461                RETURN new;
462                end if;
463                END;$BODY$
464                LANGUAGE plpgsql VOLATILE
465                COST 100;
466
467                CREATE TRIGGER service_sort_field_tg
468                BEFORE INSERT OR UPDATE OR DELETE
469                ON service_attributes
470                FOR EACH ROW
471                EXECUTE PROCEDURE service_sort_fields();
472
473                CREATE TRIGGER service_rev_tg
474                BEFORE INSERT OR UPDATE OR DELETE
475                ON service
476                FOR EACH ROW
477                EXECUTE PROCEDURE rev_tg_f();
478                },
479            ],
480        },
481        {
482            ver => 11,
483            sql => [
484                q{
485                ALTER TABLE "user" ADD COLUMN endcircuit timestamp with time zone
486                }
487            ],
488        },
489        {
490            ver => 12,
491            sql => [
492                q{
493                CREATE OR REPLACE VIEW user_attributes AS
494                (        (        (        (        (        (        (        (        (        (        (
495                SELECT "user".uidnumber::text AS value, 'uidnumber' AS attr, "user".rev AS attr_key, "user".ikey AS okey FROM "user"
496                UNION ALL
497                SELECT "user".gidnumber::text AS value, 'gidnumber' AS attr, "user".rev AS attr_key, "user".ikey AS okey FROM "user")
498                UNION ALL
499                SELECT "user".name AS value, 'name' AS attr, "user".rev AS attr_key, "user".ikey AS okey FROM "user")
500                UNION ALL
501                SELECT "user".expire::text AS value, 'expire' AS attr, "user".rev AS attr_key, "user".ikey AS okey FROM "user"
502                WHERE "user".expire IS NOT NULL)
503                UNION ALL
504                SELECT '1'::text AS value, 'exported' AS attr, "user".rev AS attr_key, "user".ikey AS okey
505                FROM "user"
506                WHERE "user".exported = true)
507                UNION ALL
508                SELECT address_attributes_site.value, 'allsite' AS attr, "user".rev AS attr_key, "user".ikey AS okey
509                FROM "user"
510                JOIN address ON address."user" = "user".name
511                JOIN address_attributes_site ON address_attributes_site.okey = address.ikey
512                WHERE address_attributes_site.attr = 'site'::text AND address.exported = true)
513                UNION ALL
514                SELECT "group".name AS value, 'memberOf' AS attr, "user".rev AS attr_key, "user".ikey AS okey
515                FROM "user"
516                JOIN group_attributes ON group_attributes.value = "user".name
517                JOIN "group" ON group_attributes.okey = "group".ikey
518                WHERE group_attributes.attr = 'memberUID'::text)
519                UNION ALL
520                SELECT user_attributes.value, user_attributes.attr, user_attributes.attr_key, user_attributes.okey
521                FROM user_attributes_base user_attributes)
522                UNION ALL
523                SELECT "group".name AS value, 'departments' AS attr, "user".rev AS attr_key, "user".ikey AS okey
524                FROM "group"
525                JOIN group_attributes_sutypes ON "group".ikey = group_attributes_sutypes.okey
526                JOIN group_attributes_users ON "group".ikey = group_attributes_users.okey AND group_attributes_users.attr = 'memberUID'::text
527                JOIN "user" ON "user".name = group_attributes_users.value
528                WHERE group_attributes_sutypes.value = 'dpmt'::text AND group_attributes_sutypes.attr = 'sutype'::text)
529                UNION ALL
530                SELECT "group".name AS value, 'cells' AS attr, "user".rev AS attr_key, "user".ikey AS okey
531                FROM "group"
532                JOIN group_attributes_sutypes ON "group".ikey = group_attributes_sutypes.okey
533                JOIN group_attributes_users ON "group".ikey = group_attributes_users.okey AND group_attributes_users.attr = 'memberUID'::text
534                JOIN "user" ON "user".name = group_attributes_users.value
535                WHERE group_attributes_sutypes.value = 'cell'::text AND group_attributes_sutypes.attr = 'sutype'::text)
536                UNION ALL
537                SELECT "group".name AS value, 'managedObjects' AS attr, "user".rev AS attr_key, "user".ikey AS okey
538                FROM "user"
539                JOIN group_attributes ON group_attributes.value = "user".name
540                JOIN "group" ON group_attributes.okey = "group".ikey
541                WHERE group_attributes.attr = 'managedBy'::text)
542                UNION ALL
543                SELECT justify_interval(now() - "user".expire)::text AS value, 'expired' AS attr, "user".rev AS attr_key, "user".ikey AS okey
544                FROM "user"
545                WHERE "user".expire <= now())
546                UNION ALL
547                SELECT 1::text AS value, 'active' AS attr, "user".rev AS attr_key, "user".ikey AS okey
548                FROM "user"
549                WHERE ("user".expire IS NULL OR "user".expire >= now()) AND "user".exported = true
550                UNION ALL
551                SELECT 0::text AS value, 'active' AS attr, "user".rev AS attr_key, "user".ikey AS okey
552                FROM "user"
553                WHERE ("user".expire IS NOT NULL and "user".expire <= now()) or "user".exported = false;
554                },
555                q{
556                CREATE OR REPLACE FUNCTION rev_tg_aliases_f()
557                RETURNS trigger AS
558                $BODY$begin
559
560                IF (TG_OP = 'DELETE') THEN
561                update "user" set rev = nextval('revisions_rev_seq'::regclass), "date" = now() where "name" = ANY (old.forward);
562                return old;
563                ELSE
564                IF (TG_OP = 'UPDATE') THEN
565                update "user" set rev = nextval('revisions_rev_seq'::regclass), "date" = now() where "name" = ANY (old.forward);
566                END IF;
567                update "user" set rev = nextval('revisions_rev_seq'::regclass), "date" = now() where "name" = ANY (new.forward);
568                return new;
569                END IF;
570
571                end;$BODY$
572                LANGUAGE plpgsql VOLATILE
573                COST 100;
574
575                CREATE TRIGGER aliases_user_tg
576                AFTER INSERT OR UPDATE OR DELETE
577                ON aliases
578                FOR EACH ROW
579                EXECUTE PROCEDURE rev_tg_aliases_f();
580                },
581            ],
582        },
583        {
584            ver => 13,
585            sql => [
586                q{
587                CREATE TABLE "stat"
588                (
589                name text NOT NULL,
590                CONSTRAINT stat_pkey PRIMARY KEY (name),
591                CONSTRAINT stat_okey_uniq UNIQUE (ikey)
592                )
593                INHERITS (objects);
594                CREATE INDEX stat_exported_idx
595                ON stat USING btree (exported);
596                CREATE UNIQUE INDEX stat_rev_idx
597                ON stat USING btree (rev);
598
599                CREATE OR REPLACE FUNCTION stat_attr_update_ref()
600                RETURNS trigger AS
601                $BODY$begin
602
603                IF (TG_OP != 'INSERT') then
604                update "stat" set date = now() where "stat".ikey = old.okey;
605                end if;
606                IF (TG_OP != 'DELETE') then
607                update "stat"  set date = now() where "stat".ikey = new.okey;
608                end if;
609
610                IF (TG_OP = 'DELETE') then
611                return old;
612                ELSE
613                return new;
614                END IF;
615
616                END;$BODY$
617                LANGUAGE plpgsql VOLATILE
618                COST 100;
619                },
620                q{
621                CREATE TABLE stat_attributes
622                (
623                CONSTRAINT stat_attributes_pkey PRIMARY KEY (attr_key),
624                CONSTRAINT stat FOREIGN KEY (okey)
625                REFERENCES stat (ikey) MATCH SIMPLE
626                ON UPDATE CASCADE ON DELETE CASCADE
627                )
628                INHERITS (attributes);
629                CREATE INDEX stat_attributes_attr_fkey
630                ON stat_attributes
631                USING btree
632                (attr);
633                CREATE INDEX stat_attr_value_idx
634                ON stat_attributes
635                USING btree
636                (value);
637                CREATE TRIGGER stat_attr_update
638                AFTER INSERT OR UPDATE OR DELETE
639                ON stat_attributes
640                FOR EACH ROW
641                EXECUTE PROCEDURE stat_attr_update_ref();
642                },
643                q{
644                CREATE TABLE stat_attributes_list
645                (
646                CONSTRAINT stat_attr_list_pkey PRIMARY KEY (ikey),
647                CONSTRAINT stat_attr_l_c_uniq UNIQUE (canonical)
648                )
649                INHERITS (revisions, attributes_list);
650                },
651                q{
652                CREATE TABLE statsentry
653                (
654                okey integer NOT NULL,
655                id bigint NOT NULL DEFAULT nextval('revisions_rev_seq'::regclass),
656                tstamp timestamp with time zone NOT NULL DEFAULT now(),
657                CONSTRAINT stat FOREIGN KEY (okey)
658                REFERENCES stat (ikey) MATCH SIMPLE
659                ON UPDATE CASCADE ON DELETE CASCADE,
660                CONSTRAINT statsentry_pkey PRIMARY KEY (id)
661                );
662                CREATE TABLE statvalues
663                (
664                sid bigint NOT NULL,
665                value text NOT NULL,
666                count bigint NOT NULL,
667                CONSTRAINT statvalues_pkey PRIMARY KEY (sid, value),
668                CONSTRAINT statvalues_fkey FOREIGN KEY (sid)
669                REFERENCES statsentry (id) MATCH SIMPLE
670                ON UPDATE CASCADE ON DELETE CASCADE
671                )
672                },
673            ],
674        },
675        {
676            ver => 14,
677            sql => [
678                q{
679                ALTER TABLE objects ADD COLUMN createdby text;
680                },
681                q{
682                ALTER TABLE objects ADD COLUMN modifiedby text;
683                },
684            ],
685        },
686        {
687            ver => 15,
688            sql => [
689                q{
690                CREATE TABLE "employment"
691                (
692                name text NOT NULL,
693                "user" text NOT NULL,
694                firstday date NOT NULL default now(),
695                lastday  date,
696                CONSTRAINT employment_pkey PRIMARY KEY (name),
697                CONSTRAINT employment_okey_uniq UNIQUE (ikey),
698                CONSTRAINT employment_user_fkey FOREIGN KEY ("user")
699                REFERENCES "user" (name) MATCH SIMPLE
700                ON UPDATE CASCADE ON DELETE CASCADE
701                )
702                INHERITS (objects);
703                CREATE INDEX employment_exported_idx
704                ON employment USING btree (exported);
705                CREATE UNIQUE INDEX employment_rev_idx
706                ON employment USING btree (rev);
707
708                CREATE OR REPLACE FUNCTION employment_attr_update_ref()
709                RETURNS trigger AS
710                $BODY$begin
711
712                IF (TG_OP != 'INSERT') then
713                update "employment" set date = now() where "employment".ikey = old.okey;
714                end if;
715                IF (TG_OP != 'DELETE') then
716                update "employment"  set date = now() where "employment".ikey = new.okey;
717                end if;
718
719                IF (TG_OP = 'DELETE') then
720                return old;
721                ELSE
722                return new;
723                END IF;
724
725                END;$BODY$
726                LANGUAGE plpgsql VOLATILE
727                COST 100;
728                },
729                q{
730                CREATE TABLE employment_attributes
731                (
732                CONSTRAINT employment_attributes_pkey PRIMARY KEY (attr_key),
733                CONSTRAINT employment FOREIGN KEY (okey)
734                REFERENCES employment (ikey) MATCH SIMPLE
735                ON UPDATE CASCADE ON DELETE CASCADE
736                )
737                INHERITS (attributes);
738                CREATE INDEX employment_attributes_attr_fkey
739                ON employment_attributes
740                USING btree
741                (attr);
742                CREATE INDEX employment_attr_value_idx
743                ON employment_attributes
744                USING btree
745                (value);
746                CREATE TRIGGER employment_attr_update
747                AFTER INSERT OR UPDATE OR DELETE
748                ON employment_attributes
749                FOR EACH ROW
750                EXECUTE PROCEDURE employment_attr_update_ref();
751                },
752                q{
753                CREATE TABLE employment_attributes_list
754                (
755                CONSTRAINT employment_attr_list_pkey PRIMARY KEY (ikey),
756                CONSTRAINT employment_attr_l_c_uniq UNIQUE (canonical)
757                )
758                INHERITS (revisions, attributes_list);
759                },
760                q{
761                CREATE INDEX employment_firstday_idx
762                ON employment
763                USING btree
764                (firstday NULLS FIRST);
765                CREATE INDEX employment_lastday_idx
766                ON employment
767                USING btree
768                (lastday NULLS LAST);
769                },
770            ],
771        },
772        {
773            ver => 16,
774            sql => [
775                q{
776                ALTER TABLE aliases
777                ADD CONSTRAINT aliases_ikey_uniq UNIQUE(ikey);
778                CREATE OR REPLACE FUNCTION aliases_attr_update_ref()
779                RETURNS trigger AS
780                $BODY$begin
781
782                IF (TG_OP != 'INSERT') then
783                update "aliases" set date = now() where "aliases".ikey = old.okey;
784                end if;
785                IF (TG_OP != 'DELETE') then
786                update "aliases"  set date = now() where "aliases".ikey = new.okey;
787                end if;
788
789                IF (TG_OP = 'DELETE') then
790                return old;
791                ELSE
792                return new;
793                END IF;
794
795                END;$BODY$
796                LANGUAGE plpgsql VOLATILE
797                COST 100;
798                },
799                q{
800                CREATE TABLE aliases_attributes_base
801                (
802                CONSTRAINT aliases_attributes_base_pkey PRIMARY KEY (attr_key),
803                CONSTRAINT aliases_fkey FOREIGN KEY (okey)
804                REFERENCES aliases (ikey) MATCH SIMPLE
805                ON UPDATE CASCADE ON DELETE CASCADE
806                )
807                INHERITS (attributes);
808                CREATE INDEX aliases_attributes_base_attr_fkey
809                ON aliases_attributes_base
810                USING btree
811                (attr);
812                CREATE INDEX aliases_attr_value_idx
813                ON aliases_attributes_base
814                USING btree
815                (value);
816                CREATE TRIGGER aliases_attr_update
817                AFTER INSERT OR UPDATE OR DELETE
818                ON aliases_attributes_base
819                FOR EACH ROW
820                EXECUTE PROCEDURE aliases_attr_update_ref();
821                },
822                q{
823                CREATE OR REPLACE VIEW aliases_attributes AS
824                SELECT "user".name AS value,
825                'user'::text AS attr,
826                aliases.rev AS attr_key,
827                aliases.ikey AS okey
828                FROM aliases
829                JOIN "user" ON aliases.name = "user".name OR aliases.forward = ARRAY["user".name]
830                union all
831                select value, attr, attr_key, okey from aliases_attributes_base
832                UNION ALL
833                SELECT "aliases".name AS value,
834                'name'::text AS attr,
835                "aliases".rev AS attr_key,
836                "aliases".ikey AS okey
837                FROM "aliases";
838
839                CREATE OR REPLACE RULE aliases_attributes_insert AS
840                ON INSERT TO aliases_attributes DO INSTEAD  INSERT INTO aliases_attributes_base (value, attr, okey)
841                VALUES (new.value, new.attr, new.okey);
842
843                CREATE OR REPLACE RULE aliases_attributes_update AS
844                ON UPDATE TO aliases_attributes DO INSTEAD  UPDATE aliases_attributes_base SET value = new.value, attr = new.attr, okey = new.okey
845                WHERE aliases_attributes_base.attr_key = old.attr_key AND aliases_attributes_base.attr = old.attr;
846
847                CREATE OR REPLACE RULE aliases_atttributes_delete AS
848                ON DELETE TO aliases_attributes DO INSTEAD  DELETE FROM aliases_attributes_base
849                WHERE aliases_attributes_base.attr_key = old.attr_key AND aliases_attributes_base.attr = old.attr;
850                }
851
852            ],
853        },
854        {
855            ver => 17,
856            sql => [
857                q{
858                CREATE TABLE passwordreset
859                (
860                -- Hérité(e) from table revisions:  rev integer NOT NULL DEFAULT nextval('revisions_rev_seq'::regclass),
861                -- Hérité(e) from table revisions:  date timestamp with time zone NOT NULL DEFAULT now(),
862                -- Hérité(e) from table revisions:  "create" timestamp with time zone NOT NULL DEFAULT now(),
863                -- Hérité(e) from table revisions:  ikey integer NOT NULL DEFAULT nextval('ikey_seq'::regclass),
864                "user" text NOT NULL,
865                id text NOT NULL,
866                CONSTRAINT passwordreset_pkey PRIMARY KEY (id),
867                CONSTRAINT password_reset_user_fkey FOREIGN KEY ("user")
868                REFERENCES "user" (name) MATCH SIMPLE
869                ON UPDATE CASCADE ON DELETE CASCADE
870                )
871                INHERITS (revisions)
872                WITH (
873                OIDS=FALSE
874                );
875                },
876            ],
877        },
878        {
879            ver => 18,
880            sql => [
881                q{
882                ALTER TABLE employment
883                ADD CHECK (lastday is null or firstday <= lastday);
884                }
885            ],
886        },
887        {
888            ver => 19,
889            sql => [
890                q{
891                ALTER TABLE "nethost" ADD COLUMN expire timestamp with time zone;
892                }
893            ],
894        },
895        {
896            ver => 20,
897            sql => [
898                q{
899                CREATE OR REPLACE VIEW user_attributes AS
900                SELECT "user".uidnumber::text AS value, 'uidnumber' AS attr, "user".rev AS attr_key, "user".ikey AS okey
901                FROM "user"
902                UNION ALL
903                SELECT "user".gidnumber::text AS value, 'gidnumber' AS attr, "user".rev AS attr_key, "user".ikey AS okey
904                FROM "user"
905                UNION ALL
906                SELECT "user".name AS value, 'name' AS attr, "user".rev AS attr_key, "user".ikey AS okey
907                FROM "user"
908                UNION ALL
909                SELECT "user".expire::text AS value, 'expire' AS attr, "user".rev AS attr_key, "user".ikey AS okey
910                FROM "user"
911                WHERE "user".expire IS NOT NULL
912                UNION ALL
913                SELECT '1'::text AS value, 'exported' AS attr, "user".rev AS attr_key, "user".ikey AS okey
914                FROM "user"
915                WHERE "user".exported = true
916                UNION ALL
917                SELECT address_attributes_site.value, 'allsite' AS attr, "user".rev AS attr_key, "user".ikey AS okey
918                FROM "user"
919                JOIN address ON address."user" = "user".name
920                JOIN address_attributes_site ON address_attributes_site.okey = address.ikey
921                WHERE address_attributes_site.attr = 'site'::text AND address.exported = true
922                UNION ALL
923                SELECT "group".name AS value, 'memberOf' AS attr, "user".rev AS attr_key, "user".ikey AS okey
924                FROM "user"
925                JOIN group_attributes ON group_attributes.value = "user".name
926                JOIN "group" ON group_attributes.okey = "group".ikey
927                WHERE group_attributes.attr = 'memberUID'::text
928                UNION ALL
929                SELECT user_attributes.value, user_attributes.attr, user_attributes.attr_key, user_attributes.okey
930                FROM user_attributes_base user_attributes
931                UNION ALL
932                SELECT "group".name AS value, 'departments' AS attr, "user".rev AS attr_key, "user".ikey AS okey
933                FROM "group"
934                JOIN group_attributes_sutypes ON "group".ikey = group_attributes_sutypes.okey
935                JOIN group_attributes_users ON "group".ikey = group_attributes_users.okey AND group_attributes_users.attr = 'memberUID'::text
936                JOIN "user" ON "user".name = group_attributes_users.value
937                WHERE group_attributes_sutypes.value = 'dpmt'::text AND group_attributes_sutypes.attr = 'sutype'::text
938                UNION ALL
939                SELECT "group".name AS value, 'cells' AS attr, "user".rev AS attr_key, "user".ikey AS okey
940                FROM "group"
941                JOIN group_attributes_sutypes ON "group".ikey = group_attributes_sutypes.okey
942                JOIN group_attributes_users ON "group".ikey = group_attributes_users.okey AND group_attributes_users.attr = 'memberUID'::text
943                JOIN "user" ON "user".name = group_attributes_users.value
944                WHERE group_attributes_sutypes.value = 'cell'::text AND group_attributes_sutypes.attr = 'sutype'::text
945                UNION ALL
946                SELECT "group".name AS value, 'managedObjects' AS attr, "user".rev AS attr_key, "user".ikey AS okey
947                FROM "user"
948                JOIN group_attributes ON group_attributes.value = "user".name
949                JOIN "group" ON group_attributes.okey = "group".ikey
950                WHERE group_attributes.attr = 'managedBy'::text
951                UNION ALL
952                SELECT justify_interval(now() - "user".expire)::text AS value, 'expired' AS attr, "user".rev AS attr_key, "user".ikey AS okey
953                FROM "user"
954                WHERE "user".expire <= now()
955                UNION ALL
956                SELECT 1::text AS value, 'active' AS attr, "user".rev AS attr_key, "user".ikey AS okey
957                FROM "user"
958                WHERE ("user".expire IS NULL OR "user".expire >= now()) AND "user".exported = true
959                UNION ALL
960                SELECT 0::text AS value, 'active' AS attr, "user".rev AS attr_key, "user".ikey AS okey
961                FROM "user"
962                WHERE "user".expire IS NOT NULL AND "user".expire <= now() OR "user".exported = false
963                UNION ALL
964                SELECT CASE WHEN "user".exported = false THEN 'unexported'
965                WHEN "user".expire IS NOT NULL AND "user".expire <= now() THEN 'expired'
966                ELSE 'active' END AS value, 'status' AS attr, "user".rev AS attr_key, "user".ikey AS okey
967                FROM "user"
968                ;
969
970                }
971            ],
972        },
973        {
974            ver => 21,
975            sql => [
976                'ALTER TABLE objects ADD COLUMN oalias text',
977                'ALTER TABLE objects
978                ADD COLUMN nodelete boolean NOT NULL DEFAULT false',
979                'ALTER TABLE objects
980                ADD COLUMN internobject boolean NOT NULL DEFAULT false',
981            ],
982        },
983        {
984            ver => 22,
985            sql => [
986                'CREATE INDEX fki_employment
987                ON employment_attributes
988                USING btree (okey);'
989            ],
990        },
991        {
992            ver => 23,
993            sql => [
994                'ALTER TABLE address ADD COLUMN expire timestamp with time zone'
995            ],
996        },
997        {
998            ver => 24,
999            sql => [
1000                    q{
1001                    CREATE OR REPLACE FUNCTION user_sort_fields()
1002                    RETURNS trigger AS
1003                    $BODY$DECLARE
1004                    rec RECORD;
1005                    BEGIN
1006
1007                    IF (TG_OP='UPDATE' or TG_OP='INSERT') THEN
1008
1009                    IF (new.attr='locked') THEN
1010                    IF (TG_OP = 'INSERT') THEN
1011                    new.value = now()::text;
1012                    ELSIF (TG_OP='UPDATE') THEN
1013                    new.value = old.value;
1014                    END IF;
1015                    END IF;
1016
1017                    IF (new.attr='nickname') THEN
1018                    PERFORM 1 from "user" where "user".ikey = new.okey
1019                        and new.value = "user".name;
1020                    IF NOT FOUND THEN
1021                    select aliases.name into rec from aliases join "user"
1022                    on array["user".name] = aliases.forward
1023                    where "user".ikey = new.okey and aliases.name = new.value;
1024                    IF NOT FOUND THEN
1025                    insert into aliases ("name", "forward", "description", exported)
1026                    select new.value, array["user".name], 'Forward for ' || "user".name || ' nickname', "user".exported from "user" where "user".ikey = new.okey;
1027                    END IF;
1028                    END IF;
1029                    END IF;
1030
1031                    IF (new.attr='uidNumber') THEN
1032                    update "user" set uidnumber = new.value::integer where ikey = new.okey;
1033                    RETURN NULL;
1034                    END IF;
1035
1036                    IF (new.attr='gidNumber') THEN
1037                    update "user" set gidnumber = new.value::integer where ikey = new.okey;
1038                    RETURN null;
1039                    END IF;
1040
1041                    IF (new.attr='expire') THEN
1042                    update "user" set expire = new.value::timestamp where ikey = new.okey;
1043                    RETURN NULL;
1044                    END IF;
1045
1046                    IF (new.attr='exported') THEN
1047                    update "user" set exported = true where ikey = new.okey;
1048                    RETURN NULL;
1049                    END IF;
1050
1051                    END IF;
1052
1053                    IF (TG_OP = 'DELETE') THEN
1054
1055                    IF (old.attr='expire') THEN
1056                    update "user" set expire = NULL where ikey = old.okey;
1057                    RETURN NULL;
1058                    END IF;
1059
1060                    IF (old.attr='exported') THEN
1061                    update "user" set exported = false where ikey = old.okey;
1062                    RETURN NULL;
1063                    END IF;
1064
1065                    END IF;
1066
1067
1068                    IF (TG_OP='INSERT') THEN
1069                    IF (new.attr='manager') THEN
1070                    insert into user_attributes_users VALUES (new.*);
1071                    RETURN NULL;
1072                    END IF;
1073
1074                    IF (new.attr='site') THEN
1075                    insert into user_attributes_site VALUES (new.*);
1076                    RETURN NULL;
1077                    END IF;
1078
1079                    IF (new.attr='department') THEN
1080                    insert into user_attributes_groups VALUES (new.*);
1081                    RETURN NULL;
1082                    END IF;
1083
1084                    IF (new.attr='contratType') THEN
1085                    insert into user_attributes_groups VALUES (new.*);
1086                    RETURN NULL;
1087                    END IF;
1088
1089                    IF (new.attr='jobType') THEN
1090                    insert into user_attributes_groups VALUES (new.*);
1091                    RETURN NULL;
1092                    END IF;
1093
1094                    END IF;
1095
1096                    IF (TG_OP='DELETE') then
1097                    RETURN old;
1098                    ELSE
1099                    RETURN new;
1100                    end if;
1101                    END;$BODY$
1102                    LANGUAGE plpgsql VOLATILE
1103                    COST 100;
1104                },
1105            ],
1106        },
1107        {
1108            ver => 25,
1109            sql => [
1110                'ALTER TABLE objects ADD COLUMN oaliascache text',
1111            ],
1112        },
1113        {
1114            ver => '26',
1115            sql => [ ],
1116        },
1117        {
1118            ver => 27,
1119            sql => [
1120                q{
1121                CREATE OR REPLACE VIEW nethost_attributes_netzone AS
1122                SELECT netzone.name AS value, 'netZone' AS attr, nethost_attributes_ips.attr_key, nethost_attributes_ips.okey
1123                FROM nethost_attributes_ips, netzone_attributes, netzone
1124                WHERE netzone.ikey = netzone_attributes.okey AND netzone_attributes.attr = 'net'::text AND nethost_attributes_ips.value::inet <<= netzone_attributes.value::inet
1125                EXCEPT
1126                SELECT netzone.name AS value, 'netZone' AS attr, nethost_attributes_ips.attr_key, nethost_attributes_ips.okey
1127                FROM nethost_attributes_ips, netzone_attributes, netzone
1128                WHERE netzone.ikey = netzone_attributes.okey AND netzone_attributes.attr = 'netExclude'::text AND nethost_attributes_ips.value::inet <<= netzone_attributes.value::inet;
1129                },
1130                q{
1131                CREATE OR REPLACE VIEW nethost_attributes_read AS
1132                SELECT nethost_attributes.value, nethost_attributes.attr, nethost_attributes.attr_key, nethost_attributes.okey
1133                FROM nethost_attributes
1134                UNION
1135                SELECT nethost_attributes_netzone.value, nethost_attributes_netzone.attr, nethost_attributes_netzone.attr_key, nethost_attributes_netzone.okey
1136                FROM nethost_attributes_netzone;
1137                }
1138            ],
1139        },
1140        {
1141            ver => 28,
1142            sql => [
1143                q{
1144                CREATE TABLE attributes_values
1145                (
1146                -- Hérité(e) from table revisions:  rev integer NOT NULL DEFAULT nextval('revisions_rev_seq'::regclass),
1147                -- Hérité(e) from table revisions:  date timestamp with time zone NOT NULL DEFAULT now(),
1148                -- Hérité(e) from table revisions:  "create" timestamp with time zone NOT NULL DEFAULT now(),
1149                -- Hérité(e) from table revisions:  ikey integer NOT NULL DEFAULT nextval('ikey_seq'::regclass),
1150                otype text NOT NULL,
1151                attributes text NOT NULL,
1152                value text NOT NULL,
1153                CONSTRAINT attributes_values_pkey PRIMARY KEY (ikey)
1154                )
1155                INHERITS (revisions);
1156
1157                CREATE UNIQUE INDEX attributes_values_idx
1158                ON attributes_values
1159                USING btree
1160                (otype, attributes, value);
1161                }
1162            ]
1163        },
1164        {
1165            ver => 29,
1166            sql => [
1167                q{
1168                ALTER TABLE objectslogs
1169                   ADD COLUMN parentotype text;
1170                ALTER TABLE objectslogs
1171                   ADD COLUMN parentname text;
1172                ALTER TABLE objectslogs
1173                   ADD COLUMN parentikey bigint;
1174                CREATE INDEX objectslogs_parentotype_idx
1175                    ON public.objectslogs
1176                    USING btree (parentotype);
1177                CREATE INDEX objectslogs_parentname_idx
1178                    ON objectslogs
1179                    USING btree (parentname);
1180                CREATE INDEX objectslogs_parentikey_idx
1181                    ON objectslogs
1182                    USING btree (parentikey);
1183                }
1184            ],
1185        },
1186        {
1187            ver => 30,
1188            recompute => 1,
1189        },
1190        {
1191            ver => 31,
1192            sql => [
1193                q{
1194                DROP TABLE attributes_list CASCADE;
1195                }
1196            ],
1197        },
1198        {
1199            ver => 32,
1200            recompute => 1,
1201        },
1202        {
1203            ver => 33,
1204            sql => [
1205                q{
1206                CREATE OR REPLACE FUNCTION public.group_sort_fields() RETURNS trigger AS
1207            $BODY$BEGIN
1208
1209              IF (TG_OP='INSERT') then
1210              IF (new.attr='managedBy'
1211                  OR  new.attr='managedAlsoBy'
1212                  OR  new.attr='member'
1213                  OR  new.attr='memberUID'
1214                  OR  new.attr='autoExclude'
1215                  OR  new.attr='autoInclude') THEN
1216              insert into group_attributes_users VALUES (new.*);
1217              RETURN NULL;
1218              END IF;
1219
1220              IF (new.attr='sutype') THEN
1221              insert into group_attributes_sutypes VALUES (new.*);
1222              RETURN NULL;
1223              END IF;
1224              end if;
1225
1226
1227              IF (TG_OP = 'UPDATE') THEN
1228              IF (new.attr='gidNumber') then
1229              update "group" set gidnumber = new.value::integer where
1230              "group".ikey = new.okey;
1231              RETURN NULL;
1232              END IF;
1233              END IF;
1234
1235              IF (TG_OP = 'DELETE') THEN
1236              IF (old.attr='exported') then
1237              update "group" set exported = false where "group".ikey = old.okey;
1238              return null;
1239              end if;
1240              else
1241              IF (new.attr='exported') then
1242              update "group" set exported = true where "group".ikey = new.okey;
1243              RETURN NULL;
1244              end if;
1245              END IF;
1246
1247              if (TG_OP='DELETE') THEN
1248              RETURN old;
1249              else
1250              RETURN new;
1251              end if;
1252              END;$BODY$
1253        LANGUAGE plpgsql VOLATILE NOT LEAKPROOF
1254        COST 100;
1255                }
1256            ],
1257        },
1258        {
1259            ver => 34,
1260            code => sub { return 1 },
1261            recompute => 1,
1262        },
1263        {
1264            ver => 35,
1265            sql => [
1266                q{
1267                ALTER TABLE "user" ADD COLUMN lastlogin timestamp with time zone
1268                }
1269            ],
1270        },
1271        {
1272            ver => 36,
1273            sql => [
1274                q{
1275                CREATE TABLE public.employmentsum
1276                (
1277                  "user" text NOT NULL,
1278                  firstday date NOT NULL DEFAULT now(),
1279                  lastday date,
1280                  contrattype text,
1281                  CONSTRAINT employmentsum_pkey PRIMARY KEY (name),
1282                  CONSTRAINT employmentsum_check CHECK (lastday IS NULL OR firstday <= lastday),
1283                  CONSTRAINT employmentsum_name_user_fkey FOREIGN KEY ("user")
1284                      REFERENCES public."user" (name) MATCH SIMPLE
1285                      ON UPDATE CASCADE ON DELETE CASCADE
1286                )
1287                INHERITS (public.objects)
1288                WITH (
1289                  OIDS=FALSE
1290                );
1291
1292                CREATE INDEX fki_employmentsum_name_user_fkey
1293                  ON public.employmentsum
1294                  USING btree
1295                  (name COLLATE pg_catalog."default");
1296
1297                CREATE INDEX fki_employmentsum_user_fkey
1298                  ON public.employmentsum
1299                  USING btree
1300                  (name COLLATE pg_catalog."default");
1301
1302                CREATE INDEX employmentsum_exported_idx
1303                  ON public.employmentsum
1304                  USING btree
1305                  (exported);
1306
1307                CREATE INDEX employmentsum_rev_idx
1308                  ON public.employmentsum
1309                  USING btree
1310                  (rev);
1311
1312                CREATE TRIGGER employmentsum_rev_tg
1313                  BEFORE INSERT OR UPDATE OR DELETE
1314                  ON public.employmentsum
1315                  FOR EACH ROW
1316                  EXECUTE PROCEDURE public.rev_tg_f();
1317                }
1318            ],
1319        },
1320        {
1321            ver => 37,
1322            sql => [
1323                qq{
1324                CREATE TABLE public."templates"
1325                (
1326                  objectType text not NULL,
1327                  data text[],
1328                  CONSTRAINT template_pkey PRIMARY KEY (name)
1329                )
1330                INHERITS (public.objects)
1331                WITH (
1332                  OIDS=FALSE
1333                );
1334
1335                CREATE INDEX templates_rev_idx
1336                  ON public."templates"
1337                  USING btree
1338                  (rev);
1339
1340                CREATE INDEX templates_exported_idx
1341                  ON public."templates"
1342                  USING btree
1343                  (exported);
1344
1345                CREATE TRIGGER templates_rev_tg
1346                  BEFORE UPDATE OR DELETE
1347                  ON public."templates"
1348                  FOR EACH ROW
1349                  EXECUTE PROCEDURE public.rev_tg_f();
1350                }
1351            ],
1352        },
1353        {
1354            ver => 38,
1355            sql => [
1356                q{
1357
1358                CREATE TABLE public.support
1359                (
1360                  CONSTRAINT support_pkey PRIMARY KEY (name),
1361                  CONSTRAINT support_ikey_uniq UNIQUE (ikey)
1362                )
1363                INHERITS (public.objects)
1364                WITH (
1365                  OIDS=FALSE
1366                );
1367
1368                CREATE TRIGGER support_update_rev_tg
1369                  BEFORE INSERT OR UPDATE OR DELETE
1370                  ON public.support
1371                  FOR EACH ROW
1372                  EXECUTE PROCEDURE public.rev_tg_f();
1373
1374
1375                CREATE TABLE public.support_attributes
1376                (
1377                  CONSTRAINT support_attributes_pkey PRIMARY KEY (attr_key),
1378                  CONSTRAINT support_attr_support_okey_fkey FOREIGN KEY (okey)
1379                      REFERENCES public.support (ikey) MATCH SIMPLE
1380                      ON UPDATE CASCADE ON DELETE CASCADE
1381                )
1382                INHERITS (public.attributes)
1383                WITH (
1384                  OIDS=FALSE
1385                );
1386
1387                CREATE OR REPLACE FUNCTION public.support_attr_update_ref()
1388                  RETURNS trigger AS
1389                $BODY$begin
1390
1391                IF (TG_OP != 'INSERT') then
1392                update "support" set date = now() where "support".ikey = old.okey;
1393                end if;
1394                IF (TG_OP != 'DELETE') then
1395                update "support"  set date = now() where "support".ikey = new.okey;
1396                end if;
1397
1398                IF (TG_OP = 'DELETE') then
1399                  return old;
1400                ELSE
1401                  return new;
1402                END IF;
1403
1404                END;$BODY$
1405                  LANGUAGE plpgsql VOLATILE
1406                  COST 100;
1407
1408                CREATE INDEX fki_support_attributes_attr_fkey
1409                  ON public.support_attributes
1410                  USING btree
1411                  (attr COLLATE pg_catalog."default");
1412
1413                CREATE INDEX support_attr_value_idx
1414                  ON public.support_attributes
1415                  USING btree
1416                  (value COLLATE pg_catalog."default");
1417
1418                  CREATE TRIGGER support_attr_update
1419                  AFTER INSERT OR UPDATE OR DELETE
1420                  ON public.support_attributes
1421                  FOR EACH ROW
1422                  EXECUTE PROCEDURE public.support_attr_update_ref();
1423
1424                CREATE TABLE public.nethost_attributes_supports
1425                (
1426                  CONSTRAINT nethost_attributes_support_pkey PRIMARY KEY (attr_key),
1427                  CONSTRAINT nethost_attr_support_okey_fkey FOREIGN KEY (okey)
1428                      REFERENCES public.nethost (ikey) MATCH SIMPLE
1429                      ON UPDATE CASCADE ON DELETE CASCADE,
1430                  CONSTRAINT nethost_attributes_support_support_fkey FOREIGN KEY (value)
1431                      REFERENCES public."support" (name) MATCH SIMPLE
1432                      ON UPDATE CASCADE ON DELETE CASCADE,
1433                  CONSTRAINT nethost_attributes_support_uniq UNIQUE (okey, attr, value)
1434                )
1435                INHERITS (public.nethost_attributes)
1436                WITH (
1437                  OIDS=FALSE
1438                );
1439
1440                CREATE INDEX fki_nethost_attr_support_okey_fkey
1441                  ON public.nethost_attributes_supports
1442                  USING btree
1443                  (okey);
1444
1445                CREATE INDEX fki_nethost_attributes_support_attr_fkey
1446                  ON public.nethost_attributes_supports
1447                  USING btree
1448                  (attr COLLATE pg_catalog."default");
1449
1450
1451                CREATE INDEX fki_nethost_attributes_support_support_fkey
1452                  ON public.nethost_attributes_supports
1453                  USING btree
1454                  (value COLLATE pg_catalog."default");
1455
1456                CREATE TRIGGER nethost_attributes_support_update_ref
1457                  AFTER INSERT OR UPDATE OR DELETE
1458                  ON public.nethost_attributes_supports
1459                  FOR EACH ROW
1460                  EXECUTE PROCEDURE public.nethost_attr_update_ref();
1461
1462                CREATE OR REPLACE FUNCTION public.nethost_sort_fields()
1463                  RETURNS trigger AS
1464                $BODY$BEGIN
1465
1466                              IF (TG_OP='INSERT') then
1467                              IF (new.attr='ip') THEN
1468                              insert into nethost_attributes_ips VALUES (new.*);
1469                              RETURN NULL;
1470                              END IF;
1471
1472                              IF (new.attr='macaddr') THEN
1473                              insert into nethost_attributes_macs VALUES (new.*);
1474                              RETURN NULL;
1475                              END IF;
1476
1477                              IF (new.attr='owner') THEN
1478                              insert into nethost_attributes_users VALUES (new.*);
1479                              RETURN NULL;
1480                              END IF;
1481
1482                              IF (new.attr='user') THEN
1483                              insert into nethost_attributes_users VALUES (new.*);
1484                              RETURN NULL;
1485                              END IF;
1486
1487                          IF (new.attr='related') THEN
1488                              insert into nethost_attributes_nethosts VALUES (new.*);
1489                              RETURN NULL;
1490                              END IF;
1491
1492                          IF (new.attr='support') THEN
1493                              insert into nethost_attributes_supports VALUES (new.*);
1494                              RETURN NULL;
1495                              END IF;
1496
1497                              end if;
1498
1499                              if (TG_OP='DELETE') THEN
1500                              RETURN old;
1501                              else
1502                              RETURN new;
1503                              end if;
1504                              END;$BODY$
1505                  LANGUAGE plpgsql VOLATILE
1506                  COST 100;
1507
1508                }
1509            ],
1510        },
1511    );
1512
1513
1514    my $dbi = $self->{_db};
1515
1516    my $NeedRecompute = 0;
1517
1518    foreach my $maj (@updates) {
1519        if ($rev >= $maj->{ver}) {
1520            next;
1521        }
1522        $self->log(LA_NOTICE, 'Switching to schema revision: ' . $maj->{ver} . "\n");
1523        foreach my $sql (@{ $maj->{sql} || []}) {
1524            {
1525                my $sqlv = $sql;
1526                $sqlv =~ s/^/  /mg;
1527            }
1528            my $err = $dbi->do($sql);
1529            defined($err) or do {
1530                $self->log(LA_ERR, "Erreur :\\" . $dbi->errstr . "\n");
1531                return;
1532            };
1533
1534        }
1535        if ($maj->{recompute}) {
1536            $NeedRecompute = 1;
1537        }
1538
1539        $self->log(LA_INFO, 'Updating schema_version to ' . $maj->{ver} . "\n");
1540
1541        $dbi->do(
1542            'UPDATE settings SET val = ? where varname = ?',
1543            undef,
1544            $maj->{ver}, 'schema_version'
1545        );
1546
1547        if ($maj->{code}) {
1548            $maj->{code}->() or return;
1549        }
1550    }
1551
1552    if ( $NeedRecompute ) {
1553        $self->set_global_value('NeedRecomputeObject', 'Yes');
1554    }
1555
1556    return 1;
1557}
1558
1559=head2 SchemaUpgrade
1560
1561Upgrade the SQL schema
1562
1563=cut
1564
1565sub _SchemaUpgrade {
1566    my ($self) = @_;
1567
1568    $self->log(LA_INFO, "Waiting to lock database to upgrade the schema...");
1569
1570    $self->db->do(q{SELECT 1 FROM settings WHERE varname = 'schema_version' FOR UPDATE});
1571
1572    $self->log(LA_INFO, "Database locked upgrading schema !");
1573 
1574    $self->temp_switch_unexported(
1575        sub {
1576            if($self->_SqlSchemaUpgrade) {
1577                $self->log(LA_DEBUG, "upgrade::_SqlSchemaUpgrade done");
1578            } else {
1579                $self->{_db}->rollback;
1580                return;
1581            }
1582
1583            if ($self->_CreateInternalObjects) {
1584                $self->log(LA_DEBUG, "upgrade::_CreateInternalObjects done");
1585            } else {
1586                $self->{_db}->rollback;
1587                return;
1588            }
1589
1590            return 1;
1591        }, 1
1592    ) or return;
1593
1594    if ($self->get_global_value('NeedRecomputeObject')) {
1595        $self->log(LA_NOTICE, 'Object value need to be recompute, this will take a moment');
1596        foreach my $otype (qw(user)) {
1597            foreach my $name ($self->listRealObjects($otype)) {
1598                my $object = $self->get_object($otype, $name);
1599                $object->PostSetAttribute();
1600            }
1601        }
1602        $self->del_global_value('NeedRecomputeObject');
1603    }
1604
1605    $self->commit;
1606
1607    return 1;
1608}
1609
16101;
Note: See TracBrowser for help on using the repository browser.