fix mssql
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / SQLMaker / MSSQL.pm
1 package # Hide from PAUSE
2   DBIx::Class::SQLMaker::MSSQL;
3
4 use base qw( DBIx::Class::SQLMaker );
5
6 #
7 # MSSQL does not support ... OVER() ... RNO limits
8 #
9 sub _rno_default_order {
10   return \ '(SELECT(1))';
11 }
12
13 sub _datetime_now_sql { 'NOW()' }
14
15 {
16   my %part_map = (
17      year         => 'year',
18      quarter      => 'quarter',
19      month        => 'month',
20      day_of_year  => 'dayofyear',
21      day_of_month => 'day',
22      week         => 'week',
23      day_of_week  => 'weekday',
24      hour         => 'hour',
25      minute       => 'minute',
26      second       => 'second',
27      millisecond  => 'millisecond',
28      nanosecond   => 'nanosecond',
29   );
30
31   my %diff_part_map = %part_map;
32   $diff_part_map{day} = delete $diff_part_map{day_of_year};
33   delete $diff_part_map{day_of_month};
34   delete $diff_part_map{day_of_week};
35
36   sub _datetime_sql {
37     die $_[0]->_unsupported_date_extraction($_[1], 'Microsoft SQL Server')
38        unless exists $part_map{$_[1]};
39     "DATEPART($part_map{$_[1]}, $_[2])"
40   }
41   sub _datetime_diff_sql {
42     die $_[0]->_unsupported_date_diff($_[1], 'Microsoft SQL Server')
43        unless exists $diff_part_map{$_[1]};
44     "DATEDIFF($diff_part_map{$_[1]}, $_[2], $_[3])"
45   }
46
47   sub _reorder_diff_datetime_vars {
48     my ($self, $d1, $d2) = @_;
49
50     return ($d2, $d1);
51   }
52
53   sub _datetime_add_sql {
54     my ($self, $part, $amount, $date) = @_;
55
56     die $self->_unsupported_date_adding($part, 'Microsoft SQL Server')
57       unless exists $diff_part_map{$part};
58
59     return "(DATEADD($diff_part_map{$part}, " .
60       ($self->using_freetds && $amount eq '?' ? "CAST($amount AS INTEGER)" : $amount )
61       . ", $date))"
62   }
63 }
64
65 =head1 DATE FUNCTION IMPLEMENTATION
66
67 The function used to extract date information is C<DATEPART>, which supports
68
69  year
70  quarter
71  month
72  day_of_year
73  day_of_month
74  week
75  day_of_week
76  hour
77  minute
78  second
79  millisecond
80
81 The function used to diff dates is C<DATEDIFF>, which supports
82
83  year
84  quarter
85  month
86  day
87  week
88  hour
89  minute
90  second
91  millisecond
92
93 =cut
94
95 sub _where_op_ADD_DATETIME_transform_args {
96    my ($self, $i, $k, $val) = @_;
97
98    if ($i == 0 && !ref $val) {
99       return $self->_convert('?'), [\'integer' => $val ]
100    } else {
101       return $self->next::method($i, $k, $val)
102    }
103 }
104
105 1;