mikee47 / ConfigDB

Configuration database for Sming
GNU General Public License v3.0
3 stars 1 forks source link

External Schemas #53

Closed mikee47 closed 1 month ago

mikee47 commented 2 months ago

I'm raising this issue to discuss how to implement external (re-useable) schemas. Currently only #/$defs/NAME is supported, and all definitions appear in the same database.

From https://json-schema.org/understanding-json-schema/structuring#schema-identification:

Even though schemas are identified by URIs, those identifiers are not necessarily network-addressable. They are just identifiers.

Generally, implementations don't make HTTP requests (https://) or read from the file system (file://) to fetch schemas. Instead, they provide a way to load schemas into an internal schema database. When a schema is referenced by it's URI identifier, the schema is retrieved from the internal schema database.

This suggests that what dbgen should not do is treat the identifier as a relative file path, but instead supply all external schema explicitly on the command line to dbgen.

At present each .cfgdb file generates a .h and .cpp file pair. Does this make sense for definition-only schemas?

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$defs": {
    ...
  }
}

If a definition is used by more than one schema, then where do we define it? We don't want a situation where each database has its own definition of the same type: it may not be an error, but it would certainly be confusing.

Therefore, even definition-only schemas should generate code since those files would need to be #included by others.

mikee47 commented 2 months ago

As an example I'll look at the test schemas. Let's say we want to use the Color definition from test-config-union.cfgdb. The C++ class we're interested in is generated as TestConfigUnion::ContainedColor.

Referencing this from, say, test-config.cfgdb means the code generator would need to output two items:

  1. #include <test-config-union.h>
  2. using ContainedColor = TestConfigUnion::ContainedColor inside class TestConfig

So the code generator only needs the name of the external schema, and the name of the definition.

So what URI should we support via $ref ?

Internal: #/$defs/Color External: test-config-union/Color

mikee47 commented 2 months ago

So the code generator only needs the name of the external schema, and the name of the definition.

Me being hopeful! No, of course it needs the full definition. For one, it needs to know the size of the generated object.

mikee47 commented 2 months ago

So I'm thinking maybe the way to tackle this is to call dbgen with all the schemas on the same command line, rather than a separate invocation for each. It can then parse all schemas together so resolving references becomes more straightforward.

pljakobs commented 1 month ago

[oh my, what did I request there again ;-) But of course, I didn't consider that just referring to an external schema would create a situation where the same code might be generated twice :o ]