Skip to content

Commit

Permalink
Added output configuration option newline_char for the end of line …
Browse files Browse the repository at this point in the history
…style and `indentation_char` for the identation style.
  • Loading branch information
doberkofler committed Mar 9, 2020
1 parent 056d377 commit c6b476c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 43 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Fixed


## [0.7.0] - 2020-03-09

### Changed
- Added output configuration option `newline_char` for the end of line style and `indentation_char` for the identation style.


## [0.6.0] - 2020-03-09

### Changed
- Added api `get_default_options`, `get_options` and `set_options` to `json_utils`package to configure (`Pretty`, `AsciiOutput` and `EscapeSolitus`) the output.
- Added api `get_default_options`, `get_options` and `set_options` to `json_utils`package to configure (`Pretty`, `ascii_output` and `escape_solitus`) the output.
- Added support for formatted (pretty) json output with the option `Pretty`.


Expand Down
34 changes: 19 additions & 15 deletions json_utils.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ IS

outputOptions OutputOptionsType;

NEW_LINE CONSTANT VARCHAR2(2) := '
';
INDENTATION_CHARACTER CONSTANT VARCHAR2(1) := ' ';

PROCEDURE copySubNodes(theTarget IN OUT NOCOPY jsonNodes, theFirstID IN OUT NOCOPY BINARY_INTEGER, theParentID IN BINARY_INTEGER, theSource IN jsonNodes, theFirstSourceID IN BINARY_INTEGER);
FUNCTION boolean_to_json(theBoolean IN NUMBER) RETURN VARCHAR2;
FUNCTION number_to_json(theNumber IN NUMBER) RETURN VARCHAR2;
Expand Down Expand Up @@ -39,6 +35,14 @@ END get_options;
PROCEDURE set_options(theOptions IN outputOptionsType)
IS
BEGIN
IF (theOptions.newline_char NOT IN (EOL_LF, EOL_CR, EOL_CRLF)) THEN
raise_application_error(-20100, 'Invalid newline style. Use EOL constant', TRUE);
END IF;

IF (theOptions.indentation_char NOT IN (IND_TAB, IND_SPACE_1, IND_SPACE_2, IND_SPACE_3, IND_SPACE_4)) THEN
raise_application_error(-20100, 'Invalid indentation style. Use IND constant', TRUE);
END IF;

outputOptions := theOptions;
END set_options;

Expand Down Expand Up @@ -540,7 +544,7 @@ BEGIN
-- Add the property name
IF (aNode.nam IS NOT NULL) THEN
PRAGMA INLINE (escape, 'YES');
aName := GAP || '"' || escape(theString=>aNode.nam, theAsciiOutput=>outputOptions.AsciiOutput, theEscapeSolitus=>outputOptions.EscapeSolitus) || '":';
aName := GAP || '"' || escape(theString=>aNode.nam, theAsciiOutput=>outputOptions.ascii_output, theEscapeSolitus=>outputOptions.escape_solitus) || '":';
IF (outputOptions.Pretty) THEN
aName := aName || ' ';
END IF;
Expand All @@ -558,13 +562,13 @@ BEGIN

WHEN json_utils.NODE_TYPE_STRING THEN
PRAGMA INLINE (escape, 'YES');
json_utils.add_string(theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theValue=>GAP || '"' || escape(theString=>aNode.str, theAsciiOutput=>outputOptions.AsciiOutput, theEscapeSolitus=>outputOptions.EscapeSolitus) || '"');
json_utils.add_string(theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theValue=>GAP || '"' || escape(theString=>aNode.str, theAsciiOutput=>outputOptions.ascii_output, theEscapeSolitus=>outputOptions.escape_solitus) || '"');

WHEN json_utils.NODE_TYPE_LOB THEN
PRAGMA INLINE (add_string, 'YES');
json_utils.add_string(theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theValue=>GAP || '"');
PRAGMA INLINE (escapeLOB, 'YES');
escapeLOB(theInputLob=>aNode.lob, theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theAsciiOutput=>outputOptions.AsciiOutput, theEscapeSolitus=>outputOptions.EscapeSolitus);
escapeLOB(theInputLob=>aNode.lob, theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theAsciiOutput=>outputOptions.ascii_output, theEscapeSolitus=>outputOptions.escape_solitus);
PRAGMA INLINE (add_string, 'YES');
json_utils.add_string(theLobBuf=>theLobBuf, theStrBuf=>theStrBuf, theValue=>'"');

Expand Down Expand Up @@ -604,16 +608,16 @@ IS
BEGIN
-- open bracket {
IF (outputOptions.Pretty) THEN
aBracket := '{' || NEW_LINE;
aBracket := '{' || outputOptions.newline_char;
ELSE
aBracket := '{';
END IF;
PRAGMA INLINE (add_string, 'YES');
json_utils.add_string(theLobBuf, theStrBuf, aBracket);

-- compute the delimiter
IF (outputOptions.Pretty) THEN
aDelimiter := ',' || NEW_LINE;
aDelimiter := ',' || outputOptions.newline_char;
ELSE
aDelimiter := ',';
END IF;
Expand All @@ -637,7 +641,7 @@ BEGIN

-- close bracket }
IF (outputOptions.Pretty) THEN
aBracket := NEW_LINE || GAP || '}';
aBracket := outputOptions.newline_char || GAP || '}';
ELSE
aBracket := GAP || '}';
END IF;
Expand All @@ -664,7 +668,7 @@ IS
BEGIN
-- open bracket {
IF (outputOptions.Pretty) THEN
aBracket := '[' || NEW_LINE;
aBracket := '[' || outputOptions.newline_char;
ELSE
aBracket := '[';
END IF;
Expand All @@ -673,7 +677,7 @@ BEGIN

-- compute the delimiter
IF (outputOptions.Pretty) THEN
aDelimiter := ',' || NEW_LINE;
aDelimiter := ',' || outputOptions.newline_char;
ELSE
aDelimiter := ',';
END IF;
Expand All @@ -697,7 +701,7 @@ BEGIN

-- close bracket }
IF (outputOptions.Pretty) THEN
aBracket := NEW_LINE || GAP || ']';
aBracket := outputOptions.newline_char || GAP || ']';
ELSE
aBracket := GAP || ']';
END IF;
Expand Down Expand Up @@ -777,7 +781,7 @@ FUNCTION get_gap(theIndentation IN INTEGER) RETURN VARCHAR2
IS
BEGIN
IF (outputOptions.Pretty) THEN
RETURN RPAD(INDENTATION_CHARACTER, theIndentation, INDENTATION_CHARACTER);
RETURN RPAD(outputOptions.indentation_char, theIndentation, outputOptions.indentation_char);
ELSE
RETURN '';
END IF;
Expand Down
36 changes: 25 additions & 11 deletions json_utils.pks
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,37 @@ CREATE OR REPLACE
PACKAGE json_utils
IS

