in sources/cg_json_schema.c [638:725]
static void cg_json_col_attrs(charbuf *output, col_info *info) {
// most of the attributes are in the semantic type, we don't have to walk the tree for them
// we do need to check for a default value.
// Note that there are implications associated with this flags and semantic analysis
// makes those conclusions (e.g. pk implies not null)
// We don't want that logic again so we use the semantic type not the raw declaration
ast_node *col = info->def;
sem_t sem_type = col->sem->sem_type;
CSTR name = col->sem->name;
bool_t is_added = col->sem->create_version > 0;
bool_t is_deleted = col->sem->delete_version > 0;
bprintf(output, ",\n\"isAdded\" : %d", is_added);
if (is_added) {
bprintf(output, ",\n\"addedVersion\" : %d", col->sem->create_version);
cg_json_added_migration_proc(output, info->attrs);
}
bprintf(output, ",\n\"isDeleted\" : %d", is_deleted);
if (is_deleted) {
bprintf(output, ",\n\"deletedVersion\" : %d", col->sem->delete_version);
cg_json_deleted_migration_proc(output, info->attrs);
}
if (sem_type & SEM_TYPE_PK) {
bprintf(info->col_pk, "\"%s\"", name);
}
if (sem_type & SEM_TYPE_UK) {
if (info->col_uk->used > 1) {
bprintf(info->col_uk, ",\n");
}
bprintf(info->col_uk, "{\n");
bprintf(info->col_uk, " \"name\" : \"%s_uk\",\n", name);
bprintf(info->col_uk, " \"columns\" : [ \"%s\" ],\n", name);
bprintf(info->col_uk, " \"sortOrders\" : [ \"\" ]\n");
bprintf(info->col_uk, "}");
}
// There could be several foreign keys, we have to walk the list of attributes and gather them all
for (ast_node *attr = info->attrs; attr; attr = attr->right) {
charbuf *saved = output;
output = info->col_fk;
if (is_ast_col_attrs_fk(attr)) {
if (output->used > 1) {
bprintf(output, ",\n");
}
bprintf(output, "{\n");
BEGIN_INDENT(fk, 2)
bprintf(output, "\"columns\" : [ \"%s\" ]", name);
cg_json_fk_target_options(output, attr->left);
END_INDENT(fk);
bprintf(output,"\n}");
}
output = saved;
}
if (sem_type & SEM_TYPE_HAS_DEFAULT) {
bprintf(output, ",\n\"defaultValue\" : ");
cg_json_default_value(output, sem_get_col_default_value(info->attrs));
}
if (sem_type & SEM_TYPE_HAS_COLLATE) {
// find the collate attribute and emit it (there can only be one)
for (ast_node *attr = info->attrs; attr; attr = attr->right) {
if (is_ast_col_attrs_collate(attr)) {
bprintf(output, ",\n\"collate\" : ");
cg_json_attr_value(output, attr->left);
}
}
}
if (sem_type & SEM_TYPE_HAS_CHECK) {
// find the check attribute and emit it (there can only be one)
for (ast_node *attr = info->attrs; attr; attr = attr->right) {
if (is_ast_col_attrs_check(attr)) {
EXTRACT_ANY_NOTNULL(when_expr, attr->left);
cg_fragment_with_params(output, "checkExpr", when_expr, gen_root_expr);
}
}
}
// end with mandatory columns, this makes the json validation with yacc a little easier
bprintf(output, ",\n\"isPrimaryKey\" : %d", !!(sem_type & SEM_TYPE_PK));
bprintf(output, ",\n\"isUniqueKey\" : %d", !!(sem_type & SEM_TYPE_UK));
bprintf(output, ",\n\"isAutoIncrement\" : %d", !!(sem_type & SEM_TYPE_AUTOINCREMENT));
}