STATUS TMhrnow( HRSYSTIME *stime) { struct _generic_64 timadr; unsigned __int64 a100nsec; PTR tz_cb; STATUS status; status = sys$gettim(&timadr); if (status != SS$_NORMAL) return TM_GETTIME_ERR; stime->tv_sec = TMconv(&timadr); /* get seconds since Jan 1, 1970 */ /* Adjust for timezone */ status = TMtz_init(&tz_cb); if (status != OK) return TM_GETTIME_ERR; stime->tv_sec -= TMtz_search(tz_cb, TM_TIMETYPE_LOCAL, stime->tv_sec); /* ** get nanoseconds since last second. VMS gives 64 bit time as number ** of 100 nsec units since Nov 17, 1858. We mod with 10 million to get ** number of 100 nsec units since last second, then convert to nsec. */ a100nsec = timadr.gen64$q_quadword; stime->tv_nsec = (a100nsec % 10000000) * 100; return OK; }
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); }