mirror of
https://github.com/php-win-ext/pecl-processing-rrd.git
synced 2026-03-24 00:52:13 +01:00
rrd pecl extension - initial commit
git-svn-id: http://svn.php.net/repository/pecl/rrd/trunk@300689 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
87
config.m4
Normal file
87
config.m4
Normal file
@@ -0,0 +1,87 @@
|
||||
dnl config.m4 for extension php_rrd
|
||||
dnl Comments in this file start with the string 'dnl'.
|
||||
|
||||
PHP_ARG_WITH(rrd, for rrdtool support,
|
||||
[ --with-rrd[=DIR] Include rrdtool support (requires rrdtool >= 1.2.x)])
|
||||
|
||||
if test "$PHP_RRD" != "no"; then
|
||||
if test "$PHP_RRD" != "yes"; then
|
||||
AC_MSG_CHECKING(if rrdtool specified path is valid)
|
||||
if test -r $PHP_RRD/include/rrd.h && test -f $PHP_RRD/lib/librrd.$SHLIB_SUFFIX_NAME -o -f $PHP_RRD/lib/librrd.a; then # path given as parameter
|
||||
RRDTOOL_DIR=$PHP_RRD
|
||||
RRDTOOL_INCDIR=$PHP_RRD/include
|
||||
RRDTOOL_LIBDIR=$PHP_RRD/lib
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([The specified RRDTool path is invalid or the installation is incomplete
|
||||
Please specify another path or reinstall the rrdtool distribution])
|
||||
fi
|
||||
else
|
||||
dnl Header path
|
||||
AC_MSG_CHECKING([for rrdtool header files in default path])
|
||||
for i in /usr/local/rrdtool /usr/local /usr /opt ""; do
|
||||
test -r $i/include/rrd.h && RRDTOOL_DIR=$i && RRDTOOL_INCDIR=$i/include
|
||||
done
|
||||
if test -z "$RRDTOOL_INCDIR"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Please reinstall the rrdtool distribution])
|
||||
else
|
||||
AC_MSG_RESULT(found in $RRDTOOL_INCDIR)
|
||||
fi
|
||||
dnl Library path
|
||||
AC_MSG_CHECKING([for rrdtool library files in default path])
|
||||
for i in librrd.$SHLIB_SUFFIX_NAME librrd.a; do
|
||||
test -f $RRDTOOL_DIR/lib/$i && RRDTOOL_LIBDIR=$RRDTOOL_DIR/lib
|
||||
done
|
||||
if test -z "$RRDTOOL_LIBDIR"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Please reinstall the rrdtool distribution])
|
||||
else
|
||||
AC_MSG_RESULT(found in $RRDTOOL_LIBDIR)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Finish the setup
|
||||
|
||||
RRD_H_PATH="$RRDTOOL_INCDIR/rrd.h"
|
||||
PHP_RRDTOOL_DIR=$RRDTOOL_DIR
|
||||
PHP_ADD_INCLUDE($RRDTOOL_INCDIR)
|
||||
|
||||
PHP_CHECK_LIBRARY(rrd, rrd_create,
|
||||
[],[
|
||||
PHP_CHECK_LIBRARY(rrd, rrd_create,
|
||||
[],[
|
||||
AC_MSG_ERROR([wrong rrd lib version or lib not found])
|
||||
],[
|
||||
-L$RRDTOOL_LIBDIR -ldl
|
||||
])
|
||||
],[
|
||||
-L$RRDTOOL_LIBDIR -ldl
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([rrdtool version])
|
||||
AC_TRY_COMPILE([
|
||||
#include <$RRD_H_PATH>
|
||||
], [int main() {
|
||||
double some_variable;
|
||||
some_variable = rrd_version();
|
||||
}
|
||||
], [
|
||||
AC_MSG_RESULT([1.2.x])
|
||||
ac_cv_rrdversion=yes
|
||||
], [
|
||||
AC_MSG_RESULT([1.0.x])
|
||||
ac_cv_rrdversion=no
|
||||
])
|
||||
|
||||
if test "$ac_cv_rrdversion" = yes; then
|
||||
AC_DEFINE(HAVE_RRD_12X, 1, [Whether you have rrd_version])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(rrd, $RRDTOOL_LIBDIR, RRD_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(rrd, rrd.c rrd_graph.c rrd_create.c rrd_update.c, $ext_shared)
|
||||
PHP_SUBST(RRD_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_RRDTOOL, 1, [ ])
|
||||
fi
|
||||
38
php_rrd.h
Normal file
38
php_rrd.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef PHP_RRD_H
|
||||
#define PHP_RRD_H
|
||||
|
||||
extern zend_module_entry rrd_module_entry;
|
||||
#define phpext_rrd_ptr &rrd_module_entry
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
typedef struct _rrd_args {
|
||||
int count;
|
||||
char **args;
|
||||
} rrd_args;
|
||||
|
||||
rrd_args *rrd_args_init_by_phparray(const char *command_name, const char *filename,
|
||||
const zval *options TSRMLS_DC);
|
||||
void rrd_args_free(rrd_args *args);
|
||||
|
||||
#endif /* PHP_RRD_H */
|
||||
136
rrd.c
Normal file
136
rrd.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
#include "php_rrd.h"
|
||||
#include "rrd_graph.h"
|
||||
#include "rrd_create.h"
|
||||
#include "rrd_update.h"
|
||||
|
||||
/* {{{ */
|
||||
static function_entry rrd_functions[] = {
|
||||
PHP_FE(rrd_update, arginfo_rrd_update)
|
||||
PHP_FE(rrd_create, arginfo_rrd_create)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_RRD
|
||||
ZEND_GET_MODULE(rrd)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
static PHP_MINIT_FUNCTION(rrd)
|
||||
{
|
||||
rrd_graph_minit(TSRMLS_CC);
|
||||
rrd_create_minit(TSRMLS_CC);
|
||||
rrd_update_minit(TSRMLS_CC);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION */
|
||||
static PHP_MINFO_FUNCTION(rrd)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "rrd wrapper", "enabled");
|
||||
php_info_print_table_row(2, "Version", "0.1");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rrd module_entry */
|
||||
zend_module_entry rrd_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"rrd",
|
||||
rrd_functions,
|
||||
PHP_MINIT(rrd),
|
||||
NULL, /* PHP_MSHUTDOWN(rrd) */
|
||||
NULL, /* PHP_RINIT(rrd) */
|
||||
NULL, /* PHP_RSHUTDOWN(rrd) */
|
||||
PHP_MINFO(rrd),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Inits rrd arguments object for a particular rrd command by php array
|
||||
* filename paremeter is optional.
|
||||
*/
|
||||
rrd_args *rrd_args_init_by_phparray(const char *command_name, const char *filename,
|
||||
const zval *options TSRMLS_DC)
|
||||
{
|
||||
uint i, option_count, args_counter = 2;
|
||||
|
||||
if (Z_TYPE_P(options) != IS_ARRAY) return NULL;
|
||||
option_count = zend_hash_num_elements(Z_ARRVAL_P(options));
|
||||
if (!option_count) return NULL;
|
||||
if (!strlen(command_name)) return NULL;
|
||||
|
||||
rrd_args *result = (rrd_args *)emalloc(sizeof(rrd_args));
|
||||
/* "dummy" + command_name + filename if presented */
|
||||
result->count = option_count + (strlen(command_name) ? 3 : 2);
|
||||
result->args = (char **)safe_emalloc(result->count, sizeof(char *), 0);
|
||||
|
||||
/* "dummy" and command_name are needed always needed */
|
||||
result->args[0] = "dummy";
|
||||
result->args[1] = estrdup(filename);
|
||||
|
||||
/* append filename if it's presented */
|
||||
if (strlen(filename)) result->args[args_counter++] = estrdup(filename);
|
||||
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(options));
|
||||
for(i=0; i<option_count; i++) {
|
||||
zval **item;
|
||||
smart_str option = {0}; /* one argument option */
|
||||
|
||||
/* force using strings as array items */
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(options), (void**) &item);
|
||||
if (Z_TYPE_PP(item) != IS_STRING) convert_to_string(*item);
|
||||
smart_str_appendl(&option, Z_STRVAL_PP(item), Z_STRLEN_PP(item));
|
||||
smart_str_0(&option);
|
||||
|
||||
result->args[args_counter++] = estrdup(option.c);
|
||||
smart_str_free(&option);
|
||||
|
||||
zend_hash_move_forward(Z_ARRVAL_P(options));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Frees all memory for arguments object
|
||||
*/
|
||||
void rrd_args_free(rrd_args *args)
|
||||
{
|
||||
int i;
|
||||
if (!args || !args->args) return;
|
||||
|
||||
for (i=1; i<args->count; i++)
|
||||
efree(args->args[i]);
|
||||
|
||||
efree(args->args);
|
||||
efree(args);
|
||||
}
|
||||
/* }}} */
|
||||
407
rrd_create.c
Normal file
407
rrd_create.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rrd.h>
|
||||
#include "php.h"
|
||||
#include "rrd_create.h"
|
||||
#include "php_rrd.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
|
||||
/* declare class entry */
|
||||
static zend_class_entry *ce_rrd_create;
|
||||
/* declare class handlers */
|
||||
static zend_object_handlers rrd_create_handlers;
|
||||
|
||||
/* overloading the standard zend object structure (std property) in the need
|
||||
of having dedicated creating/cloning/destruction functions
|
||||
*/
|
||||
typedef struct _rrd_create_object {
|
||||
zend_object std;
|
||||
/** path to newly created rrd file */
|
||||
char *file_path;
|
||||
/* "--start" parameters in rrd create */
|
||||
char *start_time;
|
||||
/* "--step" parameters in rrd create */
|
||||
zval *zv_step;
|
||||
/* "DS" parameters in rrd create */
|
||||
zval *zv_arr_data_sources;
|
||||
/* "RRA" parameters in rrd create */
|
||||
zval *zv_arr_archives;
|
||||
} rrd_create_object;
|
||||
|
||||
/* {{{ rrd_create_object_dtor
|
||||
close all resources and the memory allocated for our internal object
|
||||
*/
|
||||
static void rrd_create_object_dtor(void *object TSRMLS_DC)
|
||||
{
|
||||
rrd_create_object *intern_obj = (rrd_create_object *)object;
|
||||
|
||||
if (intern_obj->file_path)
|
||||
efree(intern_obj->file_path);
|
||||
if (intern_obj->start_time)
|
||||
efree(intern_obj->start_time);
|
||||
if (intern_obj->zv_step)
|
||||
zval_dtor(intern_obj->zv_step);
|
||||
if (intern_obj->zv_arr_data_sources)
|
||||
zval_dtor(intern_obj->zv_arr_data_sources);
|
||||
if (intern_obj->zv_arr_archives)
|
||||
zval_dtor(intern_obj->zv_arr_archives);
|
||||
|
||||
zend_object_std_dtor(&intern_obj->std TSRMLS_CC);
|
||||
efree(intern_obj);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rrd_create_object_new
|
||||
creates new rrd create object
|
||||
*/
|
||||
static zend_object_value rrd_create_object_new(zend_class_entry *ce TSRMLS_DC)
|
||||
{
|
||||
rrd_create_object *intern_obj;
|
||||
zend_object_value retval;
|
||||
zval *tmp;
|
||||
|
||||
intern_obj = ecalloc(1, sizeof(*intern_obj));
|
||||
zend_object_std_init(&intern_obj->std, ce TSRMLS_CC);
|
||||
|
||||
intern_obj->file_path = NULL;
|
||||
intern_obj->start_time = NULL;
|
||||
intern_obj->zv_step = NULL;
|
||||
intern_obj->zv_arr_data_sources = NULL;
|
||||
intern_obj->zv_arr_archives = NULL;
|
||||
|
||||
zend_hash_copy(intern_obj->std.properties, &ce->default_properties,
|
||||
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval*)
|
||||
);
|
||||
|
||||
retval.handle = zend_objects_store_put(intern_obj,
|
||||
(zend_objects_store_dtor_t)zend_objects_destroy_object,
|
||||
rrd_create_object_dtor, NULL TSRMLS_CC
|
||||
);
|
||||
|
||||
retval.handlers = &rrd_create_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void RRDCreator::__construct(string path [,string startTime]
|
||||
[,int step])
|
||||
creates new object for creating rrd database
|
||||
*/
|
||||
PHP_METHOD(RRDCreator, __construct)
|
||||
{
|
||||
rrd_create_object *intern_obj;
|
||||
char *path; int path_length;
|
||||
/* better to set defaults for optional parameters */
|
||||
char *start_time = NULL; int start_time_length = 0;
|
||||
uint step = 0;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
|
||||
if (zend_parse_parameters(argc TSRMLS_CC, "s|sl", &path, &path_length,
|
||||
&start_time, &start_time_length, &step) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path_length == 0) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"path for rrd file cannot be empty string", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc > 1 && start_time_length == 0) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"startTime cannot be empty string", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
if (argc > 2 && step <= 0) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"step parameter must be greater then 0", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_create_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
intern_obj->file_path = estrdup(path);
|
||||
if (start_time) intern_obj->start_time = estrdup(start_time);
|
||||
if (step) {
|
||||
MAKE_STD_ZVAL(intern_obj->zv_step);
|
||||
ZVAL_LONG(intern_obj->zv_step,step);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto RRDCreator::addDataSource(string description)
|
||||
Add information about data source
|
||||
*/
|
||||
PHP_METHOD(RRDCreator, addDataSource)
|
||||
{
|
||||
rrd_create_object *intern_obj;
|
||||
char *desc, *rrd_source_desc;
|
||||
int desc_length;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &desc, &desc_length) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc_length == 0) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"description parameter cannot be empty string", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_create_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (!intern_obj->zv_arr_data_sources) {
|
||||
MAKE_STD_ZVAL(intern_obj->zv_arr_data_sources);
|
||||
array_init(intern_obj->zv_arr_data_sources);
|
||||
}
|
||||
|
||||
rrd_source_desc = emalloc(desc_length + 4);
|
||||
strcpy(rrd_source_desc, "DS:");
|
||||
strcat(rrd_source_desc, desc);
|
||||
|
||||
add_next_index_string(intern_obj->zv_arr_data_sources, rrd_source_desc, 1);
|
||||
efree(rrd_source_desc);
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto RRDCreator::addArchive(string description)
|
||||
Add information about new round robin archive
|
||||
*/
|
||||
PHP_METHOD(RRDCreator, addArchive)
|
||||
{
|
||||
rrd_create_object *intern_obj;
|
||||
char *desc, *rrd_archive_desc;
|
||||
int desc_length;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &desc, &desc_length) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc_length == 0) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"description parameter cannot be empty string", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_create_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (!intern_obj->zv_arr_archives) {
|
||||
MAKE_STD_ZVAL(intern_obj->zv_arr_archives);
|
||||
array_init(intern_obj->zv_arr_archives);
|
||||
}
|
||||
|
||||
rrd_archive_desc = emalloc(desc_length + 5);
|
||||
strcpy(rrd_archive_desc, "RRA:");
|
||||
strcat(rrd_archive_desc, desc);
|
||||
|
||||
add_next_index_string(intern_obj->zv_arr_archives, rrd_archive_desc, 1);
|
||||
efree(rrd_archive_desc);
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rrd_create_add_string_arg
|
||||
Adds strings form php array into array (in C sense) of arguments for rrd_create
|
||||
call
|
||||
@param argv "C" array of arguments for rrd_create, is already allocated
|
||||
with "counter param" filled elements
|
||||
@param arr php array of strings
|
||||
@param counter count of filled elements in array, is increased for each newly
|
||||
added string
|
||||
*/
|
||||
static void rrd_create_add_string_arg(char **argv, zval *arr, uint *counter TSRMLS_DC)
|
||||
{
|
||||
uint elements = zend_hash_num_elements(Z_ARRVAL_P(arr));
|
||||
uint i;
|
||||
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(arr));
|
||||
for(i=0; i<elements; i++) {
|
||||
char *str_key;
|
||||
zval **item;
|
||||
smart_str option = {0}; /* one argument option */
|
||||
|
||||
/* Data are always string, because they are added via setters, which
|
||||
* forces using strings as arguments.
|
||||
*/
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(arr), (void**) &item);
|
||||
smart_str_appendl(&option, Z_STRVAL_PP(item), Z_STRLEN_PP(item));
|
||||
smart_str_0(&option);
|
||||
|
||||
argv[(*counter)++] = estrdup(option.c);
|
||||
smart_str_free(&option);
|
||||
|
||||
if (i<elements) zend_hash_move_forward(Z_ARRVAL_P(arr));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array RRDCreator::save()
|
||||
Saves new rrd database according to current properties.
|
||||
*/
|
||||
PHP_METHOD(RRDCreator, save)
|
||||
{
|
||||
rrd_create_object *intern_obj = (rrd_create_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
/* array of arguments for rrd_create call */
|
||||
char **argv;
|
||||
uint argc,arg_counter,i;
|
||||
uint archive_count = zend_hash_num_elements(Z_ARRVAL_P(intern_obj->zv_arr_archives));
|
||||
uint data_source_count = zend_hash_num_elements(Z_ARRVAL_P(intern_obj->zv_arr_data_sources));
|
||||
|
||||
/* 0-2 are defined below + start_time + step = 5 options */
|
||||
argc = archive_count + data_source_count + 5;
|
||||
|
||||
argv = (char **) safe_emalloc(argc, sizeof(char *), 0);
|
||||
/* "dummy" and "create" arguments are needed */
|
||||
argv[0] = "dummy";
|
||||
argv[1] = estrdup("create");
|
||||
argv[2] = estrdup(intern_obj->file_path);
|
||||
arg_counter = 3;
|
||||
|
||||
if (intern_obj->start_time) {
|
||||
const char *prefix = "--start=";
|
||||
char *start_time_str = emalloc(strlen(intern_obj->start_time)
|
||||
+ strlen(prefix) + 1);
|
||||
|
||||
strcpy(start_time_str, prefix);
|
||||
strcat(start_time_str, intern_obj->start_time);
|
||||
|
||||
argv[arg_counter++] = estrdup(start_time_str);
|
||||
efree(start_time_str);
|
||||
} else {
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (intern_obj->zv_step) {
|
||||
const char *prefix = "--step=";
|
||||
char *start_time_str;
|
||||
|
||||
convert_to_string(intern_obj->zv_step);
|
||||
start_time_str = emalloc(strlen(prefix) + Z_STRLEN_P(intern_obj->zv_step) + 1);
|
||||
|
||||
strcpy(start_time_str, prefix);
|
||||
strcat(start_time_str, Z_STRVAL_P(intern_obj->zv_step));
|
||||
|
||||
argv[arg_counter++] = estrdup(start_time_str);
|
||||
/* back to long, doesn't needed, but we are consistent */
|
||||
convert_to_long(intern_obj->zv_step);
|
||||
efree(start_time_str);
|
||||
} else {
|
||||
argc--;
|
||||
}
|
||||
|
||||
/* add array of archive, data source strings into argument list for rrd_create */
|
||||
rrd_create_add_string_arg(argv, intern_obj->zv_arr_data_sources, &arg_counter TSRMLS_CC);
|
||||
rrd_create_add_string_arg(argv, intern_obj->zv_arr_archives, &arg_counter TSRMLS_CC);
|
||||
|
||||
if (rrd_test_error()) rrd_clear_error();
|
||||
|
||||
/* call rrd_create and test if fails */
|
||||
if (rrd_create(argc-1, &argv[1]) == -1) {
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
efree(argv[i]);
|
||||
|
||||
/* throw exception with rrd error string */
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), rrd_get_error(), 0 TSRMLS_CC);
|
||||
rrd_clear_error();
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
efree(argv[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int rrd_create(string file, array options)
|
||||
Create an RRD file with the options passed
|
||||
*/
|
||||
PHP_FUNCTION(rrd_create)
|
||||
{
|
||||
char *filename;
|
||||
int filename_length;
|
||||
zval *zv_arr_options;
|
||||
rrd_args *argv;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &filename,
|
||||
&filename_length, &zv_arr_options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(filename TSRMLS_CC)) RETURN_FALSE;
|
||||
|
||||
argv = rrd_args_init_by_phparray("create", filename, zv_arr_options TSRMLS_CC);
|
||||
if (!argv) {
|
||||
zend_error(E_WARNING, "cannot allocate arguments options");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (rrd_test_error()) rrd_clear_error();
|
||||
|
||||
if (rrd_create(argv->count - 1, &argv->args[1]) == -1 ) {
|
||||
RETVAL_FALSE;
|
||||
} else {
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
|
||||
rrd_args_free(argv);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* arguments */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_ARG_INFO(0, startTime)
|
||||
ZEND_ARG_INFO(0, step)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_description, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, description)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* class method table */
|
||||
static zend_function_entry rrd_create_methods[] = {
|
||||
PHP_ME(RRDCreator, __construct, arginfo_construct, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDCreator, save, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDCreator, addDataSource, arginfo_description, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDCreator, addArchive, arginfo_description, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* minit hook, called from main module minit */
|
||||
void rrd_create_minit(TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
INIT_CLASS_ENTRY(ce, "RRDCreator", rrd_create_methods);
|
||||
ce.create_object = rrd_create_object_new;
|
||||
ce_rrd_create = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
memcpy(&rrd_create_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
rrd_create_handlers.clone_obj = NULL;
|
||||
}
|
||||
|
||||
30
rrd_create.h
Normal file
30
rrd_create.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RRD_CREATE_H
|
||||
#define RRD_CREATE_H
|
||||
|
||||
void rrd_create_minit(TSRMLS_DC);
|
||||
PHP_FUNCTION(rrd_create);
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_rrd_create, 0)
|
||||
ZEND_ARG_INFO(0, file)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#endif /* RRD_CREATE_H */
|
||||
264
rrd_graph.c
Normal file
264
rrd_graph.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rrd.h>
|
||||
#include "php.h"
|
||||
#include "rrd_graph.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
|
||||
/* declare class entry */
|
||||
static zend_class_entry *ce_rrd_graph;
|
||||
/* declare class handlers */
|
||||
static zend_object_handlers rrd_graph_handlers;
|
||||
|
||||
/* overloading the standard zend object structure (std property) in the need
|
||||
of having dedicated creating/cloning/destruction functions
|
||||
*/
|
||||
typedef struct _rrd_graph_object {
|
||||
zend_object std;
|
||||
char *file_path;
|
||||
zval *zv_arr_options;
|
||||
} rrd_graph_object;
|
||||
|
||||
/* {{{ rrd_graph_object_dtor
|
||||
close all resources and the memory allocated for our internal object
|
||||
*/
|
||||
static void rrd_graph_object_dtor(void *object TSRMLS_DC)
|
||||
{
|
||||
rrd_graph_object *intern_obj = (rrd_graph_object *)object;
|
||||
|
||||
if (intern_obj->file_path)
|
||||
efree(intern_obj->file_path);
|
||||
if (intern_obj->zv_arr_options) {
|
||||
zval_dtor(intern_obj->zv_arr_options);
|
||||
}
|
||||
|
||||
zend_object_std_dtor(&intern_obj->std TSRMLS_CC);
|
||||
efree(intern_obj);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rrd_graph_object_new
|
||||
creates new rrd graph object
|
||||
*/
|
||||
static zend_object_value rrd_graph_object_new(zend_class_entry *ce TSRMLS_DC)
|
||||
{
|
||||
rrd_graph_object *intern_obj;
|
||||
zend_object_value retval;
|
||||
zval *tmp;
|
||||
|
||||
intern_obj = ecalloc(1, sizeof(*intern_obj));
|
||||
zend_object_std_init(&intern_obj->std, ce TSRMLS_CC);
|
||||
intern_obj->file_path = NULL;
|
||||
intern_obj->zv_arr_options = NULL;
|
||||
|
||||
zend_hash_copy(intern_obj->std.properties, &ce->default_properties,
|
||||
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval*)
|
||||
);
|
||||
|
||||
retval.handle = zend_objects_store_put(intern_obj,
|
||||
(zend_objects_store_dtor_t)zend_objects_destroy_object,
|
||||
rrd_graph_object_dtor, NULL TSRMLS_CC
|
||||
);
|
||||
|
||||
retval.handlers = &rrd_graph_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void RRDGraph::__construct(string path)
|
||||
creates new object for rrd graph function
|
||||
*/
|
||||
PHP_METHOD(RRDGraph, __construct)
|
||||
{
|
||||
rrd_graph_object *intern_obj;
|
||||
char *path;
|
||||
int path_length;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_length) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_graph_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
intern_obj->file_path = estrdup(path);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void RRDGraph::setOptions(array options)
|
||||
set command options for rrd graph call
|
||||
*/
|
||||
PHP_METHOD(RRDGraph, setOptions)
|
||||
{
|
||||
rrd_graph_object *intern_obj;
|
||||
zval *zv_arr_options;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zv_arr_options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_graph_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
/* if our array is initialized, so delete it first */
|
||||
if (intern_obj->zv_arr_options) {
|
||||
zval_dtor(intern_obj->zv_arr_options);
|
||||
}
|
||||
|
||||
/* copy array from parameter */
|
||||
MAKE_STD_ZVAL(intern_obj->zv_arr_options);
|
||||
*intern_obj->zv_arr_options = *zv_arr_options;
|
||||
zval_copy_ctor(intern_obj->zv_arr_options);
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array RRDGraph::save()
|
||||
Saves graph according to current properties.
|
||||
*/
|
||||
PHP_METHOD(RRDGraph, save)
|
||||
{
|
||||
rrd_graph_object *intern_obj = (rrd_graph_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
int xsize, ysize;
|
||||
double ymin,ymax;
|
||||
char **calcpr;
|
||||
/* array of arguments for rrd_graph call */
|
||||
char **argv;
|
||||
unsigned int argc,i;
|
||||
|
||||
if (!intern_obj->zv_arr_options || Z_TYPE_P(intern_obj->zv_arr_options) != IS_ARRAY) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"options aren't correctly set", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rrd_test_error()) rrd_clear_error();
|
||||
|
||||
argc = zend_hash_num_elements(Z_ARRVAL_P(intern_obj->zv_arr_options)) + 3;
|
||||
argv = (char **) safe_emalloc(argc, sizeof(char *), 0);
|
||||
/* "dummy" and "graph" arguments are needed */
|
||||
argv[0] = "dummy";
|
||||
argv[1] = estrdup("graph");
|
||||
argv[2] = estrdup(intern_obj->file_path);
|
||||
|
||||
/* makes array of arguments for rrd_graph call from options array */
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(intern_obj->zv_arr_options));
|
||||
for(i=3; i<argc; i++) {
|
||||
char *str_key;
|
||||
ulong num_key;
|
||||
zval **item;
|
||||
smart_str option = {0}; /* one argument option */
|
||||
|
||||
/* option with string key means long option, hence they are used as
|
||||
"key=value" e.g. "--start=920804400"
|
||||
*/
|
||||
if (zend_hash_get_current_key(Z_ARRVAL_P(intern_obj->zv_arr_options), &str_key, &num_key, 0) == HASH_KEY_IS_STRING) {
|
||||
smart_str_appends(&option, str_key);
|
||||
smart_str_appendc(&option, '=');
|
||||
};
|
||||
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(intern_obj->zv_arr_options), (void**) &item);
|
||||
|
||||
if (Z_TYPE_PP(item) != IS_STRING)
|
||||
convert_to_string(*item);
|
||||
|
||||
smart_str_appendl(&option, Z_STRVAL_PP(item), Z_STRLEN_PP(item));
|
||||
smart_str_0(&option);
|
||||
|
||||
argv[i] = estrdup(option.c);
|
||||
|
||||
smart_str_free(&option);
|
||||
|
||||
if (i<argc) zend_hash_move_forward(Z_ARRVAL_P(intern_obj->zv_arr_options));
|
||||
}
|
||||
|
||||
/* call rrd graph and test if fails */
|
||||
if (rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) == -1) {
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
efree(argv[i]);
|
||||
|
||||
/* throw exception with rrd error string */
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), rrd_get_error(), 0 TSRMLS_CC);
|
||||
rrd_clear_error();
|
||||
return;
|
||||
}
|
||||
|
||||
/* rrd_graph call was OK, so copy rrd_graph return values which are stored
|
||||
in calcpr to php array
|
||||
*/
|
||||
zval zv_calcpr_array;
|
||||
|
||||
INIT_PZVAL(&zv_calcpr_array)
|
||||
array_init(&zv_calcpr_array);
|
||||
if (calcpr) {
|
||||
for (i=0; calcpr[i]; i++) {
|
||||
add_next_index_string(&zv_calcpr_array, calcpr[i], 1);
|
||||
free(calcpr[i]);
|
||||
}
|
||||
free(calcpr);
|
||||
}
|
||||
|
||||
/* made return value */
|
||||
array_init(return_value);
|
||||
add_assoc_long(return_value, "xsize", xsize);
|
||||
add_assoc_long(return_value, "ysize", ysize);
|
||||
/* add calcpr return values under "calcpr" key */
|
||||
zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"),
|
||||
(void *)&zv_calcpr_array, sizeof(zval *), NULL);
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
efree(argv[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* arguments */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rrd_path, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rrd_options, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* class method table */
|
||||
static zend_function_entry rrd_graph_methods[] = {
|
||||
PHP_ME(RRDGraph, __construct, arginfo_rrd_path, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDGraph, save, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDGraph, setOptions, arginfo_rrd_options, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* minit hook, called from main module minit */
|
||||
void rrd_graph_minit(TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
INIT_CLASS_ENTRY(ce, "RRDGraph", rrd_graph_methods);
|
||||
ce.create_object = rrd_graph_object_new;
|
||||
ce_rrd_graph = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
memcpy(&rrd_graph_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
rrd_graph_handlers.clone_obj = NULL;
|
||||
}
|
||||
24
rrd_graph.h
Normal file
24
rrd_graph.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RRD_GRAPH_H
|
||||
#define RRD_GRAPH_H
|
||||
|
||||
void rrd_graph_minit(TSRMLS_DC);
|
||||
|
||||
#endif /* RRD_GRAPH_H */
|
||||
285
rrd_update.c
Normal file
285
rrd_update.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rrd.h>
|
||||
#include "php.h"
|
||||
#include "php_rrd.h"
|
||||
#include "rrd_update.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
|
||||
/* declare class entry */
|
||||
static zend_class_entry *ce_rrd_update;
|
||||
/* declare class handlers */
|
||||
static zend_object_handlers rrd_update_handlers;
|
||||
|
||||
/* overloading the standard zend object structure (std property) in the need
|
||||
of having dedicated creating/cloning/destruction functions
|
||||
*/
|
||||
typedef struct _rrd_update_object {
|
||||
zend_object std;
|
||||
|
||||
/** path to newly created rrd file */
|
||||
char *file_path;
|
||||
} rrd_update_object;
|
||||
|
||||
/* {{{ rrd_update_object_dtor
|
||||
close all resources and the memory allocated for our internal object
|
||||
*/
|
||||
static void rrd_update_object_dtor(void *object TSRMLS_DC)
|
||||
{
|
||||
rrd_update_object *intern_obj = (rrd_update_object *)object;
|
||||
|
||||
if (intern_obj->file_path)
|
||||
efree(intern_obj->file_path);
|
||||
|
||||
zend_object_std_dtor(&intern_obj->std TSRMLS_CC);
|
||||
efree(intern_obj);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ rrd_update_object_new
|
||||
creates new rrd update object
|
||||
*/
|
||||
static zend_object_value rrd_update_object_new(zend_class_entry *ce TSRMLS_DC)
|
||||
{
|
||||
rrd_update_object *intern_obj;
|
||||
zend_object_value retval;
|
||||
zval *tmp;
|
||||
|
||||
intern_obj = ecalloc(1, sizeof(*intern_obj));
|
||||
zend_object_std_init(&intern_obj->std, ce TSRMLS_CC);
|
||||
|
||||
intern_obj->file_path = NULL;
|
||||
|
||||
zend_hash_copy(intern_obj->std.properties, &ce->default_properties,
|
||||
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval*)
|
||||
);
|
||||
|
||||
retval.handle = zend_objects_store_put(intern_obj,
|
||||
(zend_objects_store_dtor_t)zend_objects_destroy_object,
|
||||
rrd_update_object_dtor, NULL TSRMLS_CC
|
||||
);
|
||||
|
||||
retval.handlers = &rrd_update_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void RRDUpdater::__construct(string path)
|
||||
creates new object for rrd update function
|
||||
*/
|
||||
PHP_METHOD(RRDUpdater, __construct)
|
||||
{
|
||||
rrd_update_object *intern_obj;
|
||||
char *path;
|
||||
int path_length;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_length) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_update_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
intern_obj->file_path = estrdup(path);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array RRDUpdater::update(array $values, [string time=time()])
|
||||
Updates data sources in RRD database
|
||||
*/
|
||||
PHP_METHOD(RRDUpdater, update)
|
||||
{
|
||||
rrd_update_object *intern_obj;
|
||||
zval *zv_values_array;
|
||||
|
||||
zval *zv_update_argv;
|
||||
rrd_args *update_argv;
|
||||
|
||||
char *time = NULL;
|
||||
int time_str_length = 0;
|
||||
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
uint ds_count,i;
|
||||
/* string for all data source names formated for rrd_update call */
|
||||
smart_str ds_names = {0};
|
||||
/* string for all data source values for rrd_update call */
|
||||
smart_str ds_vals = {0};
|
||||
|
||||
if (zend_parse_parameters(argc TSRMLS_CC, "a|s", &zv_values_array, &time,
|
||||
&time_str_length) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ds_count = zend_hash_num_elements(Z_ARRVAL_P(zv_values_array));
|
||||
if (ds_count<=0) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
intern_obj = (rrd_update_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (php_check_open_basedir(intern_obj->file_path TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (time_str_length == 0) {
|
||||
if (argc > 1) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
|
||||
"time cannot be empty string", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
/* default time string, see rrdtool update man page, it's need to be
|
||||
freed
|
||||
*/
|
||||
time = estrdup("N");
|
||||
}
|
||||
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(zv_values_array));
|
||||
for(i=0; i<ds_count; i++) {
|
||||
char *ds_name;
|
||||
zval **ds_val;
|
||||
|
||||
if (ds_names.len) smart_str_appendc(&ds_names, ':');
|
||||
else smart_str_appends(&ds_names,"--template=");
|
||||
|
||||
zend_hash_get_current_key(Z_ARRVAL_P(zv_values_array), &ds_name, NULL, 0);
|
||||
smart_str_appends(&ds_names, ds_name);
|
||||
|
||||
/* "timestamp:value" string */
|
||||
smart_str_appends(&ds_vals, time);
|
||||
smart_str_appendc(&ds_vals, ':');
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(zv_values_array), (void**) &ds_val);
|
||||
if (Z_TYPE_PP(ds_val) != IS_STRING)
|
||||
convert_to_string(*ds_val);
|
||||
smart_str_appendl(&ds_vals, Z_STRVAL_PP(ds_val), Z_STRLEN_PP(ds_val));
|
||||
};
|
||||
|
||||
smart_str_0(&ds_names);
|
||||
smart_str_0(&ds_vals);
|
||||
|
||||
/* add copy of names and values strings into arguments array and free
|
||||
* original strings
|
||||
*/
|
||||
MAKE_STD_ZVAL(zv_update_argv);
|
||||
array_init(zv_update_argv);
|
||||
add_next_index_string(zv_update_argv, ds_names.c, 1);
|
||||
add_next_index_string(zv_update_argv, ds_vals.c, 1);
|
||||
smart_str_free(&ds_names);
|
||||
smart_str_free(&ds_vals);
|
||||
|
||||
update_argv = rrd_args_init_by_phparray("update", intern_obj->file_path, zv_update_argv TSRMLS_CC);
|
||||
if (!update_argv) {
|
||||
zend_error(E_WARNING, "cannot allocate arguments options");
|
||||
zval_dtor(zv_update_argv);
|
||||
if (time_str_length == 0) efree(time);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (rrd_test_error()) rrd_clear_error();
|
||||
|
||||
/* call rrd_update and test if fails */
|
||||
if (rrd_update(update_argv->count - 1, &update_argv->args[1]) == -1) {
|
||||
zval_dtor(zv_update_argv);
|
||||
rrd_args_free(update_argv);
|
||||
if (time_str_length == 0) efree(time);
|
||||
|
||||
/* throw exception with rrd error string */
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), rrd_get_error(), 0 TSRMLS_CC);
|
||||
rrd_clear_error();
|
||||
return;
|
||||
}
|
||||
|
||||
/* parameter isn't presented and we alloced default one, so we neeed to
|
||||
* freed
|
||||
*/
|
||||
if (time_str_length == 0) efree(time);
|
||||
zval_dtor(zv_update_argv);
|
||||
rrd_args_free(update_argv);
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int rrd_update(string file, array options)
|
||||
Updates the RRD file with a particular options and values.
|
||||
*/
|
||||
PHP_FUNCTION(rrd_update)
|
||||
{
|
||||
char *filename;
|
||||
int filename_length;
|
||||
zval *zv_arr_options;
|
||||
rrd_args *argv;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &filename,
|
||||
&filename_length, &zv_arr_options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(filename TSRMLS_CC)) RETURN_FALSE;
|
||||
|
||||
argv = rrd_args_init_by_phparray("update", filename, zv_arr_options TSRMLS_CC);
|
||||
if (!argv) {
|
||||
zend_error(E_WARNING, "cannot allocate arguments options");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (rrd_test_error()) rrd_clear_error();
|
||||
|
||||
if (rrd_update(argv->count - 1, &argv->args[1]) == -1 ) {
|
||||
RETVAL_FALSE;
|
||||
} else {
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
|
||||
rrd_args_free(argv);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* arguments */
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_construct, 0)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_update, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, values)
|
||||
ZEND_ARG_INFO(0, time)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* class method table */
|
||||
static zend_function_entry rrd_update_methods[] = {
|
||||
PHP_ME(RRDUpdater, __construct, arginfo_construct, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RRDUpdater, update, arginfo_update, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* minit hook, called from main module minit */
|
||||
void rrd_update_minit(TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
INIT_CLASS_ENTRY(ce, "RRDUpdater", rrd_update_methods);
|
||||
ce.create_object = rrd_update_object_new;
|
||||
ce_rrd_update = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
memcpy(&rrd_update_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
rrd_update_handlers.clone_obj = NULL;
|
||||
}
|
||||
30
rrd_update.h
Normal file
30
rrd_update.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Miroslav Kubelik <koubel@volny.cz> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RRD_UPDATE_H
|
||||
#define RRD_UPDATE_H
|
||||
|
||||
void rrd_update_minit(TSRMLS_DC);
|
||||
PHP_FUNCTION(rrd_update);
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_rrd_update, 0)
|
||||
ZEND_ARG_INFO(0, file)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#endif /* RRD_UPDATE_H */
|
||||
10
tests/rrd_001.phpt
Normal file
10
tests/rrd_001.phpt
Normal file
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
rrd module presence test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
echo "rrd extension loaded";
|
||||
?>
|
||||
--EXPECTF--
|
||||
rrd extension loaded
|
||||
62
tests/rrd_002.phpt
Normal file
62
tests/rrd_002.phpt
Normal file
@@ -0,0 +1,62 @@
|
||||
--TEST--
|
||||
RRDGraph test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/graphTest.rrd";
|
||||
$command = "rrdtool create $rrdFile "
|
||||
. "--start 920804400 "
|
||||
. "DS:speed:COUNTER:600:U:U "
|
||||
. "RRA:AVERAGE:0.5:1:24 "
|
||||
. "RRA:AVERAGE:0.5:6:10";
|
||||
echo "creting test.rrd via exec\n";
|
||||
exec($command);
|
||||
|
||||
$updateCommand = array(
|
||||
"rrdtool update $rrdFile 920804700:12345 920805000:12357 920805300:12363",
|
||||
"rrdtool update $rrdFile 920805600:12363 920805900:12363 920806200:12373",
|
||||
"rrdtool update $rrdFile 920806500:12383 920806800:12393 920807100:12399",
|
||||
"rrdtool update $rrdFile 920807400:12405 920807700:12411 920808000:12415",
|
||||
"rrdtool update $rrdFile 920808300:12420 920808600:12422 920808900:12423"
|
||||
);
|
||||
echo "updating test.rrd via exec\n";
|
||||
foreach($updateCommand as $command) {
|
||||
exec($command);
|
||||
}
|
||||
|
||||
$origPngFile = dirname(__FILE__) . "/speed-orig.png";
|
||||
$command = "rrdtool graph $origPngFile "
|
||||
. "--start 920804400 --end 920808000 "
|
||||
. "--vertical-label m/s "
|
||||
. "DEF:myspeed=$rrdFile:speed:AVERAGE "
|
||||
. "CDEF:realspeed=myspeed,1000,* "
|
||||
. "LINE2:realspeed#FF0000";
|
||||
|
||||
echo "exporting speed-orig.png via exec\n";
|
||||
exec($command);
|
||||
|
||||
$outputPngFile = dirname(__FILE__) . "/speed.png";
|
||||
$graphObj = new RRDGraph($outputPngFile);
|
||||
$graphObj->setOptions(array(
|
||||
"--start" => "920804400",
|
||||
"--end" => "920808000",
|
||||
"--vertical-label" => "m/s",
|
||||
"DEF:myspeed=$rrdFile:speed:AVERAGE",
|
||||
"CDEF:realspeed=myspeed,1000,*",
|
||||
"LINE2:realspeed#FF0000"
|
||||
));
|
||||
var_dump($graphObj->save());
|
||||
?>
|
||||
--EXPECTF--
|
||||
creting test.rrd via exec
|
||||
updating test.rrd via exec
|
||||
exporting speed-orig.png via exec
|
||||
array(3) {
|
||||
["xsize"]=>
|
||||
int(497)
|
||||
["ysize"]=>
|
||||
int(149)
|
||||
["calcpr"]=>
|
||||
NULL
|
||||
}
|
||||
23
tests/rrd_003.phpt
Normal file
23
tests/rrd_003.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
RRDCreator test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/createOrig.rrd";
|
||||
$command = "rrdtool create $rrdFile "
|
||||
. "--start 920804400 "
|
||||
. "DS:speed:COUNTER:600:U:U "
|
||||
. "RRA:AVERAGE:0.5:1:24 "
|
||||
. "RRA:AVERAGE:0.5:6:10";
|
||||
echo "creating original rrd for RRDCreator via exec\n";
|
||||
exec($command);
|
||||
|
||||
$creator = new RRDCreator(dirname(__FILE__) . "/createTest.rrd","now -10d", 500);
|
||||
$creator->addDataSource("speed:COUNTER:600:U:U");
|
||||
$creator->addArchive("AVERAGE:0.5:1:24");
|
||||
$creator->addArchive("AVERAGE:0.5:6:10");
|
||||
$creator->save();
|
||||
?>
|
||||
--EXPECTF--
|
||||
creating original rrd for RRDCreator via exec
|
||||
55
tests/rrd_004.phpt
Normal file
55
tests/rrd_004.phpt
Normal file
@@ -0,0 +1,55 @@
|
||||
--TEST--
|
||||
RRDUpdater test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/updateTest.rrd";
|
||||
$command = "rrdtool create $rrdFile "
|
||||
. "--start 920804400 "
|
||||
. "DS:speed:COUNTER:600:U:U "
|
||||
. "RRA:AVERAGE:0.5:1:24 "
|
||||
. "RRA:AVERAGE:0.5:6:10";
|
||||
echo "creating rrdfile for update test via exec\n";
|
||||
exec($command);
|
||||
|
||||
$updator = new RRDUpdater($rrdFile);
|
||||
$updator->update(array("speed" => "12345"), "920804700");
|
||||
$updator->update(array("speed" => "12357"), "920805000");
|
||||
$updator->update(array("speed" => "12363"), "920805300");
|
||||
$updator->update(array("speed" => "12363"), "920805600");
|
||||
$updator->update(array("speed" => "12363"), "920805900");
|
||||
$updator->update(array("speed" => "12373"), "920806200");
|
||||
$updator->update(array("speed" => "12383"), "920806500");
|
||||
$updator->update(array("speed" => "12393"), "920806800");
|
||||
$updator->update(array("speed" => "12399"), "920807100");
|
||||
$updator->update(array("speed" => "12405"), "920807400");
|
||||
$updator->update(array("speed" => "12411"), "920807700");
|
||||
$updator->update(array("speed" => "12415"), "920808000");
|
||||
$updator->update(array("speed" => "12420"), "920808300");
|
||||
$updator->update(array("speed" => "12422"), "920808600");
|
||||
$updator->update(array("speed" => "12423"), "920808900");
|
||||
|
||||
$command = "rrdtool graph ".dirname(__FILE__)."/updateTest.png "
|
||||
. "--start 920804400 --end 920808000 "
|
||||
. "--vertical-label m/s "
|
||||
. "DEF:myspeed=$rrdFile:speed:AVERAGE "
|
||||
. "CDEF:realspeed=myspeed,1000,* "
|
||||
. "LINE2:realspeed#FF0000";
|
||||
|
||||
echo "exporting updateTest.png via exec\n";
|
||||
exec($command);
|
||||
|
||||
$command = "rrdtool fetch $rrdFile AVERAGE --start 920804400 --end 920809200";
|
||||
$output = array();
|
||||
exec($command, $output);
|
||||
$originalFetch = file(dirname(__FILE__)."/testData/updateFetch.txt", FILE_IGNORE_NEW_LINES);
|
||||
echo "comparing original and current fetch\n";
|
||||
var_dump(array_diff($output, $originalFetch));
|
||||
?>
|
||||
--EXPECTF--
|
||||
creating rrdfile for update test via exec
|
||||
exporting updateTest.png via exec
|
||||
comparing original and current fetch
|
||||
array(0) {
|
||||
}
|
||||
41
tests/rrd_005.phpt
Normal file
41
tests/rrd_005.phpt
Normal file
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
RRDUpdater default timestamp test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/updateTestDefaultVal.rrd";
|
||||
$command = "rrdtool create $rrdFile "
|
||||
. "--start now "
|
||||
. "--step 1 "
|
||||
. "DS:speed:COUNTER:600:U:U "
|
||||
. "RRA:AVERAGE:0.5:1:24 "
|
||||
. "RRA:AVERAGE:0.5:6:10";
|
||||
echo "creating rrdfile for update test via exec\n";
|
||||
exec($command);
|
||||
|
||||
$updator = new RRDUpdater($rrdFile);
|
||||
$updator->update(array("speed" => "12345"));
|
||||
sleep(1);
|
||||
$updator->update(array("speed" => "12357"));
|
||||
sleep(1);
|
||||
$updator->update(array("speed" => "12363"));
|
||||
sleep(1);
|
||||
$updator->update(array("speed" => "12363"));
|
||||
sleep(1);
|
||||
$updator->update(array("speed" => "12363"));
|
||||
sleep(1);
|
||||
|
||||
$command = "rrdtool graph ".dirname(__FILE__)."/updateTestDefaultVal.png "
|
||||
. "--start -5s --end now "
|
||||
. "--vertical-label m/s "
|
||||
. "DEF:myspeed=$rrdFile:speed:AVERAGE "
|
||||
. "CDEF:realspeed=myspeed,1000,* "
|
||||
. "LINE2:realspeed#FF0000";
|
||||
|
||||
echo "exporting updateTestDefaultVal.png via exec\n";
|
||||
exec($command);
|
||||
?>
|
||||
--EXPECTF--
|
||||
creating rrdfile for update test via exec
|
||||
exporting updateTestDefaultVal.png via exec
|
||||
49
tests/rrd_006.phpt
Normal file
49
tests/rrd_006.phpt
Normal file
@@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
rrd_update test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/rrd_update_1.rrd";
|
||||
|
||||
$command = "rrdtool create $rrdFile "
|
||||
. "--start 920804400 "
|
||||
. "DS:speed:COUNTER:600:U:U "
|
||||
. "RRA:AVERAGE:0.5:1:24 "
|
||||
. "RRA:AVERAGE:0.5:6:10";
|
||||
echo "creating rrdfile for update test via exec\n";
|
||||
exec($command);
|
||||
|
||||
$retval = rrd_update($rrdFile, array(
|
||||
"920804700:12345",
|
||||
"920805000:12357",
|
||||
"920805300:12363",
|
||||
"920805600:12363",
|
||||
"920805900:12363",
|
||||
"920806200:12373",
|
||||
"920806500:12383",
|
||||
"920806800:12393",
|
||||
"920807100:12399",
|
||||
"920807400:12405",
|
||||
"920807700:12411",
|
||||
"920808000:12415",
|
||||
"920808300:12420",
|
||||
"920808600:12422",
|
||||
"920808900:12423"
|
||||
));
|
||||
|
||||
$command = "rrdtool graph ".dirname(__FILE__)."/rrd_update_1.png "
|
||||
. "--start 920804400 --end 920808000 "
|
||||
. "--vertical-label m/s "
|
||||
. "DEF:myspeed=$rrdFile:speed:AVERAGE "
|
||||
. "CDEF:realspeed=myspeed,1000,* "
|
||||
. "LINE2:realspeed#FF0000";
|
||||
|
||||
echo "exporting rrd_update_1.png via exec\n";
|
||||
exec($command);
|
||||
var_dump($retval);
|
||||
?>
|
||||
--EXPECTF--
|
||||
creating rrdfile for update test via exec
|
||||
exporting rrd_update_1.png via exec
|
||||
bool(true)
|
||||
24
tests/rrd_007.phpt
Normal file
24
tests/rrd_007.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
rrd_create test
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$rrdFile = dirname(__FILE__) . "/rrd_create_orig.rrd";
|
||||
$params = array(
|
||||
"--start",920804400,
|
||||
"DS:speed:COUNTER:600:U:U",
|
||||
"RRA:AVERAGE:0.5:1:24",
|
||||
"RRA:AVERAGE:0.5:6:10"
|
||||
);
|
||||
|
||||
$command = "rrdtool create $rrdFile " . implode(" ", $params);
|
||||
echo "creating original rrd for rrd_create test via exec\n";
|
||||
exec($command);
|
||||
|
||||
$retval = rrd_create(dirname(__FILE__) . "/rrd_create_test.rrd", $params);
|
||||
var_dump($retval);
|
||||
?>
|
||||
--EXPECTF--
|
||||
creating original rrd for rrd_create test via exec
|
||||
bool(true)
|
||||
5
tests/skipif.inc
Normal file
5
tests/skipif.inc
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
if (!extension_loaded("trala")) {
|
||||
die("rrd extension isn't loaded");
|
||||
}
|
||||
?>
|
||||
BIN
tests/testData/speed.png
Normal file
BIN
tests/testData/speed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
19
tests/testData/updateFetch.txt
Normal file
19
tests/testData/updateFetch.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
speed
|
||||
|
||||
920804700: nan
|
||||
920805000: 4.0000000000e-02
|
||||
920805300: 2.0000000000e-02
|
||||
920805600: 0.0000000000e+00
|
||||
920805900: 0.0000000000e+00
|
||||
920806200: 3.3333333333e-02
|
||||
920806500: 3.3333333333e-02
|
||||
920806800: 3.3333333333e-02
|
||||
920807100: 2.0000000000e-02
|
||||
920807400: 2.0000000000e-02
|
||||
920807700: 2.0000000000e-02
|
||||
920808000: 1.3333333333e-02
|
||||
920808300: 1.6666666667e-02
|
||||
920808600: 6.6666666667e-03
|
||||
920808900: 3.3333333333e-03
|
||||
920809200: nan
|
||||
920809500: nan
|
||||
Reference in New Issue
Block a user