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:
Miroslav Kubelik
2010-06-23 08:38:41 +00:00
commit 7d8a301b56
19 changed files with 1589 additions and 0 deletions

87
config.m4 Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,5 @@
<?php
if (!extension_loaded("trala")) {
die("rrd extension isn't loaded");
}
?>

BIN
tests/testData/speed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View 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