Browse Source

Feat: setType in reader

viest 5 years ago
parent
commit
9199a33b9c

+ 1 - 0
include/excel.h

@@ -17,6 +17,7 @@
 #define V_XLS_FIL    "fileName"
 #define V_XLS_COF    "config"
 #define V_XLS_PAT    "path"
+#define V_XLS_TYPE   "read_row_type"
 
 #define V_XLS_CONST_READ_TYPE_INT      "TYPE_INT"
 #define V_XLS_CONST_READ_TYPE_DOUBLE   "TYPE_DOUBLE"

+ 2 - 1
include/read.h

@@ -17,8 +17,9 @@
 #define READ_ROW 0x01
 
 int sheet_read_row(xlsxioreadersheet sheet_t);
+int is_number(char *value);
 xlsxioreader file_open(const char *directory, const char *file_name);
-void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t);
+void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_type_t, zval *zv_result_t);
 xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_name_t, const zend_long zl_flag);
 unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_result_t, zval *zv_type, unsigned int flag);
 unsigned int load_sheet_current_row_data_callback(zend_string *zs_sheet_name_t, xlsxioreader file_t, void *callback_data);

+ 37 - 3
kernel/excel.c

@@ -163,6 +163,10 @@ ZEND_BEGIN_ARG_INFO_EX(xls_open_sheet_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, zs_sheet_name)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(xls_set_type_arginfo, 0, 0, 1)
+                ZEND_ARG_INFO(0, zv_type_t)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(xls_next_cell_callback_arginfo, 0, 0, 2)
                 ZEND_ARG_INFO(0, fci)
                 ZEND_ARG_INFO(0, sheet_name)
@@ -754,6 +758,22 @@ PHP_METHOD(vtiful_xls, openSheet)
 }
 /* }}} */
 
+/** {{{ \Vtiful\Kernel\xls::setType(array $rowType)
+ */
+PHP_METHOD(vtiful_xls, setType)
+{
+    zval *zv_type_t = NULL;
+
+    ZEND_PARSE_PARAMETERS_START(1, 1)
+            Z_PARAM_ARRAY(zv_type_t)
+    ZEND_PARSE_PARAMETERS_END();
+
+    ZVAL_COPY(return_value, getThis());
+
+    add_property_zval_ex(getThis(), ZEND_STRL(V_XLS_TYPE), zv_type_t);
+}
+/* }}} */
+
 /** {{{ \Vtiful\Kernel\xls::getSheetData()
  */
 PHP_METHOD(vtiful_xls, getSheetData)
@@ -764,7 +784,15 @@ PHP_METHOD(vtiful_xls, getSheetData)
         RETURN_FALSE;
     }
 
-    load_sheet_all_data(obj->read_ptr.sheet_t, return_value);
+    zval *zv_type = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
+
+    if (zv_type != NULL && Z_TYPE_P(zv_type) == IS_ARRAY) {
+        load_sheet_all_data(obj->read_ptr.sheet_t, zv_type, return_value);
+
+        return;
+    }
+
+    load_sheet_all_data(obj->read_ptr.sheet_t, NULL, return_value);
 }
 /* }}} */
 
@@ -785,6 +813,10 @@ PHP_METHOD(vtiful_xls, nextRow)
         RETURN_FALSE;
     }
 
+    if (zv_type == NULL) {
+        zv_type = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
+    }
+
     load_sheet_current_row_data(obj->read_ptr.sheet_t, return_value, zv_type, READ_ROW);
 }
 /* }}} */
