test for tm.tm_gmtoff presence in configure.ac fix for #330
[rrdtool.git] / src / rrd_fetch_libdbi.c
index 2c4c722..fdd10c4 100644 (file)
@@ -1,6 +1,6 @@
 #include "rrd_tool.h"
 #include "unused.h"
-#include <dbi/dbi.h>
+// #include <dbi/dbi.h>
 #include <time.h>
 
 /* the structures */
@@ -389,6 +389,7 @@ rrd_fetch_fn_libdbi(
   unsigned long minstepsize=300;
   /* by default assume unixtimestamp */
   int isunixtime=1;
+  long gmt_offset=0;
   /* the result-set */
   long r_timestamp,l_timestamp,d_timestamp;
   double r_value,l_value,d_value;
@@ -459,7 +460,22 @@ rrd_fetch_fn_libdbi(
     return -1; 
   }
   /* if we have leading '*', then we have a TIMEDATE Field*/
-  if (table_help.timestamp[0]=='*') { isunixtime=0; table_help.timestamp++; }
+  if (table_help.timestamp[0]=='*') {
+    struct tm tm;
+#ifdef HAVE_TIMEZONE
+    extern long timezone;
+#endif
+    time_t t=time(NULL);
+    localtime_r(&t,&tm);
+#ifdef HAVE_TM_GMTOFF
+    gmt_offset=tm.TM_GMTOFF;
+#else
+#ifdef HAVE_TIMEZONE
+    gmt_offset=timezone;
+#endif
+#endif
+    isunixtime=0; table_help.timestamp++;
+  }
   /* hex-unescape the value */
   if(_inline_unescape(table_help.timestamp)) { return -1; }
 
@@ -585,6 +601,7 @@ rrd_fetch_fn_libdbi(
   while((r_status=_sql_fetchrow(&table_help,&r_timestamp,&r_value,derive))>0) {
     /* processing of value */
     /* calculate index for the timestamp */
+    r_timestamp-=gmt_offset;
     idx=(r_timestamp-(*start))/(*step);
     /* some out of bounds checks on idx */
     if (idx<0) { idx=0;}
@@ -615,7 +632,7 @@ rrd_fetch_fn_libdbi(
        (*data)[idx*(*ds_cnt)+1]=r_value; /* AVG */
        (*data)[idx*(*ds_cnt)+2]=r_value; /* MAX */
        (*data)[idx*(*ds_cnt)+3]=1;       /* COUNT */
-       (*data)[idx*(*ds_cnt)+4]=r_value; /* SIGMA */
+       (*data)[idx*(*ds_cnt)+4]=r_value*r_value; /* SIGMA */
       } else {
        /* MIN */
        if ((*data)[idx*(*ds_cnt)+0]>r_value) { (*data)[idx*(*ds_cnt)+0]=r_value; }
@@ -652,6 +669,30 @@ rrd_fetch_fn_libdbi(
     }
   }
 
+  /* Fill in missing values */
+  fillmissing/=(*step);/* Convert from seconds to steps */
+  if (fillmissing>0) {
+    int copy_left=fillmissing;
+    for(idx=1;idx<rows;idx++) {
+      long count=(*data)[idx*(*ds_cnt)+3];
+      if (count==0) {
+        /* No data this bin */
+        if (copy_left>0) {
+          /* But we can copy from previous */
+          int idx_p=idx-1;
+          (*data)[idx*(*ds_cnt)+0]=(*data)[idx_p*(*ds_cnt)+0];
+          (*data)[idx*(*ds_cnt)+1]=(*data)[idx_p*(*ds_cnt)+1];
+          (*data)[idx*(*ds_cnt)+2]=(*data)[idx_p*(*ds_cnt)+2];
+          (*data)[idx*(*ds_cnt)+3]=(*data)[idx_p*(*ds_cnt)+3];
+          (*data)[idx*(*ds_cnt)+4]=(*data)[idx_p*(*ds_cnt)+4];
+          copy_left--;
+        }
+      }else{
+        copy_left=fillmissing;
+      }
+    }
+  }
+
   /* and return OK */
   return 0;
 }