gitee.com/curryzheng/dm@v0.0.1/x.go (about)

     1  /*
     2   * Copyright (c) 2000-2018, 达梦数据库有限公司.
     3   * All rights reserved.
     4   */
     5  
     6  package dm
     7  
     8  import (
     9  	"database/sql/driver"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  const (
    15  	Seconds_1900_1970 = 2209017600
    16  
    17  	OFFSET_YEAR = 0
    18  
    19  	OFFSET_MONTH = 1
    20  
    21  	OFFSET_DAY = 2
    22  
    23  	OFFSET_HOUR = 3
    24  
    25  	OFFSET_MINUTE = 4
    26  
    27  	OFFSET_SECOND = 5
    28  
    29  	OFFSET_MILLISECOND = 6
    30  
    31  	OFFSET_TIMEZONE = 7
    32  
    33  	DT_LEN = 8
    34  
    35  	INVALID_VALUE = int(INT32_MIN)
    36  )
    37  
    38  type DmTimestamp struct {
    39  	dt                  []int
    40  	dtype               int
    41  	scale               int
    42  	oracleFormatPattern string
    43  	oracleDateLanguage  int
    44  
    45  	// Valid为false代表DmArray数据在数据库中为NULL
    46  	Valid bool
    47  }
    48  
    49  func newDmTimestampFromDt(dt []int, dtype int, scale int) *DmTimestamp {
    50  	dmts := new(DmTimestamp)
    51  	dmts.Valid = true
    52  	dmts.dt = dt
    53  	dmts.dtype = dtype
    54  	dmts.scale = scale
    55  	return dmts
    56  }
    57  
    58  func newDmTimestampFromBytes(bytes []byte, column column, conn *DmConnection) *DmTimestamp {
    59  	dmts := new(DmTimestamp)
    60  	dmts.Valid = true
    61  	dmts.dt = decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
    62  
    63  	if isLocalTimeZone(int(column.colType), int(column.scale)) {
    64  		dmts.scale = getLocalTimeZoneScale(int(column.colType), int(column.scale))
    65  	} else {
    66  		dmts.scale = int(column.scale)
    67  	}
    68  
    69  	dmts.dtype = int(column.colType)
    70  	dmts.scale = int(column.scale)
    71  	dmts.oracleDateLanguage = int(conn.OracleDateLanguage)
    72  	switch column.colType {
    73  	case DATE:
    74  		dmts.oracleFormatPattern = conn.FormatDate
    75  	case TIME:
    76  		dmts.oracleFormatPattern = conn.FormatTime
    77  	case TIME_TZ:
    78  		dmts.oracleFormatPattern = conn.FormatTimeTZ
    79  	case DATETIME:
    80  		dmts.oracleFormatPattern = conn.FormatTimestamp
    81  	case DATETIME_TZ:
    82  		dmts.oracleFormatPattern = conn.FormatTimestampTZ
    83  	}
    84  	return dmts
    85  }
    86  
    87  func NewDmTimestampFromString(str string) (*DmTimestamp, error) {
    88  	dt := make([]int, DT_LEN)
    89  	dtype, err := toDTFromString(strings.TrimSpace(str), dt)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	if dtype == DATE {
    95  		return newDmTimestampFromDt(dt, dtype, 0), nil
    96  	}
    97  	return newDmTimestampFromDt(dt, dtype, 6), nil
    98  }
    99  
   100  func NewDmTimestampFromTime(time time.Time) *DmTimestamp {
   101  	dt := toDTFromTime(time)
   102  	return newDmTimestampFromDt(dt, DATETIME, 6)
   103  }
   104  
   105  func (dmTimestamp *DmTimestamp) ToTime() time.Time {
   106  	return toTimeFromDT(dmTimestamp.dt, 0)
   107  }
   108  
   109  // 获取年月日时分秒毫秒时区
   110  func (dmTimestamp *DmTimestamp) GetDt() []int {
   111  	return dmTimestamp.dt
   112  }
   113  
   114  func (dmTimestamp *DmTimestamp) CompareTo(ts DmTimestamp) int {
   115  	if dmTimestamp.ToTime().Equal(ts.ToTime()) {
   116  		return 0
   117  	} else if dmTimestamp.ToTime().Before(ts.ToTime()) {
   118  		return -1
   119  	} else {
   120  		return 1
   121  	}
   122  }
   123  
   124  func (dmTimestamp *DmTimestamp) String() string {
   125  	if dmTimestamp.oracleFormatPattern != "" {
   126  		return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, dmTimestamp.oracleDateLanguage)
   127  	}
   128  	return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
   129  }
   130  
   131  func (dest *DmTimestamp) Scan(src interface{}) error {
   132  	if dest == nil {
   133  		return ECGO_STORE_IN_NIL_POINTER.throw()
   134  	}
   135  	switch src := src.(type) {
   136  	case nil:
   137  		*dest = *new(DmTimestamp)
   138  		// 将Valid标志置false表示数据库中该列为NULL
   139  		(*dest).Valid = false
   140  		return nil
   141  	case *DmTimestamp:
   142  		*dest = *src
   143  		return nil
   144  	case time.Time:
   145  		ret := NewDmTimestampFromTime(src)
   146  		*dest = *ret
   147  		return nil
   148  	default:
   149  		return UNSUPPORTED_SCAN
   150  	}
   151  }
   152  
   153  func (dmTimestamp DmTimestamp) Value() (driver.Value, error) {
   154  	if !dmTimestamp.Valid {
   155  		return nil, nil
   156  	}
   157  	return dmTimestamp, nil
   158  }
   159  
   160  func (dmTimestamp *DmTimestamp) toBytes() ([]byte, error) {
   161  	return encode(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale, dmTimestamp.dt[OFFSET_TIMEZONE])
   162  }
   163  
   164  /**
   165   * 获取当前对象的年月日时分秒,如果原来没有decode会先decode;
   166   */
   167  func (dmTimestamp *DmTimestamp) getDt() []int {
   168  	return dmTimestamp.dt
   169  }
   170  
   171  func (dmTimestamp *DmTimestamp) getTime() int64 {
   172  	sec := toTimeFromDT(dmTimestamp.dt, 0).Unix()
   173  	return sec + int64(dmTimestamp.dt[OFFSET_MILLISECOND])
   174  }
   175  
   176  func (dmTimestamp *DmTimestamp) setTime(time int64) {
   177  	timeInMillis := (time / 1000) * 1000
   178  	nanos := (int64)((time % 1000) * 1000000)
   179  	if nanos < 0 {
   180  		nanos = 1000000000 + nanos
   181  		timeInMillis = (((time / 1000) - 1) * 1000)
   182  	}
   183  	dmTimestamp.dt = toDTFromUnix(timeInMillis, nanos)
   184  }
   185  
   186  func (dmTimestamp *DmTimestamp) setTimezone(tz int) error {
   187  	// DM中合法的时区取值范围为-12:59至+14:00
   188  	if tz <= -13*60 || tz > 14*60 {
   189  		return ECGO_INVALID_DATETIME_FORMAT.throw()
   190  	}
   191  	dmTimestamp.dt[OFFSET_TIMEZONE] = tz
   192  	return nil
   193  }
   194  
   195  func (dmTimestamp *DmTimestamp) getNano() int64 {
   196  	return int64(dmTimestamp.dt[OFFSET_MILLISECOND] * 1000)
   197  }
   198  
   199  func (dmTimestamp *DmTimestamp) setNano(nano int64) {
   200  	dmTimestamp.dt[OFFSET_MILLISECOND] = (int)(nano / 1000)
   201  }
   202  
   203  func (dmTimestamp *DmTimestamp) string() string {
   204  	if dmTimestamp.oracleFormatPattern != "" {
   205  		return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, dmTimestamp.oracleDateLanguage)
   206  	}
   207  	return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
   208  }
   209  
   210  func (dmTimestamp *DmTimestamp) checkValid() error {
   211  	if !dmTimestamp.Valid {
   212  		return ECGO_IS_NULL.throw()
   213  	}
   214  	return nil
   215  }