Package DB Schema v3
Karel Zak
kzak at redhat.com
Tue Dec 5 13:57:27 UTC 2006
On Mon, Dec 04, 2006 at 09:59:11PM -0800, Toshio Kuratomi wrote:
> create table Collection (
> id serial primary key,
> name text not null,
> version text not null,
> status text not null default 'development',
> owner integer not null,
> publishURLTemplate text null,
From PostgreSQL docs:
NULL
The column is allowed to contain null values. This is the
default.
^^^^^^
This clause is only provided for compatibility with
non-standard SQL databases. Its use is discouraged in new
applications.
> pendingURLTemplate text null,
> summary text null,
> description text null,
> unique (name, version),
> check (status = 'development' or status = 'active' or status = 'maintanence'
> or status = 'EOL' or status = 'rejected')
> );
From my point of view the status column is odd. I think you should
use an abbreviation or one char only.
status text not null default 'D'
check ( status IN ('D','A','M','E','R') )
>
> create table Branch (
> collectionId integer not null primary key,
> branchName varchar(32) not null,
^^^^^^^^^
> distTag varchar(32) not null,
^^^^^^
is it right define duplicate tags and branch names?
> parentId integer null,
> foreign key (parentId) references Collection(id),
> foreign key (collectionId) references Collection(id)
> );
Hmm.. here I see 1:1 model (PK=FK). Strange. (It usually means that
you should merge the tables to one table only.) Maybe:
create table Branch (
id serial primary key,
branchName varchar(32) not null unique,
distTag varchar(32) not null unique,
parentId integer references Collection(id),
collectionId integer not null references Collection(id)
);
Also, I think there should be defined some FK policy for update and
delete. It means "ON DELETE" and "ON UPDATE" definition for the
references.
> create table Package (
> id serial primary key,
> name text not null unique,
> summary text not null,
> description text null,
> reviewURL text null,
> status text not null default 'awaitingreview',
> check (status = 'awaitingreview' or status = 'underreview' or status = 'approved' or status = 'denied')
> );
IMHO, same problem with the status column. Here it is more terrible,
because this table will be larger.
CHECK( status IN (
'W', -- wait
'R', -- review
'A', -- approved
'D' -- denied
))
>
> -- Permissions for who can make various changes to the code.
> -- We want to limit the access that a given person may have to edit the package
> --
> -- Fields:
> -- :id: Primary key
> -- :pkgListId: What package in what collection has this value.
> -- :acl: The permission being set.
> -- :status: Whether this permission is active.
> create table PackageACL (
> id serial primary key,
> packageListingId integer not null,
> acl text not null,
> status text not null,
> foreign key (packageListingId) references PackageListing(id),
> check (status = 'awaitingreview' or status = 'approved' or status = 'denied'
> or status = 'obsolete'),
> check (acl = 'commit' or acl = 'build' or acl = 'watchbugzilla'
> or acl = 'watchcommits' or acl = 'approveacls' or acl = 'checkout')
> );
>
> -- ACLs that allow a person to do something
> --
> -- Fields:
> -- :packageACLId: Inherit from an ACL record.
> -- :userId: User id from the account system.
> create table PersonPackageACL (
> packageACLId integer primary key,
> userId integer not null,
> foreign key (packageACLId) references PackageACL (id)
> );
Again. 1:1 model (PK=FK).
I think the ACL model should be:
what (ACL), where (package), who (user)
you can use one table only (or two if ACL is group of permissions).
> -- ACLs that allow a group to do something
> --
> -- Fields:
> -- :packageACLId: Inherit from an ACL record.
> -- :groupId: Group id from the account system.
> create table GroupPackagePermissions (
> packageACLId integer primary key,
> groupId integer not null,
> foreign key (PackageACLId) references PackageACL (id)
> );
Again. 1:1
> -- Log a change to the packageDB.
> --
> -- Fields:
> -- :id: Primary key
> -- :userId: Who made the change.
> -- :changeTime: Time that the change occurred.
> create table Log (
> id serial primary key,
> userId integer not null,
> changeTime timestamp default now() not null
> );
When, Who, ... and where is "What"? (type of change)
> -- Log a change made to the Package table.
> --
> -- Fields:
> -- :logId: The id of the log entry.
> -- :packageId: The package that changed.
> -- :action: What happened to the package.
> -- :description: Additional information about the change.
> create table PackageLog (
> logId integer primary key,
> packageId integer not null,
> action text not null,
> description text null,
> check (action = 'added' or action = 'removed' or action = 'statuschanged' or
> action = 'awaitingreview' or action = 'underreview' or action = 'approved'
> or action = 'denied'),
> foreign key (logId) references Log(id),
> foreign key (packageId) references Package(id)
> );
... ah... here is the "What". Again 1:1 (PK=FK).
Don't forget PRIMARY KEY is always UNIQUE.
> -- Log changes to packages in collections.
> --
> -- Fields:
> -- :logId: The id of the log entry.
> -- :packageListingId: The packageListing that changed.
> -- :action: What happened to the package in the collection.
> -- :description: Additional information about the change.
> create table PackageListingLog (
> logId integer primary key,
> packageListingId integer not null,
> action text not null,
> description text null,
> check (action = 'added' or action = 'removed' or action = 'awaitingreview'
> or action = 'awaitingbranch' or action = 'underreview' or
> action = 'approved' or action = 'denied'),
> foreign key (logId) references Log (id),
> foreign key (packageListingId) references PackageListing(id)
> );
Again. 1:1.
> -- Log changes to built packages.
> --
> -- Fields:
> -- :logId: The id of the log entry.
> -- :packageVersionId: The `PackageVersion` that changed.
> -- :action: What happened to the `PackageVersion`.
> -- :description: Additional information about the change.
> create table PackageVersionLog (
> logId integer primary key,
> packageVersionId integer not null,
> action text not null,
> description text null,
> check (action = 'added' or action = 'awaitingdevel' or
> action = 'awaitingreview' or action = 'awaitingqa' or
> action = 'aaitingpublish' or action = 'approved' or action = 'denied' or
> action = 'obsolete'),
> foreign key (logId) references Log (id),
> foreign key (packageVersionId) references PackageVersion(id)
> );
Again. 1:1.
> -- Log changes to built package ACLs.
> --
> -- Fields:
> -- :logId: The id of the log entry.
> -- :packageVersionId: The `PackageACL` that changed.
> -- :action: What happened to the ACLs for the package.
> -- :description: Additional information about the change.
> create table PackageACLLog (
> logId integer primary key,
> packageACLId integer not null,
> action text not null,
> description text null,
> check (action = 'added' or action = 'awaitingreview'
> or action = 'awaitingbranch' or action = 'underreview' or
> action = 'approved' or action = 'denied' or action = 'obsolete'),
> foreign key (logId) references Log (id),
> foreign key (packageACLId) references PackageACL(id)
> );
Again. 1:1.
Karel
--
Karel Zak <kzak at redhat.com>
More information about the infrastructure
mailing list