source: trunk/LATMOS-Accounts/bin/la-sql-upgrade.in @ 1375

Last change on this file since 1375 was 1366, checked in by nanardon, 9 years ago

Add passwordLastSet, store the datetime when password has been changed

File size: 17.4 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use LATMOS::Accounts;
6use Getopt::Long;
7use Pod::Usage;
8
9my $DATADIR = '@DATADIR@';
10
11=head1 NAME
12
13    la-sql-upgrade - Update SQL base schema
14
15=head1 SYNOPSIS
16
17    la-sql-upgrade [options] [name]
18
19=cut
20
21GetOptions(
22    'c|config=s'     => \my $config,
23    'b|base=s'       => \my $base,
24    'no-commit'      => \my $nocommit,
25    'v|verbose'      => \my $verbose,
26    'h|help'         => sub { pod2usage(1); },
27) or pod2usage();
28
29=head1 OPTIONS
30
31=over 4
32
33=item -c|--config configdir
34
35Use this configuration directory instead of the default one.
36
37=item -b|--base basename
38
39Query this specific base instead of the default one.
40
41=back
42
43=cut
44
45$| = 1; # autoflush
46
47my $LA = LATMOS::Accounts->new($config, noacl => 1);
48my $labase = $LA->base($base);
49
50my $dbi = $labase->db;
51
52my $rev = $labase->get_global_value('schema_version') || 1;
53
54my @updates = (
55    {
56        ver => 3,
57        sql => [
58            q{ALTER TABLE nethost_attributes_ips DROP CONSTRAINT
59            nethost_is_single_ip},
60            q{DROP TRIGGER IF EXISTS check_zone_name_unity_tg ON nethost},
61            q{DROP TRIGGER IF EXISTS check_zone_name_unity_tg ON netzone},
62            q{DROP FUNCTION IF EXISTS check_zone_name_unity()},
63            q{ALTER TABLE nethost_attributes_ips DROP CONSTRAINT
64            nethost_is_single_ip},
65            q{INSERT INTO settings(varname, val) VALUES ('schema_version', 3)},
66        ],
67    },
68    {
69        ver => 4,
70        sql => [
71            q{
72            CREATE OR REPLACE FUNCTION nethost_sort_fields()
73            RETURNS trigger AS
74            $BODY$BEGIN
75
76            IF (TG_OP='INSERT') then
77            IF (new.attr='ip') THEN
78            insert into nethost_attributes_ips VALUES (new.*);
79            RETURN NULL;
80            END IF;
81
82            IF (new.attr='macaddr') THEN
83            insert into nethost_attributes_macs VALUES (new.*);
84            RETURN NULL;
85            END IF;
86
87            IF (new.attr='owner') THEN
88            insert into nethost_attributes_users VALUES (new.*);
89            RETURN NULL;
90            END IF;
91
92            IF (new.attr='user') THEN
93            insert into nethost_attributes_users VALUES (new.*);
94            RETURN NULL;
95            END IF;
96            end if;
97
98
99            if (TG_OP='DELETE') THEN
100            RETURN old;
101            else
102            RETURN new;
103            end if;
104            END;$BODY$
105            LANGUAGE plpgsql VOLATILE
106            COST 100;
107            },
108        ],
109    },
110    {
111        ver => 5,
112        sql => [
113            q{
114            CREATE OR REPLACE VIEW address_attributes AS
115            ( ( SELECT address."user" AS value, 'user' AS attr, address.rev AS attr_key, address.ikey AS okey
116            FROM address
117            UNION ALL
118            SELECT address.name AS value, 'name' AS attr, address.rev AS attr_key, address.ikey AS okey
119            FROM address )
120            UNION ALL
121            SELECT address_attributes.value, address_attributes.attr, address_attributes.attr_key, address_attributes.okey
122            FROM address_attributes_base address_attributes )
123            UNION ALL
124            SELECT '1' AS value, 'active' AS attr, address.rev AS attr_key, address.ikey AS okey
125            FROM "user" JOIN address ON "user".name = address."user"
126            WHERE "user".exported AND address.exported and
127            ("user".expire IS NULL or "user".expire > now())
128            }
129        ],
130    },
131    {
132        ver => 6,
133        sql => [
134            q{
135            CREATE TABLE request
136            (
137                id serial NOT NULL,
138                "create" timestamp with time zone NOT NULL DEFAULT now(),
139                name text NOT NULL,
140                object text,
141                apply timestamp with time zone NOT NULL DEFAULT now(),
142                done timestamp with time zone,
143                "user" text,
144                CONSTRAINT request_pkey PRIMARY KEY (id ),
145                CONSTRAINT request_name_fkey FOREIGN KEY (name)
146                REFERENCES accreq (name) MATCH SIMPLE
147                ON UPDATE CASCADE ON DELETE CASCADE,
148                CONSTRAINT request_user_fkey FOREIGN KEY ("user")
149                REFERENCES "user" (name) MATCH SIMPLE
150                ON UPDATE CASCADE ON DELETE SET NULL
151            )
152            },
153            q{
154            CREATE INDEX fki_request_name_fkey ON request
155            USING btree (name )
156            },
157            q{
158            CREATE INDEX fki_request_user_fkey ON request
159            USING btree ("user" )
160            },
161            q{
162            CREATE TABLE request_attributes
163            (
164                reqid bigint,
165                attribute text NOT NULL,
166                value text,
167                CONSTRAINT request_id_fkey FOREIGN KEY (reqid)
168                REFERENCES request (id) MATCH SIMPLE
169                ON UPDATE CASCADE ON DELETE CASCADE
170            )
171            },
172            q{
173            CREATE INDEX fki_request_id_fkey ON request_attributes
174            USING btree (reqid )
175            },
176            q{
177            delete from accreq_attributes_list
178            }
179        ],
180    },
181    {
182        ver => 7,
183        sql => [
184            q{
185            ALTER TABLE request ADD COLUMN automated boolean NOT NULL DEFAULT false;
186            },
187            q{
188            ALTER TABLE request ADD COLUMN objrev bigint;
189            },
190            q{
191            ALTER TABLE aliases ADD COLUMN description text;
192            },
193            q{
194            ALTER TABLE revaliases ADD COLUMN description text;
195            },
196            q{
197            CREATE OR REPLACE FUNCTION group_sort_fields()
198              RETURNS trigger AS
199              $BODY$BEGIN
200
201              IF (TG_OP='INSERT') then
202              IF (new.attr='managedBy'
203                  OR  new.attr='managedAlsoBy'
204                  OR  new.attr='member'
205                  OR  new.attr='memberUID') THEN
206              insert into group_attributes_users VALUES (new.*);
207              RETURN NULL;
208              END IF;
209
210              IF (new.attr='sutype') THEN
211              insert into group_attributes_sutypes VALUES (new.*);
212              RETURN NULL;
213              END IF;
214              end if;
215
216
217              IF (TG_OP = 'UPDATE') THEN
218              IF (new.attr='gidNumber') then
219              update "group" set gidnumber = new.value::integer where
220              "group".ikey = new.okey;
221              RETURN NULL;
222              END IF;
223              END IF;
224
225              IF (TG_OP = 'DELETE') THEN
226              IF (old.attr='exported') then
227              update "group" set exported = false where "group".ikey = old.okey;
228              return null;
229              end if;
230              else
231              IF (new.attr='exported') then
232              update "group" set exported = true where "group".ikey = new.okey;
233              RETURN NULL;
234              end if;
235              END IF;
236
237              if (TG_OP='DELETE') THEN
238              RETURN old;
239              else
240              RETURN new;
241              end if;
242              END;$BODY$
243                LANGUAGE plpgsql VOLATILE
244                  COST 100;
245            },
246        ],
247    },
248    {
249        ver => 8,
250        sql => [
251            q{
252            CREATE TABLE objectslogs
253            (
254              logkey SERIAL NOT NULL,
255              ikey bigint NOT NULL,
256              irev bigint,
257              otype text NOT NULL,
258              name text NOT NULL,
259              changetype text NOT NULL,
260              username text NOT NULL,
261              message text NOT NULL,
262              logdate timestamp with time zone NOT NULL DEFAULT now(),
263              CONSTRAINT objectlogs_pkey PRIMARY KEY (logkey)
264            );},
265            q{
266            CREATE INDEX objectlogs_name_idx
267              ON objectslogs
268              USING btree
269              (name);
270            },
271            q{
272            CREATE INDEX objectslogs_ikey_idx
273              ON objectslogs
274              USING btree
275              (ikey);
276            },
277            q{
278            CREATE INDEX objectslogs_otype_idx
279              ON objectslogs
280              USING btree
281              (otype);
282            }
283        ],
284    },
285    {
286        ver => 9,
287        sql => [
288            q{
289            CREATE TABLE nethost_attributes_nethosts
290            (
291            CONSTRAINT nethost_attributes_nethosts_pkey PRIMARY KEY (attr_key),
292            CONSTRAINT nethost_attr_nethosts_fkey FOREIGN KEY (okey)
293            REFERENCES nethost (ikey) MATCH SIMPLE
294            ON UPDATE CASCADE ON DELETE CASCADE,
295            CONSTRAINT nethost_attr_nethosts_nethosts FOREIGN KEY ("value")
296            REFERENCES nethost (name) MATCH SIMPLE
297            ON UPDATE CASCADE ON DELETE CASCADE
298            )
299            INHERITS (nethost_attributes);
300
301            CREATE INDEX fki_nethost_attr_nethosts_fkey
302            ON nethost_attributes_nethosts
303            USING btree
304            (okey);
305
306            CREATE TRIGGER nethost_attr_nethosts_update
307            AFTER INSERT OR UPDATE OR DELETE
308            ON nethost_attributes_nethosts
309            FOR EACH ROW
310            EXECUTE PROCEDURE nethost_attr_update_ref();
311
312
313            CREATE OR REPLACE FUNCTION nethost_sort_fields()
314              RETURNS trigger AS
315              $BODY$BEGIN
316
317              IF (TG_OP='INSERT') then
318              IF (new.attr='ip') THEN
319              insert into nethost_attributes_ips VALUES (new.*);
320              RETURN NULL;
321              END IF;
322
323              IF (new.attr='macaddr') THEN
324              insert into nethost_attributes_macs VALUES (new.*);
325              RETURN NULL;
326              END IF;
327
328              IF (new.attr='owner') THEN
329              insert into nethost_attributes_users VALUES (new.*);
330              RETURN NULL;
331              END IF;
332
333              IF (new.attr='user') THEN
334              insert into nethost_attributes_users VALUES (new.*);
335              RETURN NULL;
336              END IF;
337
338              IF (new.attr='related') THEN
339              insert into nethost_attributes_nethosts VALUES (new.*);
340              RETURN NULL;
341              END IF;
342              end if;
343
344              if (TG_OP='DELETE') THEN
345              RETURN old;
346              else
347              RETURN new;
348              end if;
349              END;$BODY$
350              LANGUAGE plpgsql VOLATILE
351              COST 100;
352
353            }
354        ],
355    },
356    {
357        ver => 10,
358        sql => [
359            q{
360            CREATE OR REPLACE FUNCTION service_attr_update_ref()
361            RETURNS trigger AS
362            $BODY$begin
363
364            IF (TG_OP != 'INSERT') then
365            update "service" set date = now() where "service".ikey = old.okey;
366            end if;
367            IF (TG_OP != 'DELETE') then
368            update "service"  set date = now() where "service".ikey = new.okey;
369            end if;
370
371            IF (TG_OP = 'DELETE') then
372            return old;
373            ELSE
374            return new;
375            END IF;
376
377            END;$BODY$
378            LANGUAGE plpgsql VOLATILE
379            COST 100;
380            },
381            q{
382
383            CREATE TABLE service
384            (
385            "start" date,
386            "end" date,
387            CONSTRAINT service_pkey PRIMARY KEY (name),
388            CONSTRAINT service_ikey_uniq UNIQUE (ikey)
389            )
390            INHERITS (objects);
391            },
392            q{
393            CREATE TABLE service_attributes_list
394            (
395            ikey integer NOT NULL DEFAULT nextval('ikey_seq'::regclass),
396            canonical text NOT NULL,
397            description text,
398            CONSTRAINT service_attributes_list_pkey PRIMARY KEY (ikey),
399            CONSTRAINT g_attr_l_service_uniq UNIQUE (canonical)
400            )
401            INHERITS (revisions, attributes_list)
402            WITH (
403            OIDS=FALSE
404            );
405            ALTER TABLE service_attributes_list
406            OWNER TO latmos;
407
408            CREATE TABLE service_attributes
409            (
410            CONSTRAINT service_attributes_pkey PRIMARY KEY (attr_key),
411            CONSTRAINT service_attr_users_okey_fkey FOREIGN KEY (okey)
412            REFERENCES service (ikey) MATCH SIMPLE
413            ON UPDATE CASCADE ON DELETE CASCADE,
414            CONSTRAINT service_attributes_attr_fkey FOREIGN KEY (attr)
415            REFERENCES service_attributes_list (canonical) MATCH SIMPLE
416            ON UPDATE CASCADE ON DELETE NO ACTION
417            )
418            INHERITS (attributes)
419            WITH (
420            OIDS=FALSE
421            );
422            ALTER TABLE service_attributes
423            OWNER TO latmos;
424
425            CREATE INDEX fki_service_attributes_attr_fkey
426            ON nethost_attributes
427            USING btree
428            (attr);
429
430            CREATE INDEX service_attr_value_idx
431            ON nethost_attributes
432            USING btree
433            (value);
434
435            CREATE TRIGGER serivce_attr_update
436            AFTER INSERT OR UPDATE OR DELETE
437            ON service_attributes
438            FOR EACH ROW
439            EXECUTE PROCEDURE service_attr_update_ref();
440            },
441            q{
442            CREATE TABLE service_attributes_users
443            (
444            CONSTRAINT service_attributes_user_pkey PRIMARY KEY (attr_key),
445            CONSTRAINT service_attr_users_okey_fkey FOREIGN KEY (okey)
446            REFERENCES service (ikey) MATCH SIMPLE
447            ON UPDATE CASCADE ON DELETE CASCADE,
448            CONSTRAINT service_attributes_users_attr_fkey FOREIGN KEY (attr)
449            REFERENCES service_attributes_list (canonical) MATCH SIMPLE
450            ON UPDATE CASCADE ON DELETE NO ACTION,
451            CONSTRAINT service_attributes_users_user_fkey FOREIGN KEY (value)
452            REFERENCES "user" (name) MATCH SIMPLE
453            ON UPDATE CASCADE ON DELETE CASCADE,
454            CONSTRAINT service_attributes_users_uniq UNIQUE (okey, attr, value)
455            )
456            INHERITS (service_attributes);
457
458            CREATE INDEX fki_service_attr_users_okey_fkey
459            ON service_attributes_users
460            USING btree
461            (okey);
462
463            CREATE INDEX fki_service_attributes_users_attr_fkey
464            ON service_attributes_users
465            USING btree
466            (attr);
467
468            CREATE INDEX fki_service_attributes_users_user_fkey
469            ON service_attributes_users
470            USING btree
471            (value);
472
473            CREATE TRIGGER service_attributes_users_update_ref
474            AFTER INSERT OR UPDATE OR DELETE
475            ON service_attributes_users
476            FOR EACH ROW
477            EXECUTE PROCEDURE service_attr_update_ref();
478
479            CREATE OR REPLACE FUNCTION service_sort_fields()
480              RETURNS trigger AS
481              $BODY$BEGIN
482
483              if (TG_OP='INSERT' or TG_OP='UPDATE') THEN
484              IF (new.attr='manager') THEN
485              insert into service_attributes_users VALUES (new.*);
486              RETURN NULL;
487              END IF;
488              END IF;
489
490              if (TG_OP='DELETE') THEN
491              RETURN old;
492              else
493              RETURN new;
494              end if;
495              END;$BODY$
496              LANGUAGE plpgsql VOLATILE
497              COST 100;
498
499              CREATE TRIGGER service_sort_field_tg
500              BEFORE INSERT OR UPDATE OR DELETE
501              ON service_attributes
502              FOR EACH ROW
503              EXECUTE PROCEDURE service_sort_fields();
504
505            CREATE TRIGGER service_rev_tg
506            BEFORE INSERT OR UPDATE OR DELETE
507            ON service
508            FOR EACH ROW
509            EXECUTE PROCEDURE rev_tg_f();
510            },
511        ],
512    },
513    {
514        ver => 11,
515        sql => [
516            q{
517            ALTER TABLE "user" ADD COLUMN endcircuit timestamp with time zone
518            }
519        ],
520    },
521);
522
523my @objects = (
524    {
525        name => 'dpmt',
526        otype => 'sutype',
527        attrs => {
528            description => 'Department',
529        },
530    },
531    {
532        name => 'contrattype',
533        otype => 'sutype',
534        attrs => {
535            description => 'Contract',
536        },
537    },
538);
539
540$dbi->rollback;
541
542foreach my $maj (@updates) {
543    if ($rev >= $maj->{ver}) {
544        next;
545    }
546    print "\n";
547    print 'Switching to schema revision: ' . $maj->{ver} . "\n";
548    foreach my $sql (@{ $maj->{sql} }) {
549        {
550            my $sqlv = $sql;
551            $sqlv =~ s/^/  /mg;
552            if ($verbose) {
553                warn '  >' . $sqlv . "\n";
554            } else {
555                print 'x';
556            }
557        }
558        $dbi->do($sql) or die "Erreur :\\" . $dbi->errstr . "\n";
559    }
560
561    print "\n";
562
563    print 'Updating schema_version to ' . $maj->{ver} . "\n";
564
565    $dbi->do(
566        'UPDATE settings SET val = ? where varname = ?',
567        undef,
568        $maj->{ver}, 'schema_version'
569    );
570    print "Done\n\n";
571
572}
573
574foreach my $otype ($labase->list_supported_objects) {
575    foreach my $attribute ($labase->list_canonical_fields($otype, 'r')) {
576        my $attr = $labase->attribute($otype, $attribute);
577        $attr->{inline} and next;
578        $attr->{managed} and next;
579
580        if ($labase->is_registered_attribute($otype, $attribute)) {
581        } else {
582            $labase->register_attribute($otype, $attribute, $attr->{comment})
583                or die "Error, aborting\n";
584            print "Attr. $attribute for object type $otype registred\n";
585        }
586    }
587}
588 
589foreach (@objects) {
590    if (!$labase->get_object($_->{otype}, $_->{name})) {
591        printf("Creatting object %s/%s\n", $_->{otype}, $_->{name});
592        $labase->create_object($_->{otype}, $_->{name}, %{$_->{attrs} || {}})
593            or die sprintf("cannot create %s/%s\n", $_->{otype}, $_->{name});
594
595    }
596}
597
598if ($nocommit) {
599    $dbi->rollback;
600} else {
601    $dbi->commit;
602}
603print "Process terminated successfully\n";
Note: See TracBrowser for help on using the repository browser.