Skip to content

Commit 05703b0

Browse files
authored
Convert table_schema type to TableSchema object (#100)
* Convert table_schema type to TableSchema object * Remove unused use
1 parent 0a1e659 commit 05703b0

18 files changed

+556
-753
lines changed

src/BuildSchemaCLI.php

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
use namespace HH\Lib\{C, Regex};
66
use type Facebook\CLILib\CLIWithArguments;
77
use namespace Facebook\CLILib\CLIOptions;
8-
use type Facebook\HackCodegen\{HackBuilderKeys, HackBuilderValues, HackCodegenConfig, HackCodegenFactory};
98

109
final class BuildSchemaCLI extends CLIWithArguments {
11-
private string $constName = 'DB_SCHEMA';
10+
private string $functionName = 'get_db_schema';
1211

1312
<<__Override>>
1413
protected function getSupportedOptions(): vec<CLIOptions\CLIOption> {
1514
return vec[CLIOptions\with_required_string(
1615
$name ==> {
17-
$this->constName = $name;
16+
$this->functionName = $name;
1817
},
19-
'The name of the constant to generate. Defaults to DB_SCHEMA',
18+
'The name of the function name to generate. Defaults to get_db_schema',
2019
'--name',
2120
)];
2221
}
@@ -67,43 +66,96 @@ protected function getSupportedOptions(): vec<CLIOptions\CLIOption> {
6766
$generated[$db] = $schema;
6867
}
6968

70-
$cg = new HackCodegenFactory(new HackCodegenConfig());
71-
72-
$generated = $cg->codegenConstant($this->constName)
73-
->setType('dict<string, dict<string, table_schema>>')
74-
->setValue($generated, HackBuilderValues::dict(HackBuilderKeys::export(), HackBuilderValues::dict(
75-
HackBuilderKeys::export(),
76-
// special exporters are required to make shapes and enum values, ::export would turn them into arrays and strings
77-
HackBuilderValues::shapeWithPerKeyRendering(
78-
shape(
79-
'name' => HackBuilderValues::export(),
80-
'indexes' =>
81-
HackBuilderValues::vec(HackBuilderValues::shapeWithUniformRendering(HackBuilderValues::export())),
82-
'fields' => HackBuilderValues::vec(HackBuilderValues::shapeWithPerKeyRendering(
83-
shape(
84-
'name' => HackBuilderValues::export(),
85-
'type' => HackBuilderValues::lambda(($_cfg, $str) ==> 'DataType::'.$str),
86-
'length' => HackBuilderValues::export(),
87-
'null' => HackBuilderValues::export(),
88-
'hack_type' => HackBuilderValues::export(),
89-
'default' => HackBuilderValues::export(),
90-
'unsigned' => HackBuilderValues::export(),
91-
),
92-
)),
93-
),
94-
),
95-
)))
96-
->render();
97-
98-
$generated = <<<EOT
99-
use type Slack\\SQLFake\\{table_schema, DataType};
100-
101-
102-
EOT
103-
.
104-
$generated;
69+
$generated = self::getRenderedHackTableSchemaWithClusters($this->functionName, $generated);
10570

10671
await $terminal->getStdout()->writeAllAsync($generated);
10772
return 0;
10873
}
74+
75+
//
76+
// Write out a top level import target containing all of our generated db files.
77+
//
78+
// This also contains a memoized function that returns a lookup for each field in our DB tables and the type of those fields.
79+
//
80+
81+
public static function getRenderedHackTableSchemaWithClusters(
82+
string $function_name,
83+
dict<string, dict<string, TableSchema>> $table_schemas,
84+
): string {
85+
$file_contents = '';
86+
87+
$file_contents .= "use type Slack\\SQLFake\\{Column, DataType, Index, TableSchema};\n";
88+
$file_contents .= "\n";
89+
$file_contents .= "<<__Memoize>>\n";
90+
$file_contents .= "function {$function_name}(): dict<string, dict<string, table_schema>> {\n";
91+
$file_contents .= "\treturn dict[\n";
92+
foreach ($table_schemas as $cluster => $tables) {
93+
$file_contents .= "\t\t'{$cluster}' => ".self::getRenderedHackTableSchema($tables, "\t\t");
94+
}
95+
$file_contents .= "\t];\n";
96+
$file_contents .= "}\n";
97+
98+
return $file_contents;
99+
}
100+
101+
public static function getRenderedHackTableSchema(
102+
dict<string, TableSchema> $table_schemas,
103+
string $indentation,
104+
): string {
105+
$file_contents = "dict[\n";
106+
foreach ($table_schemas as $table_schema) {
107+
$table_name = $table_schema->name;
108+
$file_contents .= $indentation."\t'{$table_name}' => new TableSchema(\n";
109+
110+
//
111+
// Write out the fields
112+
//
113+
114+
$file_contents .= $indentation."\t\t'{$table_name}',\n";
115+
$file_contents .= $indentation."\t\tvec[\n";
116+
foreach ($table_schema->fields as $field) {
117+
$file_contents .= $indentation."\t\t\tnew Column(\n";
118+
$file_contents .= $indentation."\t\t\t\t'{$field->name}',\n";
119+
$file_contents .= $indentation."\t\t\t\tDataType::{$field->type},\n";
120+
$file_contents .= $indentation."\t\t\t\t{$field->length},\n";
121+
$file_contents .= $indentation."\t\t\t\t" . ($field->null ? 'true' : 'false') . ",\n";
122+
$file_contents .= $indentation."\t\t\t\t'{$field->hack_type}',\n";
123+
if ($field->unsigned is nonnull || $field->default is nonnull) {
124+
if ($field->unsigned is nonnull) {
125+
$file_contents .= $indentation."\t\t\t\t" . ($field->unsigned ? 'true' : 'false') . ",\n";
126+
} else {
127+
$file_contents .= $indentation."\t\t\t\tnull,\n";
128+
}
129+
if ($field->default is nonnull) {
130+
$file_contents .= $indentation."\t\t\t\t'{$field->default}',\n";
131+
}
132+
}
133+
$file_contents .= $indentation."\t\t\t),\n";
134+
}
135+
$file_contents .= $indentation."\t\t],\n";
136+
137+
//
138+
// Write out the indexes
139+
//
140+
141+
$file_contents .= $indentation."\t\tvec[\n";
142+
foreach ($table_schema->indexes as $index) {
143+
$file_contents .= $indentation."\t\t\tnew Index(\n";
144+
$file_contents .= $indentation."\t\t\t\t'{$index->name}',\n";
145+
$file_contents .= $indentation."\t\t\t\t'{$index->type}',\n";
146+
$fields = 'keyset[\''.\implode('\', \'', $index->fields).'\']';
147+
$file_contents .= $indentation."\t\t\t\t{$fields},\n";
148+
$file_contents .= $indentation."\t\t\t),\n";
149+
}
150+
$file_contents .= $indentation."\t\t],\n";
151+
$file_contents .= $indentation."\t),\n";
152+
}
153+
154+
$file_contents .= $indentation."],\n";
155+
return $file_contents;
156+
}
157+
158+
private static function varExportStringArray(Container<string> $array): string {
159+
return C\is_empty($array) ? 'vec[]' : 'vec[\''.\HH\Lib\Str\join($array, '\', \'').'\']';
160+
}
109161
}

src/Column.hack

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Slack\SQLFake;
2+
3+
final class Column {
4+
public function __construct(
5+
public string $name,
6+
public DataType $type,
7+
public int $length,
8+
public bool $null,
9+
public string $hack_type,
10+
public ?bool $unsigned = null,
11+
public ?string $default = null,
12+
) {}
13+
}

0 commit comments

Comments
 (0)