Bivio::Type::PrimaryId
# Copyright (c) 1999-2010 bivio Software, Inc. All rights reserved. # $Id$ package Bivio::Type::PrimaryId; use strict; use Bivio::Base 'Type.Number'; # C<Bivio::Type::PrimaryId> is a number which uniquely identifies a # row in certain tables. It is the one and only primary key for those # tables. # # Compare C<PrimaryId> values using C<eq> and C<ne>, B<not> the numeric # equivalents. PrimaryIds are larger that fit into a 32-bit integer. # # All C<PrimaryId> values are unique within a given "universe". PrimaryIds are # "structured", but you should avoid depending on this structure. The purpose of the # structure is to allow for easy horizontal and vertical partitioning. The lower # five digits identify the table and a site. This leaves 13 digits for # the rows. By using the lower digits, we avoid # large numbers until we have large numbers of users and we can expand the # space without having to change the numbering scheme, or all tables. # # L<to_parts|"to_parts"> and L<from_parts|"from_parts"> allow you to take apart # the PrimaryId. sub UNSPECIFIED_VALUE { return 0; } sub can_be_negative { return 0; } sub can_be_positive { return 1; } sub can_be_zero { return 0; } sub from_literal { my($proto, $value) = @_; # Make sure is at least one digit long, non-zero, and unsigned. $proto->internal_from_literal_warning unless wantarray; return undef unless defined($value) && $value =~ /\S/; $value =~ s/\s+//g; return $value if $value =~ /^0$/; $value =~ s/^0+//g; return $value if $value =~ /^\d+$/; return (undef, Bivio::TypeError->PRIMARY_ID); } sub from_parts { my(undef, $parts) = @_; # Returns parts (see L<to_parts|"to_parts">) as string. return sprintf('%s%1d%02d%02d', @{$parts}{qw(number version site type)}); } sub get_decimals { return 0; } sub get_max { return '999999999999999999'; } sub get_min { return '100001'; } sub get_precision { return 18; } sub get_width { return 18; } sub is_equal { my(undef, $left, $right) = @_; return 0 if defined($left) xor defined($right); return 1 unless defined($left); return $left eq $right ? 1 : 0; } sub is_specified { my($proto, $value) = @_; return defined($value) && $value =~ /\d/ && $value ne Bivio::Biz::ListModel->EMPTY_KEY_VALUE && $value ne $proto->UNSPECIFIED_VALUE ? 1 : 0; } sub is_valid { my($p) = shift->unsafe_to_parts(@_); return $p && $p->{number} && $p->{type} ? 1 : 0; } sub to_html { my($self, $value) = @_; return defined($value) ? $value : ''; } sub to_literal { my(undef, $value) = @_; return defined($value) ? $value : ''; } sub to_parts { return shift->unsafe_to_parts(@_) || Bivio::Die->die($_[0], ': bad value'); } sub to_query { my($self, $value) = @_; return defined($value) ? $value : ''; } sub to_uri { my($self, $value) = @_; return defined($value) ? $value : ''; } sub unsafe_to_parts { my(undef, $value) = @_; return ($value || '') =~ /^(\d+)(\d)(\d{2})(\d{2})$/ ? { number => $1, version => $3 + 0, site => $2 + 0, type => $4 + 0, } : undef; } 1;