/*{ ** Name: adu_datenow - Retrieve current time and date ** ** Description: ** This routine will fill the result with the INGRES internal date ** for the current date and time. ** ** Inputs: ** adf_scb Pointer to an ADF session control block. ** .adf_errcb ADF_ERROR struct. ** .ad_ebuflen The length, in bytes, of the buffer ** pointed to by ad_errmsgp. ** .ad_errmsgp Pointer to a buffer to put formatted ** error message in, if necessary. ** adu_dv Pointer to the data value to be filled: ** .db_datatype Must be DB_DTE_TYPE (non-nullable DATE). ** .db_prec Ignored (should be zero). ** .db_length Must be sizeof(DB_DATE) ** .db_data Pointer to result location to fill. ** ** Outputs: ** adf_scb Pointer to an ADF session control block. ** .adf_errcb ADF_ERROR struct. If an ** error occurs the following fields will ** be set. NOTE: if .ad_ebuflen = 0 or ** .ad_errmsgp = NULL, no error message ** will be formatted. ** .ad_errcode ADF error code for the error. ** .ad_errclass Signifies the ADF error class. ** .ad_usererr If .ad_errclass is ADF_USER_ERROR, ** this field is set to the corresponding ** user error which will either map to ** an ADF error code or a user-error code. ** .ad_emsglen The length, in bytes, of the resulting ** formatted error message. ** .adf_errmsgp Pointer to the formatted error message. ** adu_dv Data value to be filled: ** .db_data INGRES date of "now". ** ** Returns: ** The following DB_STATUS codes may be returned: ** E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL ** ** If a DB_STATUS code other than E_DB_OK is returned, the caller ** can look in the field adf_scb.adf_errcb.ad_errcode to determine ** the ADF error code. The following is a list of possible ADF error ** codes that can be returned by this routine: ** ** E_AD0000_OK Completed successfully. ** E_AD2004_BAD_DTID Datatype passed in was not valid ** (must be non-nullable DATE) ** E_AD2005_BAD_DTLEN Length passed in was not valid ** (must be sizeof(DB_DATE)) ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-oct-89 (jrb) ** Created. ** 19-jun-2006 (gupsh01) ** Added support for new datetime datatypes. ** 01-aug-2006 (gupsh01) ** Supply nanosecond parameter in adu_cvtime() ** call. ** 29-aug-2006 (gupsh01) ** Removed support for ANSI datetime datatypes. ** date(now) is only used for ingresdate types. ** 07-nov-2006 (gupsh01) ** Fixed the second calculations. ** 08-Feb-2008 (kiria01) b119885 ** Change dn_time to dn_seconds to avoid the inevitable confusion with ** the dn_time in AD_DATENTRNL. Also ensure that the dn structure ** is fully iniialised. */ DB_STATUS adu_datenow( ADF_CB *adf_scb, DB_DATA_VALUE *adu_dv) { i4 bintim_secs; DB_DATA_VALUE dv_tmp; DB_STATUS db_stat; struct timevect tv; AD_NEWDTNTRNL dn; /* Check validity of inputs */ if (adu_dv->db_datatype != DB_DTE_TYPE) return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0)); if (adu_dv->db_length != ADF_DTE_LEN) return(adu_error(adf_scb, E_AD2005_BAD_DTLEN, 0)); dv_tmp.db_datatype = DB_INT_TYPE; dv_tmp.db_prec = 0; dv_tmp.db_length = 4; dv_tmp.db_data = (PTR) &bintim_secs; if (db_stat = adu_dbconst(adf_scb, &Adf_globs->Adk_bintim_map, &dv_tmp)) return (db_stat); adu_cvtime((i4) bintim_secs, 0, &tv); dn.dn_year = tv.tm_year + AD_TV_NORMYR_BASE; dn.dn_month = tv.tm_mon + AD_TV_NORMMON; dn.dn_day = tv.tm_mday; dn.dn_seconds = tv.tm_hour * AD_39DTE_ISECPERHOUR + tv.tm_min * AD_10DTE_ISECPERMIN + tv.tm_sec; dn.dn_nsecond = 0; AD_TZ_SETNEW(&dn, 0); dn.dn_status = AD_DN_ABSOLUTE | AD_DN_TIMESPEC; dn.dn_dttype = adu_dv->db_datatype; return (adu_7from_dtntrnl (adf_scb, adu_dv, &dn)); }
DB_STATUS adu_dbconst( ADF_CB *adf_scb, ADK_MAP *kmap, DB_DATA_VALUE *rdv) { ADK_CONST_BLK *k = adf_scb->adf_constants; bool kcalced = FALSE; PTR kptr = NULL; DB_ERROR err; ADF_DBMSINFO *dbi = kmap->adk_dbi; i4 kbit = kmap->adk_kbit; DB_STATUS db_stat; bool datetimetype = FALSE; DB_DT_ID date_dt; u_i4 val; /* Beware that some of the dbmsinfo functions care not about ** caller lengths and will update the DBV regardless so ** we arrange to get the constants written directy and if ** need be, we conver on return. */ DB_DATA_VALUE tmp_rdv = *rdv; i8 tmp_buf[1024/sizeof(i8)]; /* Make temporary aligned */ switch (kbit) /* look for datetime constants */ { case ADK_CURR_DATE: /* _current_date */ datetimetype = TRUE; date_dt = DB_ADTE_TYPE; break; case ADK_CURR_TIME: /* _current_time */ datetimetype = TRUE; date_dt = DB_TMW_TYPE; break; case ADK_CURR_TSTMP: /* _current_timestamp */ datetimetype = TRUE; date_dt = DB_TSW_TYPE; break; case ADK_LOCAL_TIME: /* _local_time*/ datetimetype = TRUE; date_dt = DB_TME_TYPE; break; case ADK_LOCAL_TSTMP: /* _local_timestamp */ datetimetype = TRUE; date_dt = DB_TSTMP_TYPE; break; } if (k != NULL) { switch (kbit) /* switch on known query constants */ { case ADK_BINTIM: /* _bintim */ tmp_rdv.db_data = (PTR) &k->adk_bintim; tmp_rdv.db_length = sizeof(k->adk_bintim); break; case ADK_CPU_MS: /* _cpu_ms */ tmp_rdv.db_data = (PTR) &k->adk_cpu_ms; tmp_rdv.db_length = sizeof(k->adk_cpu_ms); break; case ADK_ET_SEC: /* _et_sec */ tmp_rdv.db_data = (PTR) &k->adk_et_sec; tmp_rdv.db_length = sizeof(k->adk_et_sec); break; case ADK_DIO_CNT: /* _dio_cnt */ tmp_rdv.db_data = (PTR) &k->adk_dio_cnt; tmp_rdv.db_length = sizeof(k->adk_dio_cnt); break; case ADK_BIO_CNT: /* _bio_cnt */ tmp_rdv.db_data = (PTR) &k->adk_bio_cnt; tmp_rdv.db_length = sizeof(k->adk_bio_cnt); break; case ADK_PFAULT_CNT: /* _pfault_cnt */ tmp_rdv.db_data = (PTR) &k->adk_pfault_cnt; tmp_rdv.db_length = sizeof(k->adk_pfault_cnt); break; case ADK_CURR_DATE: /* _current_date */ tmp_rdv.db_data = (PTR) &k->adk_curr_date; tmp_rdv.db_length = sizeof(k->adk_curr_date); break; case ADK_CURR_TIME: /* _current_time */ tmp_rdv.db_data = (PTR) &k->adk_curr_time; tmp_rdv.db_length = sizeof(k->adk_curr_time); break; case ADK_CURR_TSTMP: /* _current_timestamp */ tmp_rdv.db_data = (PTR) &k->adk_curr_tstmp; tmp_rdv.db_length = sizeof(k->adk_curr_tstmp); break; case ADK_LOCAL_TIME: /* _local_time*/ tmp_rdv.db_data = (PTR) &k->adk_local_time; tmp_rdv.db_length = sizeof(k->adk_local_time); break; case ADK_LOCAL_TSTMP: /* _local_timestamp */ tmp_rdv.db_data = (PTR) &k->adk_local_tstmp; tmp_rdv.db_length = sizeof(k->adk_local_tstmp); break; default: return (adu_error (adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "dbmsinfo kbit")); } if (k->adk_set_mask & kbit) /* Has this value been calculated yet? */ kcalced = TRUE; } else tmp_rdv.db_data = (PTR)tmp_buf; if (!kcalced) { /* Must calculate value from scratch */ if (datetimetype) { AD_NEWDTNTRNL dn; struct timevect tv; DB_STATUS db_stat; i4 sec_time_zone; HRSYSTIME hrsystime; TMhrnow(&hrsystime); MEfill ((u_i2) sizeof(i4)*10, NULLCHAR, (PTR) &tv); adu_cvtime((i4) hrsystime.tv_sec, (i4)hrsystime.tv_nsec, &tv); MEfill((u_i2) sizeof(AD_NEWDTNTRNL), NULLCHAR, (PTR) &dn); /* Interpret the time vector */ dn.dn_year = (i2)tv.tm_year + 1900; dn.dn_month = (i2)tv.tm_mon + 1; dn.dn_day = tv.tm_mday; dn.dn_seconds = tv.tm_hour * 3600 + tv.tm_min * 60 + tv.tm_sec; dn.dn_nsecond = tv.tm_nsec; dn.dn_dttype = date_dt; sec_time_zone = TMtz_search(adf_scb->adf_tzcb, TM_TIMETYPE_GMT, (i4) hrsystime.tv_sec); AD_TZ_SETNEW(&dn, sec_time_zone); dn.dn_status = AD_DN_ABSOLUTE; switch (date_dt) { case DB_ADTE_TYPE: /* _current_date */ dn.dn_seconds = 0; dn.dn_nsecond = 0; dn.dn_status2 |= AD_DN2_ADTE_TZ; dn.dn_status |= AD_DN_YEARSPEC|AD_DN_MONTHSPEC|AD_DN_DAYSPEC; break; case DB_TME_TYPE: /* _local_time*/ dn.dn_status2 |= AD_DN2_TZ_OFF_LCL; /*FALLTHROUGH*/ case DB_TMW_TYPE: /* _current_time */ dn.dn_status |= AD_DN_TIMESPEC; dn.dn_status2 |= AD_DN2_NO_DATE; break; case DB_TSTMP_TYPE: /* _local_timestamp */ dn.dn_status2 |= AD_DN2_TZ_OFF_LCL; /*FALLTHROUGH*/ case DB_TSW_TYPE: /* _current_timestamp */ dn.dn_status |= AD_DN_YEARSPEC|AD_DN_MONTHSPEC|AD_DN_DAYSPEC; dn.dn_status |= AD_DN_TIMESPEC; break; } /* Convert straight into constant data area */ if (db_stat = adu_7from_dtntrnl (adf_scb, &tmp_rdv, &dn)) return (db_stat); } else if (dbi == NULL || dbi->dbi_func == NULL) { /* If no function ptr in dbmsinfo array, set default value */ if (db_stat = adc_getempty(adf_scb, &tmp_rdv)) return (db_stat); } else { /* Get the value from the proper dbmsinfo function */ /* ** NOTE: If the dbmsinfo routines ever change the size of ** of the returned object, it will be assumed that the length ** will match the adk_* buffer length. If not, there will ** be a risk of uninitialised data slipping in. */ if (db_stat = (*dbi->dbi_func)(dbi, NULL, &tmp_rdv, &err)) return (db_stat); } /* We now have the calculated result written directly to the ** constant buffers if they exist or to the tmp_buf. ** Either way, we don't need to write the constant again, we just ** need to convert out to the return buffer/dbv. */ /* Don't forget to set the `already calculated' bit */ if (k) k->adk_set_mask |= kbit; } /* We have the value requested, so just set result and return */ if (rdv->db_datatype == DB_INT_TYPE) { /* Currently, all query constants are uints or dates */ u_i8 val; switch (tmp_rdv.db_length) { case 8: val = (u_i8)*(u_i8*)tmp_rdv.db_data; break; case 4: val = (u_i8)*(u_i4*)tmp_rdv.db_data; break; case 2: val = (u_i8)*(u_i2*)tmp_rdv.db_data; break; case 1: val = (u_i8)*(u_i1*)tmp_rdv.db_data; break; } switch (rdv->db_length) { case 8: I8ASSIGN_MACRO(val, *(u_i8 *)rdv->db_data); break; case 4: { u_i4 val4 = (u_i4)val; I4ASSIGN_MACRO(val4, *(u_i4 *)rdv->db_data); } break; case 2: { u_i2 val2 = (u_i2)val; I2ASSIGN_MACRO(val2, *(i2*)rdv->db_data); } break; case 1: *(u_i1 *)rdv->db_data = (u_i1)val; break; default: return (adu_error (adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "dbmsinfo isz")); } } else if (tmp_rdv.db_length != rdv->db_length) { return (adu_error (adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "dbmsinfo len")); } else { MEcopy(tmp_rdv.db_data, rdv->db_length, rdv->db_data); } return (E_DB_OK); }