Project

General

Profile

« Previous | Next » 

Revision 6218

schemas/py_functions.sql: _date(): Removed features that require dateutil, which is not available under plpython3u. This includes removing the now-unused date string parameter.

View differences:

schemas/py_functions.sql
40 40
ALTER FUNCTION py_functions._date(date timestamp with time zone) OWNER TO bien;
41 41

  
42 42
--
43
-- Name: _date(text, text, text, text); Type: FUNCTION; Schema: py_functions; Owner: bien
43
-- Name: _date(text, text, text); Type: FUNCTION; Schema: py_functions; Owner: bien
44 44
--
45 45

  
46
CREATE FUNCTION _date(date text DEFAULT NULL::text, year text DEFAULT NULL::text, month text DEFAULT NULL::text, day text DEFAULT NULL::text) RETURNS text
46
CREATE FUNCTION _date(year text DEFAULT NULL::text, month text DEFAULT NULL::text, day text DEFAULT NULL::text) RETURNS text
47 47
    LANGUAGE plpython3u IMMUTABLE
48 48
    AS $$
49 49
global date, year, month, day
50 50

  
51 51
import datetime
52
import dateutil.tz
53 52

  
54 53
def e_msg(e): return e.args[0].rstrip()
55 54

  
56
def e_str(e): return e.__class__.__name__+': '+e_msg(e)
55
# Year is required
56
if year == None:
57
    if month == None and day == None: return None # entire date is empty
58
    else: raise AssertionError(
59
        'null value in column "year" violates not-null constraint')
57 60

  
58
def raise_invalid_value(cause, value):
59
    raise ValueError('invalid input value: "'+str(value)+'"\nDETAIL:  '
60
        +e_str(cause))
61
# Convert month name to number
62
if month != None and not month.isdigit(): # month is name
63
    month = str(datetime.datetime.strptime(month, '%b').month)
61 64

  
62
utc = dateutil.tz.tzutc()
65
if month == None: month = 1
66
if day == None: day = 1
67
year, month, day = map(int, (year, month, day))
63 68

  
64
def naive2utc(datetime_):
65
    assert datetime_.tzinfo == None
66
    return datetime_.replace(tzinfo=utc)
69
for try_num in range(2):
70
    try:
71
        date = datetime.date(year, month, day)
72
        break
73
    except ValueError as e:
74
        if try_num > 0: raise # exception still raised after retry
75
        msg = e_msg(e)
76
        if msg == 'month must be in 1..12': # try swapping month and day
77
            month, day = day, month
78
        else: raise
67 79

  
68
def from_timestamp(utc_timestamp):
69
    return naive2utc(datetime.datetime.utcfromtimestamp(utc_timestamp))
70

  
71
epoch = from_timestamp(0)
72

  
73
def strtotime(str_, default=epoch):
74
    import dateutil.parser
75
    return dateutil.parser.parse(str_, default=default)
76

  
77
if date != None:
78
    str_ = date
79
    try: year = float(str_)
80
    except ValueError:
81
        try: date = strtotime(str_)
82
        except ImportError: return str_
83
        except ValueError as e: raise_invalid_value(e, str_)
84
    else: date = (datetime.date(int(year), 1, 1) +
85
        datetime.timedelta(round((year % 1.)*365)))
86
else:
87
    # Year is required
88
    if year == None:
89
        if month == None and day == None: return None # entire date is empty
90
        else: raise AssertionError(
91
            'null value in column "year" violates not-null constraint')
92
    
93
    # Convert month name to number
94
    if month != None and not month.isdigit(): # month is name
95
        month = str(strtotime(month).month)
96
    
97
    if month == None: month = 1
98
    if day == None: day = 1
99
    year, month, day = map(int, (year, month, day))
100
    
101
    for try_num in range(2):
102
        try:
103
            date = datetime.date(year, month, day)
104
            break
105
        except ValueError as e:
106
            if try_num > 0: raise # exception still raised after retry
107
            msg = e_msg(e)
108
            if msg == 'month must be in 1..12': # try swapping month and day
109
                month, day = day, month
110
            else: raise
111

  
112 80
return str(date)
113 81
$$;
114 82

  
115 83

  
116
ALTER FUNCTION py_functions._date(date text, year text, month text, day text) OWNER TO bien;
84
ALTER FUNCTION py_functions._date(year text, month text, day text) OWNER TO bien;
117 85

  
118 86
--
119 87
-- Name: _dateRangeEnd(text); Type: FUNCTION; Schema: py_functions; Owner: bien

Also available in: Unified diff