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