Skip to content
Snippets Groups Projects
Commit 25525a3c authored by Recolic K's avatar Recolic K
Browse files

Allow multiple-col-selection, and add tests

parent c41230d7
No related branches found
No related tags found
No related merge requests found
......@@ -33,29 +33,42 @@ void json_decay_single_element_array(json &input) {
while(input.is_array() && input.size() == 1)
input = input[0];
}
void _json_get_subset(json &input, rlib::string subset_key) {
// This function steps one-level deeper in the path
json_decay_single_element_array(input);
if(input.is_object()) {
// Supports multiple col selection
auto subset_keys = subset_key.split(',');
if(subset_keys.size() == 1)
// Simplest case. we must decay to the next level, if there's only one subset key.
input = input[subset_keys[0]];
else {
// Multiple subset keys. The result is a table in the same level, EVEN IF only one of them exists in result.
json result = {}; // Not-null even if none of keys exists.
for(auto &&k : subset_keys) {
if(!k.empty()) result[k] = input[k];
}
input = std::move(result);
}
}
else if(input.is_array()) {
// Do element-wise-operation for every element.
json result_json_arr = json::array();
for(auto &[_, item] : input.items()) {
json_decay_single_element_array(item);
_json_get_subset(item, subset_key);
result_json_arr.emplace_back(std::move(item));
}
input = std::move(result_json_arr);
}
else {
throw std::invalid_argument("json_path is not valid for json. No element `" + subset_key + "` found in json input. (the result of previous level is neither object nor array)");
}
}
void naive_json_access_path(json &input, rlib::string json_path) {
for(auto &next : json_path.split('/')) {
if(!next.empty()) {
json_decay_single_element_array(input);
if(input.is_object()) {
// Simplest case.
input = input[next];
}
else if(input.is_array()) {
// Do this for every element.
json result_json_arr = json::array();
for(auto &[_, item] : input.items()) {
json_decay_single_element_array(item);
if(item.is_object())
result_json_arr.push_back(item[next]);
else
throw std::invalid_argument("json_path is not valid for json. No element `" + next + "` found in json input. (note that I support only one-level array iterate)");
}
input = std::move(result_json_arr);
}
else {
throw std::invalid_argument("json_path is not valid for json. No element `" + next + "` found in json input. ");
}
_json_get_subset(input, next);
}
}
}
......@@ -63,10 +76,12 @@ void naive_json_access_path(json &input, rlib::string json_path) {
int main(int argc, char **argv) {
rlib::opt_parser args(argc, argv);
if(args.getBoolArg("-h", "--help")) {
rlib::println("json2table version 1.0.3, maintainer Recolic Keghart <root@recolic.net>");
rlib::println("json2table version 1.0.4, maintainer Recolic Keghart <root@recolic.net>");
rlib::println("Usage: cat xxx.json | json2table");
rlib::println("Usage: curl https://myapi/getJson | json2table /path/to/subobject");
rlib::println("Set --programming to make the output easier for program to process. ");
rlib::println("Set --programming / -p to make the output easier for program to process. ");
rlib::println("You can use /path/to/col1,col2,col8 to select multiple columns. ");
rlib::println("This tool has a stable CLI interface between different version, unless explicitly warned. ");
return 1;
}
program_mode = args.getBoolArg("-p", "--programming");
......@@ -83,6 +98,7 @@ int main(int argc, char **argv) {
size_t curr_row_pos = 0;
json_decay_single_element_array(input);
if(input.is_array()) {
// multi-row complete table
for(auto &[_, item] : input.items()) {
json_decay_single_element_array(item);
if(item.is_object()) {
......@@ -111,7 +127,7 @@ int main(int argc, char **argv) {
}
}
else if(input.is_object()) {
// single-row
// single-row table
for(auto &[key, value] : input.items()) {
// Add key-value into table.
headers.emplace_back(key);
......@@ -119,11 +135,13 @@ int main(int argc, char **argv) {
}
}
else {
// gg. Just print and go.
// No way to create table. Just print and go.
rlib::println("Single value:", json_to_string(input));
return 0;
}
////////////////////// Print-out the table
if(program_mode) {
rlib::println(rlib::printable_iter(headers, "|"));
for(auto &row : rows) {
......
{
"vm": [
{"username": "he,llo", "ip": "1.1.1.1", "password": "n,oob"},
{"username": "hello", "ip": "1.1.1.1", "password": "b"},
{"username": "hell,o4", "ip": "12.1.1.1", "password": "noob"},
{"username": "hello", "ip": "1.1.1.1", "password": "oob"},
{"username": "hel,lo4", "ip": "1.21.1.1", "password": "noob"},
{"username": "hello", "ip": "1.1.21.1", "password": "no,,ob"},
{"username": "hello", "ip": "1.1.21.1", "password": "noob"},
{"username": "he,llo4", "ip": "1.1.21.1", "password": "noo2b"},
{"username": "hello", "ip": "1.12.12.1", "password": "no2,,,ob"},
{"username": "he,llo5", "ip": "1.21.1.1", "password": "noob"},
{"username": "hello", "ip": "1.1.1.1", "password": "noob"},
{"username": "hello3", "ip": "1.12.1.1", "password": "no222ob"},
{"username": "hello", "ip": "1.1.1.1", "password": "noo,,,22b"},
{"username": "hello", "ip": "1.1.12.1", "password": "noob"},
{"username": "hello1", "ip": "1.1.1.1", "password": "no2ob"},
{"username": "he,llo", "ip": "1.12.1.1", "password": "n2oo,,b"},
{"username": "hello1", "ip": "1.1.1.1", "password": "noo2b"},
{"username": "hello", "ip": "1.12.1.1", "password": "noo22b"},
{"username": "he,llo", "ip": "1.12.21.1", "password": "no22o,,b"},
{"username": "hello", "ip": "1.1.1.21", "password": "noob"},
{"username": "hel,lo1", "ip": "1.1.1.21", "password": "no2ob"},
{"username": "he,llo11", "ip": "1.1.1.21", "password": "2noob,,,"}
]
}
{
"medications":[{
"aceInhibitors":[{
"name":"lisinopril",
"strength":"10 mg Tab",
"dose":"1 tab",
"route":"PO",
"sig":"daily",
"pillCount":"#90",
"refills":"Refill 3"
}],
"antianginal":[{
"name":"nitroglycerin",
"strength":"0.4 mg Sublingual Tab",
"dose":"1 tab",
"route":"SL",
"sig":"q15min PRN",
"pillCount":"#30",
"refills":"Refill 1"
}],
"anticoagulants":[{
"name":"warfarin sodium",
"strength":"3 mg Tab",
"dose":"1 tab",
"route":"PO",
"sig":"daily",
"pillCount":"#90",
"refills":"Refill 3"
}],
"betaBlocker":[{
"name":"metoprolol tartrate",
"strength":"25 mg Tab",
"dose":"1 tab",
"route":"PO",
"sig":"daily",
"pillCount":"#90",
"refills":"Refill 3"
}],
"diuretic":[{
"name":"furosemide",
"strength":"40 mg Tab",
"dose":"1 tab",
"route":"PO",
"sig":"daily",
"pillCount":"#90",
"refills":"Refill 3"
}],
"mineral":[{
"name":"potassium chloride ER",
"strength":"10 mEq Tab",
"dose":"1 tab",
"route":"PO",
"sig":"daily",
"pillCount":"#90",
"refills":"Refill 3"
}]
}
],
"labs":[{
"name":"Arterial Blood Gas",
"time":"Today",
"location":"Main Hospital Lab"
},
{
"name":"BMP",
"time":"Today",
"location":"Primary Care Clinic"
},
{
"name":"BNP",
"time":"3 Weeks",
"location":"Primary Care Clinic"
},
{
"name":"BUN",
"time":"1 Year",
"location":"Primary Care Clinic"
},
{
"name":"Cardiac Enzymes",
"time":"Today",
"location":"Primary Care Clinic"
},
{
"name":"CBC",
"time":"1 Year",
"location":"Primary Care Clinic"
},
{
"name":"Creatinine",
"time":"1 Year",
"location":"Main Hospital Lab"
},
{
"name":"Electrolyte Panel",
"time":"1 Year",
"location":"Primary Care Clinic"
},
{
"name":"Glucose",
"time":"1 Year",
"location":"Main Hospital Lab"
},
{
"name":"PT/INR",
"time":"3 Weeks",
"location":"Primary Care Clinic"
},
{
"name":"PTT",
"time":"3 Weeks",
"location":"Coumadin Clinic"
},
{
"name":"TSH",
"time":"1 Year",
"location":"Primary Care Clinic"
}
],
"imaging":[{
"name":"Chest X-Ray",
"time":"Today",
"location":"Main Hospital Radiology"
},
{
"name":"Chest X-Ray",
"time":"Today",
"location":"Main Hospital Radiology"
},
{
"name":"Chest X-Ray",
"time":"Today",
"location":"Main Hospital Radiology"
}
]
}
test/3.json 0 → 100644
This diff is collapsed.
6f7808fc1f39b029d26a3d2198e1fa5cb61245edf2dc96f666518cfbddf220efLS0gMS5qc29uCg==
6f7808fc1f39b029d26a3d2198e1fa5cb61245edf2dc96f666518cfbddf220efLS0gMS5qc29uIC8K
300d1fec1e7e022452a65f6e42c466517b8287b2c25fe3e4a1b0321120145f3eLS0gMS5qc29uIC92bQo=
83f0a32269140ce47f00b85111c2da8aae6a1f6cbc4601733d5b86b8eab20ee4LS0gMS5qc29uIC92bS9pcAo=
3e4d1d5dbb7930fee4bc4c6d2d8a3aecb990aceca77c9247dada2aa9509b8186LS0gMS5qc29uIC92bS9pcCxwYXNzd29yZAo=
34f5f5a4a506ef8b52f65ebbc7c1f7d4751a7f98c6f3581c09a574259a65e3d7LS0gMS5qc29uIC92bSxub25lCg==
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855LS0gMS5qc29uIC92bS9pcC9ub25lCg==
30b2f547623587a220972fbe575b0a53c20a85c43d23b9e65b75782acfa2cd73LS0gMS5qc29uIC92bS9pcCxwYXNzd29yZC9ub25lCg==
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMS5qc29uIC92bSxub25lL2lwCg==
f326e229cd63a520c50ebdc0630aa08b649910a013575a36b6ed3b1196e276bfLS0gMi5qc29uIC8K
e233f3f411a5c7a3b9d524dea30897caef8fd64ec996d27bd5a80e64aade5bc1LS0gMi5qc29uIC9sYWJzCg==
8f6cf4f9a6f12ae6bd42155c53dd61f0a3557b724dd2bfb433985abd2655fdbfLS0gMi5qc29uIC9tZWRpY2F0aW9ucwo=
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMi5qc29uIC9sYWJzLG1lZGljYXRpb25zL25hbWUK
2779e990520f609638a7d1cdf4a635f97d7404e054f4835b76ed48a983818050LS0gMi5qc29uIC9tZWRpY2F0aW9ucy9taW5lcmFsCg==
2779e990520f609638a7d1cdf4a635f97d7404e054f4835b76ed48a983818050LS0gMi5qc29uIC9tZWRpY2F0aW9ucy9taW5lcmFsLwo=
f326e229cd63a520c50ebdc0630aa08b649910a013575a36b6ed3b1196e276bfLS0gMi5qc29uIC8vLy8vLy8K
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMi5qc29uIC9pbWFnaW5nLGxhYnMvbG9jYXRpb24K
d31440a27334d901c1629656eb3598e7ca394b3d829b905626076045737c9453LS0gMy5qc29uIC9wYXlsb2FkL2NvbW1pdHMsaGVhZCxhY3Rpb24K
3c415812bce0140888d90dd09f78a5e1045ad6d8ee13eac4751842404b32b30dLS0gMy5qc29uIC9wYXlsb2FkL2NvbW1pdHMK
e9aa21255980931bcd8f4bacc40f59b5f7142fd0fe25682ebbdda4cf4949636bLS0gMy5qc29uIC9wYXlsb2FkCg==
6f7808fc1f39b029d26a3d2198e1fa5cb61245edf2dc96f666518cfbddf220efLS0gMS5qc29uCg==
b7935e2c3b4974d7d6894a5b05b626f342162e03723d7905cea3bd054b2bb57aLS0gMS5qc29uIC8gLXAK
644ead988d726ace4a13f3c306ea554e1729da70581a32bbe970b2788194471fLS0gMS5qc29uIC92bSAtcAo=
523f850ed8e9f1b31e699c7977bf687edc2a30fd8413308fdca8909c229a9ea4LS0gMS5qc29uIC92bS9pcCAtcAo=
28a516f6ebed9672b85cee5eab83135fb90c65fc7fd096ed0e519027ed55287eLS0gMS5qc29uIC92bS9pcCxwYXNzd29yZCAtcAo=
82c0db542f229d42e8fc9f146d29168189efab44f00ae70d8ccb6e94c47d8344LS0gMS5qc29uIC92bSxub25lIC1wCg==
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855LS0gMS5qc29uIC92bS9pcC9ub25lIC1wCg==
dde2e9b0550fb1534468f299627b2f14ec7c10d249a89b0d9cc0d574aec1273bLS0gMS5qc29uIC92bS9pcCxwYXNzd29yZC9ub25lIC1wCg==
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMS5qc29uIC92bSxub25lL2lwIC1wCg==
7e440d19e81e9f448353bae27a63bcba100669376f1b138048806b39840e0758LS0gMi5qc29uIC8gLXAK
77d00107487aac9d0662c42b92406d6dde354f08ddc338f37143cedb9e0846f5LS0gMi5qc29uIC9sYWJzIC1wCg==
b7498016437c2535dd25f2b67e4b690d74e8d76e7e65f12766ca75b943932e6bLS0gMi5qc29uIC9tZWRpY2F0aW9ucyAtcAo=
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMi5qc29uIC9sYWJzLG1lZGljYXRpb25zL25hbWUgLXAK
13c3bb68fcf51e09a704a5d9f04597cae19393ea646c89a0e38766e83af527e7LS0gMi5qc29uIC9tZWRpY2F0aW9ucy9taW5lcmFsIC1wCg==
13c3bb68fcf51e09a704a5d9f04597cae19393ea646c89a0e38766e83af527e7LS0gMi5qc29uIC9tZWRpY2F0aW9ucy9taW5lcmFsLyAtcAo=
7e440d19e81e9f448353bae27a63bcba100669376f1b138048806b39840e0758LS0gMi5qc29uIC8vLy8vLy8gLXAK
f8883e36a4930c95f6538a34b965772c2ff2fc44d5fd7c08498629f0a37974e2LS0gMi5qc29uIC9pbWFnaW5nLGxhYnMvbG9jYXRpb24gLXAK
772fd278789db1083f8701aeae35405f898d74f778ed0eb9ae13c4a9198d85fcLS0gMy5qc29uIC9wYXlsb2FkL2NvbW1pdHMsaGVhZCxhY3Rpb24gLXAK
2ee6cffe37ad185bb27ef0342dd4d1d77a985d8b4f5edbfbdd2d367b303b33d0LS0gMy5qc29uIC9wYXlsb2FkL2NvbW1pdHMgLXAK
be9ac75fe4781b6312aa0fda78b392f7e4b3ca5099178d723f1e7e5f7312e777LS0gMy5qc29uIC9wYXlsb2FkIC1wCg==
function testcase () {
res=`cat "$1" | json2table "$2" "$3" | sha256sum | cut -d ' ' -f 1``echo -- "$@" | base64 -w 0`
if [[ $standard = 1 ]]; then
echo "$res" >> answers
else
grep "$res" answers > /dev/null && echo -- "OK: $@" || echo -- "FAIL: $@"
fi
}
standard=0
testcase 1.json
testcase 1.json /
testcase 1.json /vm
testcase 1.json /vm/ip
testcase 1.json /vm/ip,password
testcase 1.json /vm,none
testcase 1.json /vm/ip/none
testcase 1.json /vm/ip,password/none
testcase 1.json /vm,none/ip
testcase 2.json /
testcase 2.json /labs
testcase 2.json /medications
testcase 2.json /labs,medications/name
testcase 2.json /medications/mineral
testcase 2.json /medications/mineral/
testcase 2.json ///////
testcase 2.json /imaging,labs/location
testcase 3.json /payload/commits,head,action
testcase 3.json /payload/commits
testcase 3.json /payload
testcase 1.json
testcase 1.json / -p
testcase 1.json /vm -p
testcase 1.json /vm/ip -p
testcase 1.json /vm/ip,password -p
testcase 1.json /vm,none -p
testcase 1.json /vm/ip/none -p
testcase 1.json /vm/ip,password/none -p
testcase 1.json /vm,none/ip -p
testcase 2.json / -p
testcase 2.json /labs -p
testcase 2.json /medications -p
testcase 2.json /labs,medications/name -p
testcase 2.json /medications/mineral -p
testcase 2.json /medications/mineral/ -p
testcase 2.json /////// -p
testcase 2.json /imaging,labs/location -p
testcase 3.json /payload/commits,head,action -p
testcase 3.json /payload/commits -p
testcase 3.json /payload -p
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment