File Coverage

blib/lib/DBIx/QuickORM/Type/UUID.pm
Criterion Covered Total %
statement 80 89 89.8
branch 29 44 65.9
condition 10 25 40.0
subroutine 18 19 94.7
pod 0 9 0.0
total 137 186 73.6


line stmt bran cond sub pod time code
1             package DBIx::QuickORM::Type::UUID;
2 4     4   32 use strict;
  4         10  
  4         169  
3 4     4   23 use warnings;
  4         10  
  4         317  
4              
5             our $VERSION = '0.000019';
6              
7 4     4   22 use Role::Tiny::With qw/with/;
  4         9  
  4         315  
8             with 'DBIx::QuickORM::Role::Type';
9              
10 4     4   58 use DBIx::QuickORM::Util qw/parse_conflate_args/;
  4         9  
  4         39  
11              
12 4     4   199 use Scalar::Util qw/blessed/;
  4         11  
  4         348  
13 4     4   2770 use UUID qw/uuid7 parse unparse/;
  4         7754  
  4         37  
14 4     4   790 use Carp qw/croak/;
  4         9  
  4         4371  
15              
16 7     7 0 3135 sub new { uuid7() }
17              
18             sub qorm_inflate {
19 16     16 0 106 my $params = parse_conflate_args(@_);
20 16 100       90 my $val = $params->{value} or return undef;
21 15   50     61 my $class = $params->{class} // __PACKAGE__;
22              
23 15 50       46 return undef unless defined $val;
24              
25 15   66     72 return $class->looks_like_uuid($val) // $class->looks_like_bin($val) // croak "'$val' does not look like a UUID";
      33        
26             }
27              
28             sub qorm_deflate {
29 18     18 0 165 my $params = parse_conflate_args(@_);
30 18 100       91 my $val = $params->{value} or return undef;
31 17 50       61 my $affinity = $params->{affinity} or croak "Could not determine affinity";
32 17   50     49 my $class = $params->{class} // __PACKAGE__;
33              
34 17 100       71 if (my $uuid = $class->looks_like_uuid($val)) {
35 13 100       73 return $uuid if $affinity eq 'string';
36              
37 8         10 my $b;
38 8         78 parse($val, $b);
39 8         48 return $b;
40             }
41              
42 4 100       15 if (my $uuid = $class->looks_like_bin($val)) {
43 3 100       15 return $val if $affinity eq 'binary';
44 2         14 return $uuid;
45             }
46              
47 1         1063 croak "'$val' does not look like a uuid";
48             }
49              
50             sub qorm_compare {
51 4     4 0 13 my $class = shift;
52 4         12 my ($a, $b) = @_;
53              
54 4         22 $a = $class->qorm_inflate($a);
55 4         21 $b = $class->qorm_inflate($b);
56              
57 4         14 my $da = defined($a);
58 4         31 my $db = defined($b);
59              
60 4 50 33     51 return $a cmp $b if $da && $db;
61 0 0 0     0 return 0 unless $da || $db;
62 0         0 return 1;
63             }
64              
65             sub qorm_affinity {
66 5     5 0 28 my $class = shift;
67 5         24 my %params = @_;
68              
69 5 100       82 if (my $sql_type = $params{sql_type}) {
70 4 100       30 return 'string' if lc($sql_type) eq 'uuid';
71 1 50       15 return 'binary' if $sql_type =~ m/(bin(ary)?|bytea?|blob)/i;
72             }
73              
74 1 50       5 if (my $dialect = $params{dialect}) {
75 1 50       42 return 'string' if $dialect->supports_type('uuid');
76             }
77              
78 1         8 return 'string';
79             }
80              
81             sub qorm_sql_type {
82 0     0 0 0 my $self = shift;
83 0         0 my ($dialect) = @_;
84              
85 0 0       0 if (my $stype = $dialect->supports_type('uuid')) {
86 0         0 return $stype;
87             }
88              
89             # Document how to set up binary(16)
90             # Basically use the post_column hook in Autofill
91 0         0 return 'VARCHAR(36)';
92             }
93              
94             sub looks_like_bin {
95 7     7 0 20 my $in = pop;
96 4     4   42 use bytes;
  4         11  
  4         220  
97 7 100       45 return undef unless length($in) == 16;
98 6         3350 my $s;
99 6         47 unparse($in, $s);
100 6         64 return $s;
101             }
102              
103             sub looks_like_uuid {
104 33     33 0 75 my $in = pop;
105 33 100 66     454 return $in if $in && $in =~ m/^[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}$/i;
106 7         35 return undef;
107             }
108              
109             sub qorm_register_type {
110 3     3 0 11 my $self = shift;
111 3         7 my ($types, $affinities) = @_;
112              
113 3   33     19 my $class = ref($self) || $self;
114              
115 3   33     22 $types->{uuid} //= $class;
116              
117 3         19 push @{$affinities->{binary}} => sub {
118 1     1   6 my %params = @_;
119 1 50       11 return $class if $params{name} =~ m/uuid/i;
120 0 0       0 return $class if $params{db_name} =~ m/uuid/i;
121 0         0 return;
122 3         6 };
123              
124 3         20 push @{$affinities->{string}} => sub {
125 14     14   104 my %params = @_;
126 14 50       83 return $class if $params{name} =~ m/uuid/i;
127 14 50       42 return $class if $params{db_name} =~ m/uuid/i;
128 14         96 return;
129 3         21 };
130             }
131              
132             1;