Skip to content

Commit

Permalink
prof: enhance json data parse logic
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Nov 18, 2021
1 parent d95f4e4 commit 8fc9f35
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 56 deletions.
17 changes: 9 additions & 8 deletions app/Console/Controller/ConvertController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@
use function file_get_contents;
use function implode;
use function is_file;
use function json_encode;
use function strlen;
use function substr;
use function trim;
use function vdump;

/**
* Class ConvertController
Expand Down Expand Up @@ -122,20 +120,23 @@ public function sql2mdCommand(FlagsParser $fs, Output $output): void
}

/**
* convert create mysql table SQL to markdown table
* convert formatted text to markdown table
*
* @arguments
* type The target text doc type, allow: raw, md-table,
*
* @options
* -s,--source string;The source code for convert. allow: FILEPATH, @clipboard;true
* -o,--output The output target. default is stdout.
* --item-sep The item sep char. default is NL.
* --value-num int;The item value number. default get from first line.
* --value-sep The item value sep char. default is SPACE
* -s,--source string;The source code for convert. allow: FILEPATH, @clipboard;true
* -o,--output The output target. default is stdout.
* --is, --item-sep The item sep char. default is NL.
* --vn, --value-num int;The item value number. default get from first line.
* --vs, --value-sep The item value sep char. default is SPACE
*
* @param FlagsParser $fs
* @param Output $output
*
* @example
* {binWithCmd} -s @c --vn
*/
public function textCommand(FlagsParser $fs, Output $output): void
{
Expand Down
3 changes: 2 additions & 1 deletion app/Console/Controller/PhpController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use function preg_quote;
use function sprintf;
use function str_contains;
use function strlen;
use function trim;
use function vdump;

Expand Down Expand Up @@ -363,7 +364,7 @@ public function runFuncCommand(FlagsParser $fs, Output $output): void
if ($args = $fs->getArg('funcArgs')) {
$fmtArgs = [];
foreach ($args as $k => $arg) {
if (is_numeric($arg)) {
if (is_numeric($arg) && strlen($arg) < 11) {
$fmtArgs[] = $arg;
$args[$k] = (int)$arg;
} else {
Expand Down
2 changes: 2 additions & 0 deletions app/Lib/Generate/Java/JavaType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class JavaType
{
public const LONG = 'Long';

public const LIST = 'List';

public const OBJECT = 'Object';

/**
Expand Down
78 changes: 69 additions & 9 deletions app/Lib/Generate/Json5Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use Inhere\Kite\Lib\Parser\Text\Json5ItemParser;
use Inhere\Kite\Lib\Parser\Text\TextParser;
use Toolkit\Stdlib\Obj\AbstractObj;
use Toolkit\Stdlib\Type;
use function count;
use function gettype;
use function is_array;
use function str_replace;
use function strpos;
use function substr;
Expand All @@ -24,20 +27,28 @@ class Json5Data extends AbstractObj
*/
private array $settings = [];

/**
* @var array<string, string>
*/
private array $comments = [];

/**
* @var array<string, JsonField>
*/
private array $fields = [];

/**
* @var array<string, array<string, JsonField>>
*/
private array $subObjects = [];

/**
* @param string $json
*
* @return $this
*/
public function loadFrom(string $json): self
{
$comments = [];

// has comments chars
if (str_contains($json, '//')) {
$p = TextParser::newWithParser($json, new Json5ItemParser())
Expand All @@ -54,7 +65,7 @@ public function loadFrom(string $json): self
})
->parse();

$comments = $p->getStringMap('field', 'comment');
$this->comments = $p->getStringMap('field', 'comment');
$this->setSettings($p->getSettings());
// get no header json
$json = $p->getTextBody();
Expand All @@ -66,15 +77,56 @@ public function loadFrom(string $json): self
}

$jsonData = Json5Decoder::decode($json, true);
foreach ($jsonData as $key => $value) {
$this->fields[$key] = JsonField::new([
'name' => $key,
'type' => gettype($value),
'comment' => $comments[$key] ?? $key,
$this->collectObjectFields('', $jsonData);
$this->comments = [];

return $this;
}

/**
* @param string $name
* @param array $map
*/
protected function collectObjectFields(string $name, array $map): void
{
$fields = [];
foreach ($map as $key => $value) {
$type = gettype($value);

$elemType = $elemSfx = '';
if ($type === 'array' && !empty($value)) {
if ($key && isset($this->subObjects[$key])) {
$elemSfx = '_' . count($this->subObjects);
}

// is object
if (!isset($value[0])) {
$type = Type::OBJECT;
$this->collectObjectFields($key, $value);
} elseif (!empty($value[0])) { // is array
// collect first item on it's object
if (is_array($value[0])) {
$elemSfx = 'Item' . $elemSfx;
$this->collectObjectFields($key, $value[0]);
} else {
$elemType = gettype($value[0]);
}
}
}

$fields[$key] = JsonField::new([
'name' => $key,
'type' => $type,
'elemType' => $elemType . $elemSfx,
'comment' => $this->comments[$key] ?? $key,
]);
}

return $this;
if ($name) {
$this->subObjects[$name] = $fields;
} else {
$this->fields = $fields;
}
}

/**
Expand All @@ -100,4 +152,12 @@ public function getFields(): array
{
return $this->fields;
}

/**
* @return Json\JsonField[][]
*/
public function getSubObjects(): array
{
return $this->subObjects;
}
}
32 changes: 25 additions & 7 deletions app/Lib/Parser/Item/FieldItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Toolkit\Stdlib\Str;
use Toolkit\Stdlib\Type;
use function preg_match;
use function sprintf;

/**
* class FieldItem
Expand All @@ -21,6 +22,13 @@ class FieldItem extends AbstractObj implements JsonSerializable

public string $type;

/**
* sub-elem type on type is array
*
* @var string
*/
public string $elemType = '';

public string $comment = '';

/**
Expand Down Expand Up @@ -50,22 +58,32 @@ public function phpType(): string
*/
public function javaType(): string
{
if (str_ends_with($this->name, 'id') || str_ends_with($this->name, 'Id')) {
return JavaType::LONG;
}

return $this->toJavaType($this->type);
return $this->toJavaType($this->type, $this->name);
}

/**
* @param string $type
* @param string $name
*
* @return string
*/
public function toJavaType(string $type): string
public function toJavaType(string $type, string $name): string
{
if (Str::hasSuffixIC($this->name, 'id')) {
return JavaType::LONG;
}

if ($type === Type::ARRAY) {
return JavaType::OBJECT;
$elemType = $this->elemType ?: $name;
if ($elemType === 'List') {
$elemType .= '_KW';
}

return sprintf('%s<%s>', JavaType::LIST, Str::upFirst($elemType));
}

if ($type === Type::OBJECT) {
return Str::upFirst($name);
}

return Str::upFirst($type);
Expand Down
6 changes: 4 additions & 2 deletions app/Lib/Parser/MySQL/TableField.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ public function phpType(): string

/**
* @param string $type
* @param string $name
*
* @return string
*/
public function toJavaType(string $type): string
public function toJavaType(string $type, string $name): string
{
if ($type === DBType::JSON) {
return JavaType::OBJECT;
// return JavaType::OBJECT;
return Str::upFirst($name);
}

$type = DBType::toPhpType($type);
Expand Down
40 changes: 36 additions & 4 deletions plugin/AddCommentsToJson5.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function exec(Application $app, Output $output): void
return;
}

$parent = '';
$source = $this->fs->getOpt('source');

$reader = ContentsAutoReader::new();
Expand All @@ -75,18 +76,49 @@ public function exec(Application $app, Output $output): void
foreach (explode("\n", $srcText) as $line) {
$trimmed = trim($line);
// empty or exists comments
if (!$trimmed || str_contains($trimmed, '//')) {
if (!$trimmed) {
$fmtLines[] = $line;
continue;
}

if (preg_match('/[a-zA-Z][\w_]+/', $trimmed, $matches)) {
$field = $matches[0];
// 匹配字段名
if (preg_match('/^\s*[\'"]?([a-zA-Z][\w_]+)/', $trimmed, $matches)) {
$field = $matches[1];
$fullK = $parent ? $parent . '.'. $field : '';

// 有注释标记了。检查特殊标记
if (strpos($trimmed, '//') > 0) {
[$prefix, $comment] = Str::explode($trimmed, '//', 2);

// 字段映射到map的别名 用于一些通用字段
// 比如 type, status 等; type -> order.type, goods.type
if ($comment && str_ends_with($comment, ".$field")) {
$line = $prefix;
$field = $comment;
} else {
$fmtLines[] = $line;
// start mark: eg 'object: {', 'array: ['
if (Str::isEndWiths($prefix, ['{', '['])) {
$parent = $field;
}
continue;
}

// start mark: eg 'object: {', 'array: ['
} elseif (Str::isEndWiths($trimmed, ['{', '['])) {
$parent = $field;
}

// add comments
if (isset($this->mapData[$field]) && !in_array($field, $this->exclude, true)) {
if ($fullK && isset($this->mapData[$fullK])) {
$line .= ' // ' . $this->mapData[$fullK];
} elseif (isset($this->mapData[$field]) && !in_array($field, $this->exclude, true)) {
$line .= ' // ' . $this->mapData[$field];
}

// object,array end: '}', ']'
} elseif (Str::isEndWiths(rtrim($trimmed, ','), ['}', ']'])) {
$parent = '';
}

$fmtLines[] = $line;
Expand Down
Loading

0 comments on commit 8fc9f35

Please sign in to comment.