Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into bugfix/2573_RPC_er…
Browse files Browse the repository at this point in the history
…ror_fix
  • Loading branch information
davidnich committed Dec 30, 2017
2 parents 5bb3379 + 61e167b commit 9ce7d58
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .jenkins.prop
@@ -1 +1 @@
QORE_BRANCH_NAME=0.8.13
QORE_BRANCH_NAME=develop
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.3)
project(qore-yaml-module)

set (VERSION_MAJOR 0)
set (VERSION_MINOR 5)
set (VERSION_MINOR 7)
set (VERSION_PATCH 0)

# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
@@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script.

# AC_PREREQ(2.59)
AC_INIT([qore-yaml-module], [0.6],
AC_INIT([qore-yaml-module], [0.7],
[David Nichols <david@qore.org>],
[qore-yaml-module])
AM_INIT_AUTOMAKE([no-dist-gzip dist-bzip2 tar-ustar])
Expand Down
6 changes: 5 additions & 1 deletion docs/mainpage.doxygen.tmpl
Expand Up @@ -80,12 +80,16 @@ any data = parse_yaml(yaml_str);
|date (relative)|\c !duration|\c P2M3DT10H14u|\c P2M3DT10H14u|Relative date/time values (durations) are serialized with Qore's <a href="http://en.wikipedia.org/wiki/ISO_8601#Durations">ISO-8601</a>-based format.<br><br>This tag is a custom tag used only by Qore to serialize Qore relative date/time values with YAML
|date (absolute)|\c !!timestamp|\c 2010-05-05T15:35:02.100|\c 2010-05-05T15:35:02.1+02:00|Absolute date/time values are serialized with YAML's <a href="http://yaml.org/type/timestamp.html">timestamp</a> format.<br><br>Note that qore date/time values without an explicit time zone are assumed to be in the local time zone.<br><br>When converting a YAML timestamp to a Qore date, because Qore supports only up to microsecond resolution in date/time values, any digits after microseconds are lost.
|NOTHING|\c !!null|\c NOTHING|\c null|direct serialization
|NULL|\c !!null|\c NULL|\c null|serialization to YAML null, just like \c NOTHING; will be deserialized as \c NOTHING.
|NULL|\c !!null or \c !sqlnull|\c NULL|\c null or \c !sqlnull|without @ref @ref Qore::YAML::EmitSqlNull "EmitSqlNull", serialization to YAML null, just like \c NOTHING; will be deserialized as \c NOTHING, with @ref Qore::YAML::EmitSqlNull "EmitSqlNull" will be deserialized to \c NULL.
|list|\c !!seq|\c (1, 2, "three")|\c [1, 2, "three"]|direct serialization
|hash|\c !!map|\c ("key" : 1, "other" : 2.0, "data" : "three")|\c {key: 1, other: 2.0, data: "three"}|direct serialization, although qore will maintain key order as well even though this property is only defined for an ordered map

@section yamlreleasenotes Release Notes

@subsection yaml07 yaml Module Version 0.7

- added optional support for serializing SQL NULL values with @ref Qore::YAML::EmitSqlNull "EmitSqlNull"

@subsection yaml06 yaml Module Version 0.6

- improved the description for the \c DESERIALIZATION-ERROR exception for non-deserializable message bodies from HTTP servers with error responses (<a href="https://github.com/qorelanguage/qore/issues/1033">issue 1033</a>)
Expand Down
5 changes: 4 additions & 1 deletion qore-yaml-module.spec
@@ -1,4 +1,4 @@
%global mod_ver 0.6
%global mod_ver 0.7

%{?_datarootdir: %global mydatarootdir %_datarootdir}
%{!?_datarootdir: %global mydatarootdir /usr/share}
Expand Down Expand Up @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_ROOT
%doc COPYING.LGPL COPYING.MIT README RELEASE-NOTES AUTHORS

%changelog
* Sat Oct 21 2017 David Nichols <david@qore.org> 0.7
- updated to version 0.7

* Wed Nov 23 2016 David Nichols <david@qore.org> 0.6
- updated to version 0.6

Expand Down
7 changes: 6 additions & 1 deletion src/QoreYamlEmitter.cpp
Expand Up @@ -2,7 +2,7 @@
/*
yaml Qore module
Copyright (C) 2010 - 2013 David Nichols, all rights reserved
Copyright (C) 2010 - 2017 Qore Technologies, s.r.o.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -31,6 +31,7 @@ QoreYamlEmitter::QoreYamlEmitter(QoreYamlWriteHandler &n_wh, int flags, int widt
: QoreYamlBase(n_xsink), wh(n_wh), block(flags & QYE_BLOCK_STYLE),
implicit_start_doc(!(flags & QYE_EXPLICIT_START_DOC)),
implicit_end_doc(!(flags & QYE_EXPLICIT_END_DOC)),
emit_sqlnull(flags & QYE_EMIT_SQLNULL),
yaml_ver(0) {
if (!yaml_emitter_initialize(&emitter)) {
err("unknown error initializing yaml emitter");
Expand Down Expand Up @@ -95,6 +96,10 @@ int QoreYamlEmitter::emit(const QoreValue& v) {
return emitValue(*v.get<const BinaryNode>());

case NT_NULL:
if (emit_sqlnull)
return emitSqlNull();
// fall down to nothing

case NT_NOTHING:
return emitNull();

Expand Down
17 changes: 12 additions & 5 deletions src/QoreYamlParser.cpp
Expand Up @@ -2,7 +2,7 @@
/*
yaml Qore module
Copyright (C) 2010 - 2016 David Nichols, all rights reserved
Copyright (C) 2010 - 2017 Qore Technologies, s.r.o.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -344,13 +344,17 @@ AbstractQoreNode* QoreYamlParser::parseScalar(bool favor_string) {

// check for null
if (!strcmp(val, "null") || !strcmp(val, "~") || !len)
return 0;
return nullptr;

// check for sqlnull
if (!strcmp(val, "sqlnull"))
return &Null;

// check for absolute date/time values
if (len > 9 && isdigit(val[0]) && isdigit(val[1]) && isdigit(val[2]) && isdigit(val[3]) && val[4] == '-'
&& isdigit(val[5]) && isdigit(val[6]) && val[7] == '-'
&& isdigit(val[8]) && isdigit(val[9]))
return parseAbsoluteDate();
return parseAbsoluteDate();

// check for relative date/time values (durations)
if (*val == 'P') {
Expand All @@ -376,14 +380,15 @@ AbstractQoreNode* QoreYamlParser::parseScalar(bool favor_string) {
}

const char* tag = (const char*)event.data.scalar.tag;
// FIXME: use a map here for O(ln(n)) performance
if (!strcmp(tag, YAML_TIMESTAMP_TAG))
return parseAbsoluteDate();
if (!strcmp(tag, YAML_BINARY_TAG))
return parseBase64(val, len, xsink);
if (!strcmp(tag, YAML_STR_TAG))
return new QoreStringNode(val, len, QCS_UTF8);
if (!strcmp(tag, YAML_NULL_TAG))
return 0;
return nullptr;
if (!strcmp(tag, YAML_BOOL_TAG))
return parseBool();
if (!strcmp(tag, YAML_INT_TAG))
Expand All @@ -394,10 +399,12 @@ AbstractQoreNode* QoreYamlParser::parseScalar(bool favor_string) {
return new DateTimeNode(val);
if (!strcmp(tag, QORE_YAML_NUMBER_TAG))
return parseNumber(val, len);
if (!strcmp(tag, QORE_YAML_SQLNULL_TAG))
return &Null;

xsink->raiseException(QY_PARSE_ERR, "don't know how to parse scalar tag '%s'", tag);

return 0;
return nullptr;
}

QoreBoolNode* QoreYamlParser::parseBool() {
Expand Down
5 changes: 4 additions & 1 deletion src/ql_yaml.qpp
Expand Up @@ -4,7 +4,7 @@
yaml Qore module
Copyright (C) 2010 - 2012 David Nichols
Copyright (C) 2010 - 2017 Qore Technologies, s.r.o.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -74,6 +74,9 @@ const ExplicitEndDoc = QYE_EXPLICIT_END_DOC;
//! emitter constant: emit seq and map with block style
const BlockStyle = QYE_BLOCK_STYLE;

//! emitter constant: emit SQL null \c "!!sqlnull"
const EmitSqlNull = QYE_EMIT_SQLNULL;

//const Yaml1_0 = QYE_VER_1_0;

//! emitter constant: emit YAML 1.1 (not necessary to use as this is the default and currently the only YAML version supported by libyaml)
Expand Down
4 changes: 3 additions & 1 deletion src/yaml-module.cpp
Expand Up @@ -2,7 +2,7 @@
/*
yaml Qore module
Copyright (C) 2010 - 2016 David Nichols, all rights reserved
Copyright (C) 2010 - 2017 Qore Technologies, s.r.o.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -44,9 +44,11 @@ DLLEXPORT qore_license_t qore_module_license = QL_LGPL;
DLLEXPORT char qore_module_license_str[] = "MIT";

QoreString NullStr("null");
QoreString SqlNullStr("sqlnull");

const char* QORE_YAML_DURATION_TAG = "!duration";
const char* QORE_YAML_NUMBER_TAG = "!number";
const char* QORE_YAML_SQLNULL_TAG = "!sqlnull";

yaml_version_directive_t yaml_ver_1_0 = {1, 0}, yaml_ver_1_1 = {1, 1}, yaml_ver_1_2 = {1, 2};

Expand Down
16 changes: 12 additions & 4 deletions src/yaml-module.h
Expand Up @@ -4,7 +4,7 @@
Qore Programming Language
Copyright 2003 - 2016 David Nichols
Copyright 2003 - 2017 Qore Technologies, s.r.o.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -45,6 +45,7 @@
#define QYE_VER_1_0 (1 << 5)
#define QYE_VER_1_1 (1 << 6)
#define QYE_VER_1_2 (1 << 7)
#define QYE_EMIT_SQLNULL (1 << 8)

#define QYE_DEFAULT (QYE_NONE)

Expand All @@ -58,12 +59,14 @@

DLLLOCAL extern const char* QORE_YAML_DURATION_TAG;
DLLLOCAL extern const char* QORE_YAML_NUMBER_TAG;
DLLLOCAL extern const char* QORE_YAML_SQLNULL_TAG;

DLLLOCAL extern const char *QY_EMIT_ERR;

DLLLOCAL extern const char *QY_PARSE_ERR;

DLLLOCAL extern QoreString NullStr;
DLLLOCAL extern QoreString SqlNullStr;

DLLLOCAL extern yaml_version_directive_t yaml_ver_1_0, yaml_ver_1_1, yaml_ver_1_2;

Expand Down Expand Up @@ -100,7 +103,8 @@ class QoreYamlEmitter : public QoreYamlBase {

bool block,
implicit_start_doc,
implicit_end_doc;
implicit_end_doc,
emit_sqlnull;

yaml_version_directive_t *yaml_ver;

Expand Down Expand Up @@ -214,8 +218,8 @@ class QoreYamlEmitter : public QoreYamlBase {
if (*xsink)
return -1;

if (!yaml_scalar_event_initialize(&event, (yaml_char_t *)anchor, (yaml_char_t *)tag,
(yaml_char_t *)str->c_str(), str->strlen(),
if (!yaml_scalar_event_initialize(&event, (yaml_char_t*)anchor, (yaml_char_t *)tag,
(yaml_char_t*)str->c_str(), str->strlen(),
plain_implicit, quoted_implicit, style))
return err("unknown error initializing yaml scalar output event for yaml type '%s', value '%s'", tag, value.getBuffer());

Expand Down Expand Up @@ -327,6 +331,10 @@ class QoreYamlEmitter : public QoreYamlBase {
return emitScalar(NullStr, YAML_NULL_TAG);
}

DLLLOCAL int emitSqlNull() {
return emitScalar(SqlNullStr, QORE_YAML_SQLNULL_TAG);
}

DLLLOCAL void setCanonical(bool b = true) {
yaml_emitter_set_canonical(&emitter, b);
}
Expand Down
19 changes: 19 additions & 0 deletions test/yaml.qtest
Expand Up @@ -67,6 +67,7 @@ public class Main inherits QUnit::Test {
addTestCase("Date/Time test", \testDates());
addTestCase("Structure with NaN test", \testNanStructure());
addTestCase("single quoted strings", \testSingleQuotedStrings());
addTestCase("sql null test", \sqlNull());

# Return for compatibility with test harness that checks return value.
set_return_value(main());
Expand Down Expand Up @@ -128,4 +129,22 @@ public class Main inherits QUnit::Test {
assertEq(500n, parse_yaml("'5e+02n{128}'"));
assertEq(2017-10-26T09:37:36.119613+02:00, parse_yaml("'2017-10-26 09:37:36.119613 +02:00'"));
}

sqlNull() {
string yaml = make_yaml(NULL, EmitSqlNull);
assertRegex("^sqlnull", yaml);
assertEq(NULL, parse_yaml(yaml));
yaml = make_yaml("sqlnull");
assertRegex("sqlnull", yaml);
assertEq("sqlnull", parse_yaml(yaml));
yaml = make_yaml("sqlnull", EmitSqlNull);
assertRegex("sqlnull", yaml);
assertEq("sqlnull", parse_yaml(yaml));
yaml = make_yaml(NULL);
assertRegex("^null", yaml);
assertEq(NOTHING, parse_yaml(yaml));
list d = DATA + "NULL";
yaml = make_yaml(d, EmitSqlNull);
assertEq(d, parse_yaml(yaml));
}
}

0 comments on commit 9ce7d58

Please sign in to comment.