@@ -846,6 +878,7 @@ zend_function_entry xls_methods[] = {
 #ifdef ENABLE_READER
         PHP_ME(vtiful_xls, openFile,         xls_open_file_arginfo,          ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, openSheet,        xls_open_sheet_arginfo,         ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, setType,          xls_set_type_arginfo,           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, getSheetData,     NULL,                           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, nextRow,          NULL,                           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, nextCellCallback, xls_next_cell_callback_arginfo, ZEND_ACC_PUBLIC)
@@ -868,8 +901,9 @@ VTIFUL_STARTUP_FUNCTION(excel) {
     vtiful_xls_handlers.offset   = XtOffsetOf(xls_object, zo);
     vtiful_xls_handlers.free_obj = vtiful_xls_objects_free;
 
-    REGISTER_CLASS_PROPERTY_NULL(vtiful_xls_ce, V_XLS_COF, ZEND_ACC_PRIVATE);
-    REGISTER_CLASS_PROPERTY_NULL(vtiful_xls_ce, V_XLS_FIL, ZEND_ACC_PRIVATE);
+    REGISTER_CLASS_PROPERTY_NULL(vtiful_xls_ce, V_XLS_COF,  ZEND_ACC_PRIVATE);
+    REGISTER_CLASS_PROPERTY_NULL(vtiful_xls_ce, V_XLS_FIL,  ZEND_ACC_PRIVATE);
+    REGISTER_CLASS_PROPERTY_NULL(vtiful_xls_ce, V_XLS_TYPE, ZEND_ACC_PRIVATE);
 
 #ifdef ENABLE_READER
     REGISTER_CLASS_CONST_LONG(vtiful_xls_ce, V_XLS_CONST_READ_SKIP_NONE,        XLSXIOREAD_SKIP_NONE);

+ 28 - 3
kernel/read.c

@@ -41,6 +41,17 @@ xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_na
 }
 /* }}} */
 
+/* {{{ */
+int is_number(char *value)
+{
+    if (strspn(value, ".0123456789") == strlen(value)) {
+        return XLSWRITER_TRUE;
+    }
+
+    return XLSWRITER_FALSE;
+}
+/* }}} */
+
 /* {{{ */
 int sheet_read_row(xlsxioreadersheet sheet_t)
 {
@@ -83,22 +94,34 @@ unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_res
         }
 
         if (_type & READ_TYPE_DATETIME) {
+            if (!is_number(_string_value)) {
+                goto STRING;
+            }
+
             double value = strtod(_string_value, NULL);
 
             if (value != 0) {
                 value = (value - 25569) * 86400;
             }
 
-            add_next_index_double(zv_result_t, value);
+            add_next_index_long(zv_result_t, (zend_long)(value + 0.5));
             continue;
         }
 
         if (_type & READ_TYPE_DOUBLE) {
+            if (!is_number(_string_value)) {
+                goto STRING;
+            }
+
             add_next_index_double(zv_result_t, strtod(_string_value, NULL));
             continue;
         }
 
         if (_type & READ_TYPE_INT) {
+            if (!is_number(_string_value)) {
+                goto STRING;
+            }
+
             zend_long _long_value;
 
             sscanf(_string_value, "%" PRIi64, &_long_value);
@@ -106,6 +129,8 @@ unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_res
             continue;
         }
 
+        STRING:
+
         add_next_index_stringl(zv_result_t, _string_value, strlen(_string_value));
     }
 
@@ -185,7 +210,7 @@ unsigned int load_sheet_current_row_data_callback(zend_string *zs_sheet_name_t,
 /* }}} */
 
 /* {{{ */
-void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t)
+void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_type_t, zval *zv_result_t)
 {
     if (Z_TYPE_P(zv_result_t) != IS_ARRAY) {
         array_init(zv_result_t);
@@ -196,7 +221,7 @@ void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t)
         zval _zv_tmp_row;
         ZVAL_NULL(&_zv_tmp_row);
 
-        load_sheet_current_row_data(sheet_t, &_zv_tmp_row, NULL, READ_SKIP_ROW);
+        load_sheet_current_row_data(sheet_t, &_zv_tmp_row, zv_type_t, READ_SKIP_ROW);
         add_next_index_zval(zv_result_t, &_zv_tmp_row);
     }
 }

+ 3 - 1
tests/002.phpt

@@ -9,7 +9,7 @@ $excel = new \Vtiful\Kernel\Excel($config);
 var_dump($excel);
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -17,5 +17,7 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   NULL
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }
 

+ 3 - 1
tests/003.phpt

@@ -10,7 +10,7 @@ $fileFd = $excel->fileName('tutorial01.xlsx');
 var_dump($fileFd);
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -18,4 +18,6 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   string(23) "./tests/tutorial01.xlsx"
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }

+ 3 - 1
tests/004.phpt

@@ -11,7 +11,7 @@ $setHeader = $fileFd->header(['Item', 'Cost']);
 var_dump($setHeader);
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -19,4 +19,6 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   string(23) "./tests/tutorial01.xlsx"
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }

+ 3 - 1
tests/open_xlsx_file.phpt

