1 /** 2 * DDBC - D DataBase Connector - abstraction layer for RDBMS access, with interface similar to JDBC. 3 * 4 * Source file ddbc/drivers/mysqlddbc.d. 5 * 6 * DDBC library attempts to provide implementation independent interface to different databases. 7 * 8 * Set of supported RDBMSs can be extended by writing Drivers for particular DBs. 9 * 10 * JDBC documentation can be found here: 11 * $(LINK http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/package-summary.html)$(BR) 12 * 13 * This module contains misc utility functions which may help in implementation of DDBC drivers. 14 * 15 * Copyright: Copyright 2013 16 * License: $(LINK www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 17 * Author: Vadim Lopatin 18 */ 19 module ddbc.drivers.utils; 20 21 private import std.conv : ConvException; 22 private import std.datetime : Date, DateTime, TimeOfDay; 23 private import std.datetime.date; 24 private import std.datetime.systime : SysTime; 25 private import std.datetime.timezone : UTC; 26 private import std.format : formattedRead; 27 //private import std.traits : isSomeString; 28 private import std.algorithm : canFind; 29 30 string copyCString(T)(const T* c, int actualLength = -1) if (is(T == char) || is (T == ubyte)) { 31 const(T)* a = c; 32 if(a is null) 33 return null; 34 35 if(actualLength == -1) { 36 T[] ret; 37 while(*a) { 38 ret ~= *a; 39 a++; 40 } 41 return cast(string)ret; 42 } else { 43 return cast(string)(a[0..actualLength].idup); 44 } 45 46 } 47 48 SysTime parseSysTime(const string timestampString) @safe { 49 try { 50 import std.regex : match; 51 if(match(timestampString, r"\d{4}-\D{3}-\d{2}.*")) { 52 return SysTime.fromSimpleString(timestampString); 53 } else if(match(timestampString, r".*[\+|\-]\d{1,2}:\d{1,2}|.*Z")) { 54 return timestampString.canFind('-') ? 55 SysTime.fromISOExtString(timestampString) : 56 SysTime.fromISOString(timestampString); 57 } else { 58 return SysTime(parseDateTime(timestampString), UTC()); 59 } 60 } catch (ConvException e) { 61 // static if(__traits(compiles, (){ import std.experimental.logger; } )) { 62 // import std.experimental.logger : sharedLog; 63 // sharedLog.error("Could not parse " ~ timestampString ~ " to SysTime", e); 64 // } 65 throw new DateTimeException("Can not convert"); 66 } 67 } 68 69 unittest { 70 // Accept valid (as per D language) systime formats 71 parseSysTime("2019-May-04 13:34:10.500Z"); 72 parseSysTime("2019-Jan-02 13:34:10-03:00"); 73 parseSysTime("2019-05-04T13:34:10.500Z"); 74 parseSysTime("2019-06-14T13:34:10.500+01:00"); 75 parseSysTime("2019-02-07T13:34:10Z"); 76 parseSysTime("2019-08-12T13:34:10+01:00"); 77 parseSysTime("2019-09-03T13:34:10"); 78 79 // Accept valid (as per D language) date & datetime timestamps 80 // parseSysTime("2019-05-04 13:34:10"); 81 // parseSysTime("2019-05-07 13:32"); 82 // parseSysTime("2019-05-08"); 83 84 // Accept non-standard (as per D language) timestamp formats 85 //parseSysTime("2019/05/07 13:32"); 86 // parseSysTime("2010-12-30 12:10:04.1+00"); // postgresql 87 } 88 89 DateTime parseDateTime(const string timestampString) @safe { 90 return DateTime.fromISOExtString(timestampString); // todo: make this better 91 //return DateTime.fromISOExtString( s.translate( [ ' ': 'T' ] ).split( '.' ).front() ); 92 } 93 94 TimeOfDay parseTimeoid(const string timeoid) 95 { 96 string input = timeoid.dup; 97 int hour, min, sec; 98 formattedRead(input, "%s:%s:%s", &hour, &min, &sec); 99 return TimeOfDay(hour, min, sec); 100 } 101 102 Date parseDateoid(const string dateoid) 103 { 104 string input = dateoid.dup; 105 int year, month, day; 106 formattedRead(input, "%s-%s-%s", &year, &month, &day); 107 return Date(year, month, day); 108 }