-- indentation styles
IND_TAB CONSTANT VARCHAR2(1 CHAR) := CHR(9);
IND_SPACE_1 CONSTANT VARCHAR2(1 CHAR) := ' ';
IND_SPACE_2 CONSTANT VARCHAR2(2 CHAR) := ' ';
IND_SPACE_3 CONSTANT VARCHAR2(3 CHAR) := ' ';
IND_SPACE_4 CONSTANT VARCHAR2(4 CHAR) := ' ';

-- end of line styles
EOL_LF CONSTANT VARCHAR2(1 CHAR) := CHR(10); -- macos
EOL_CR CONSTANT VARCHAR2(1 CHAR) := CHR(13); -- linux
EOL_CRLF CONSTANT VARCHAR2(2 CHAR) := EOL_CR || EOL_LF; -- windows

-- output options
TYPE outputOptionsType IS RECORD
(
Pretty BOOLEAN DEFAULT FALSE,
AsciiOutput BOOLEAN DEFAULT TRUE,
EscapeSolitus BOOLEAN DEFAULT FALSE
pretty BOOLEAN DEFAULT FALSE,
newline_char VARCHAR2(2 CHAR) DEFAULT EOL_CRLF,
indentation_char VARCHAR2(4 CHAR) DEFAULT IND_TAB,
ascii_output BOOLEAN DEFAULT TRUE,
escape_solitus BOOLEAN DEFAULT FALSE
);

-- node types
NODE_TYPE_NULL CONSTANT VARCHAR2(1) := '0';
NODE_TYPE_STRING CONSTANT VARCHAR2(1) := 'S';
NODE_TYPE_LOB CONSTANT VARCHAR2(1) := 'L';
NODE_TYPE_NUMBER CONSTANT VARCHAR2(1) := 'N';
NODE_TYPE_DATE CONSTANT VARCHAR2(1) := 'D';
NODE_TYPE_BOOLEAN CONSTANT VARCHAR2(1) := 'B';
NODE_TYPE_OBJECT CONSTANT VARCHAR2(1) := 'O';
NODE_TYPE_ARRAY CONSTANT VARCHAR2(1) := 'A';
NODE_TYPE_NULL CONSTANT VARCHAR2(1 CHAR) := '0';
NODE_TYPE_STRING CONSTANT VARCHAR2(1 CHAR) := 'S';
NODE_TYPE_LOB CONSTANT VARCHAR2(1 CHAR) := 'L';
NODE_TYPE_NUMBER CONSTANT VARCHAR2(1 CHAR) := 'N';
NODE_TYPE_DATE CONSTANT VARCHAR2(1 CHAR) := 'D';
NODE_TYPE_BOOLEAN CONSTANT VARCHAR2(1 CHAR) := 'B';
NODE_TYPE_OBJECT CONSTANT VARCHAR2(1 CHAR) := 'O';
NODE_TYPE_ARRAY CONSTANT VARCHAR2(1 CHAR) := 'A';

----------------------------------------------------------
-- get_default_options
Expand Down
35 changes: 19 additions & 16 deletions unittest/json_ut.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -1363,35 +1363,38 @@ END UT_BigObject;
PROCEDURE UT_PrettyOutput
IS
aOldOptions json_utils.outputOptionsType := json_utils.get_options();
aOptions json_utils.outputOptionsType := json_utils.get_default_options();
aOptions json_utils.outputOptionsType := json_utils.get_options();

aObject1 jsonObject := jsonObject();
aObject2 jsonObject := jsonObject();
aArray jsonArray := jsonArray();

aLob CLOB := empty_clob();

aResult CLOB := '{
"o1": {
"a1": [
1,
2,
3
],
"a2": [
1,
2,
3
]
}
}';
aResult CLOB;
BEGIN
UT_util.module('UT_PrettyOutput');

-- set pretty output
aOptions.Pretty := TRUE;
json_utils.set_options(aOptions);

-- result
aResult :=
'{'||aOptions.newline_char||
aOptions.indentation_char||'"o1": {'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||'"a1": ['||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'1,'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'2,'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'3'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||'],'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||'"a2": ['||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'1,'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'2,'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||aOptions.indentation_char||'3'||aOptions.newline_char||
aOptions.indentation_char||aOptions.indentation_char||']'||aOptions.newline_char||
aOptions.indentation_char||'}'||aOptions.newline_char||
'}';

-- allocate clob
dbms_lob.createtemporary(aLob, TRUE);

Expand Down

0 comments on commit c6b476c

Please sign in to comment.