# $SnapHashLicense:
#
# SnapLogic - Open source data services
#
# Copyright (C) 2009, SnapLogic, Inc. All rights reserved.
#
# See http://www.snaplogic.org for more information about
# the SnapLogic project.
#
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2. See the LEGAL file
# at the top of the source tree.
#
# "SnapLogic" is a trademark of SnapLogic, Inc.
#
#
# $
# $Id: __init__.py 8544 2009-08-11 16:32:57Z dmitri $
"""
This package contains general utility functions for components.
"""
__docformat__ = "epytext en"
from datetime import date,datetime
from decimal import Decimal
from types import NoneType
from snaplogic.common.data_types import SnapString,SnapNumber,SnapDateTime
from datetime import datetime,timedelta
import time
from snaplogic.common.snap_exceptions import *
def convert_to_supported_type(value):
"""
Converts python types to type expected by SnapLogic records.
The following types are converted:
1) str to unicode
2) float, int and long to Decimal
3) date to datetime
@param value: Value to be converted
@type value: varies
@return: The converted value.
@rtype: datetime/unicode/Decimal/bool
"""
t = type(value)
if t == str:
value = value.decode('utf-8')
elif t == date:
value = datetime(value.year, value.month, value.day)
elif t == float or t == int or t == long:
value = Decimal(str(value))
# Now we've done the needed conversions...
# Is this type even allowed?
elif not (t in [datetime, unicode, Decimal, bool, NoneType]):
raise SnapObjTypeError("Cannot handle type: %s" % str(t))
return value
_DATE_FORMAT_1 = "%Y-%m-%dT%H:%M:%S" # Matches TypeConverter
_DATE_FORMAT_2 = "%Y-%m-%d %H:%M:%S" # Variant of TypeConverter
_DATE_FORMAT_3 = '%Y-%m-%d' # Matches DateDimension
_DATE_FORMATS = [_DATE_FORMAT_1, _DATE_FORMAT_2, _DATE_FORMAT_3]
_DATE_FORMAT_PRESENTATION = ["yyyy-mm-ddThh:mm:ss", "yyyy-mm-dd hh:mm:ss", "yyyy-mm-dd"]
SQLITE_DATE_FORMAT_STRING = _DATE_FORMAT_2
def convert_to_field_type(type, value):
""" Convert value from string to number or date """
# Strings or Nones don't require any conversion
if type == SnapString or value is None:
return value
elif type == SnapNumber:
try:
if isinstance(value, float):
return Decimal(str(value))
else:
return Decimal(value)
except Exception:
raise SnapComponentError("'%s' is not a number" % value)
elif type == SnapDateTime:
for datetime_fmt in _DATE_FORMATS:
try:
return datetime(*time.strptime(value, datetime_fmt)[0:6])
except:
# Try the next mask in the for loop
pass
# We've tried all date masks, and neither one worked.
raise SnapComponentError("Cannot convert '%s' to date. Value did not match any supported format: %s" %
(value, ", ".join(_DATE_FORMAT_PRESENTATION)))
def parse_date_with_fractions(s, fmt=SQLITE_DATE_FORMAT_STRING):
"""
Parse a string containing microseconds into a datetime
object, because strptime does not understand fractions
of a second (milliseconds, microseconds, etc).
@param s: String to parse into date
@type s: string
@param fmt: Format string
@type fmt: str
@return: datetime object
@rtype: datetime
"""
micros = None
if '.' in s:
dot_idx = s.index('.')
micros = s[dot_idx+1:]
micros_mult = 10 ** (6 - len(micros))
micros = int(micros) * micros_mult
s = s[:dot_idx]
result = datetime(*(time.strptime(s, fmt)[0:6]))
if micros:
delta = timedelta(0, 0, micros)
result += delta
return result
|