@@ -22,7 +22,7 @@ var_dump($data);
 @unlink(__DIR__ . '/tutorial.xlsx');
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -30,4 +30,6 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   string(21) "./tests/tutorial.xlsx"
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }

+ 55 - 0
tests/open_xlsx_get_data_with_set_type.phpt

@@ -0,0 +1,55 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php
+require __DIR__ . '/include/skipif.inc';
+skip_disable_reader();
+?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx')
+    ->header(['Name', 'Age', 'Date'])
+    ->data([
+        ['Viest', 24]
+    ])
+    ->insertDate(1, 2, 1568877706)
+    ->output();
+
+$data = $excel->openFile('tutorial.xlsx')
+    ->openSheet()
+    ->setType([
+        \Vtiful\Kernel\Excel::TYPE_STRING,
+        \Vtiful\Kernel\Excel::TYPE_STRING,
+        \Vtiful\Kernel\Excel::TYPE_TIMESTAMP,
+    ])
+    ->getSheetData();
+
+var_dump($data);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  array(3) {
+    [0]=>
+    string(4) "Name"
+    [1]=>
+    string(3) "Age"
+    [2]=>
+    string(4) "Date"
+  }
+  [1]=>
+  array(3) {
+    [0]=>
+    string(5) "Viest"
+    [1]=>
+    string(2) "24"
+    [2]=>
+    int(1568877706)
+  }
+}

+ 1 - 1
tests/open_xlsx_next_row_with_data_type_date.phpt

@@ -40,7 +40,7 @@ array(1) {
 }
 array(1) {
   [0]=>
-  float(1568389354)
+  int(1568389354)
 }
 NULL
 NULL

+ 1 - 1
tests/open_xlsx_next_row_with_data_type_date_array_index.phpt

@@ -52,5 +52,5 @@ array(5) {
   [3]=>
   string(0) ""
   [4]=>
-  float(1568818881)
+  int(1568818881)
 }

+ 48 - 0
tests/open_xlsx_next_row_with_set_type.phpt

@@ -0,0 +1,48 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php
+require __DIR__ . '/include/skipif.inc';
+skip_disable_reader();
+?>
+--FILE--
+<?php
+$config = ['path' => './tests'];
+
+$fileObject = new \Vtiful\Kernel\Excel($config);
+$fileObject = $fileObject->fileName('tutorial.xlsx');
+
+$filePath = $fileObject->data([
+        [1, 'Test']
+    ])
+    ->insertDate(1, 2, 1568389354, 'mmm d yyyy hh:mm AM/PM')
+    ->output();
+
+$fileObject->openFile('tutorial.xlsx')
+    ->openSheet()
+    ->setType([
+        \Vtiful\Kernel\Excel::TYPE_INT,
+        \Vtiful\Kernel\Excel::TYPE_STRING,
+        \Vtiful\Kernel\Excel::TYPE_TIMESTAMP,
+    ]);
+
+var_dump($fileObject->nextRow()); // Header
+var_dump($fileObject->nextRow());
+var_dump($fileObject->nextRow());
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+array(0) {
+}
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  string(4) "Test"
+  [2]=>
+  int(1568389354)
+}
+NULL

+ 3 - 1
tests/open_xlsx_sheet.phpt

@@ -22,7 +22,7 @@ var_dump($data);
 @unlink(__DIR__ . '/tutorial.xlsx');
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -30,4 +30,6 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   string(21) "./tests/tutorial.xlsx"
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }

+ 3 - 1
tests/open_xlsx_sheet_flag.phpt

@@ -22,7 +22,7 @@ var_dump($data);
 @unlink(__DIR__ . '/tutorial.xlsx');
 ?>
 --EXPECT--
-object(Vtiful\Kernel\Excel)#1 (2) {
+object(Vtiful\Kernel\Excel)#1 (3) {
   ["config":"Vtiful\Kernel\Excel":private]=>
   array(1) {
     ["path"]=>
@@ -30,4 +30,6 @@ object(Vtiful\Kernel\Excel)#1 (2) {
   }
   ["fileName":"Vtiful\Kernel\Excel":private]=>
   string(21) "./tests/tutorial.xlsx"
+  ["read_row_type":"Vtiful\Kernel\Excel":private]=>
+  NULL
 }