@@ -33,6 +33,11 @@ def replace_component_in_paths(oldname, newname, paths):
3333 paths [index ] = newPath
3434
3535
36+ def _versioned (typename , version ):
37+ """Return a versioned name of the typename"""
38+ return f"{ typename } v{ version } "
39+
40+
3641class IncludeFrom (IntEnum ):
3742 """Enum to signify if an include is needed and from where it should come"""
3843
@@ -72,7 +77,6 @@ def __init__( # pylint: disable=too-many-arguments
7277 self .old_yamlfile = old_description
7378 self .evolution_file = evolution_file
7479 self .old_schema_version = None
75- self .old_schema_version_int = None
7680 self .old_datamodel = None
7781 self .old_datamodels_components = set ()
7882 self .old_datamodels_datatypes = set ()
@@ -117,21 +121,7 @@ def do_process_component(self, name, component):
117121 component ["includes" ] = self ._sort_includes (includes )
118122
119123 self ._fill_templates ("Component" , component )
120- # Add potentially older schema for schema evolution
121- # based on ROOT capabilities for now
122- if name in self .root_schema_dict :
123- schema_evolutions = self .root_schema_dict [name ]
124- component = deepcopy (component )
125- for schema_evolution in schema_evolutions :
126- if isinstance (schema_evolution , RenamedMember ):
127- for member in component ["Members" ]:
128- if member .name == schema_evolution .member_name_new :
129- member .name = schema_evolution .member_name_old
130- component ["class" ] = DataType (name + self .old_schema_version )
131- else :
132- raise NotImplementedError
133- self ._fill_templates ("Component" , component )
134- self .root_schema_component_names .add (name + self .old_schema_version )
124+ self ._preprocess_schema_evolution_component (name , component )
135125
136126 return component
137127
@@ -143,47 +133,7 @@ def do_process_datatype(self, name, datatype):
143133 self ._preprocess_for_obj (datatype )
144134 self ._preprocess_for_collection (datatype )
145135
146- # ROOT schema evolution preparation
147- # Compute and prepare the potential schema evolution parts
148- schema_evolution_datatype = deepcopy (datatype )
149- needs_schema_evolution = False
150- for member in schema_evolution_datatype ["Members" ]:
151- if member .is_array :
152- if member .array_type in self .root_schema_dict :
153- needs_schema_evolution = True
154- replace_component_in_paths (
155- member .array_type ,
156- member .array_type + self .old_schema_version ,
157- schema_evolution_datatype ["includes_data" ],
158- )
159- member .full_type = member .full_type .replace (
160- member .array_type , member .array_type + self .old_schema_version
161- )
162- member .array_type = member .array_type + self .old_schema_version
163-
164- else :
165- if member .full_type in self .root_schema_dict :
166- needs_schema_evolution = True
167- # prepare the ROOT I/O rule
168- replace_component_in_paths (
169- member .full_type ,
170- member .full_type + self .old_schema_version ,
171- schema_evolution_datatype ["includes_data" ],
172- )
173- member .full_type = member .full_type + self .old_schema_version
174- member .bare_type = member .bare_type + self .old_schema_version
175-
176- if needs_schema_evolution :
177- print (f" Preparing explicit schema evolution for { name } " )
178- schema_evolution_datatype ["class" ].bare_type = (
179- schema_evolution_datatype ["class" ].bare_type + self .old_schema_version
180- ) # noqa
181- schema_evolution_datatype ["old_schema_version" ] = self .old_schema_version_int
182- self ._fill_templates ("Data" , schema_evolution_datatype )
183- self .root_schema_datatype_names .add (name + self .old_schema_version )
184- self ._fill_templates ("Collection" , datatype , schema_evolution_datatype )
185- else :
186- self ._fill_templates ("Collection" , datatype )
136+ self ._preprocess_schema_evolution_datatype (name , datatype )
187137
188138 self ._fill_templates ("Data" , datatype )
189139 self ._fill_templates ("Object" , datatype )
@@ -215,7 +165,7 @@ def do_process_link(self, _, link):
215165 for rel in ("From" , "To" ):
216166 rel_type = link [rel ]
217167 include_header = f"{ rel_type .bare_type } Collection"
218- if self ._is_interface (rel_type .full_type ):
168+ if self ._is_in (rel_type .full_type , "interfaces" ):
219169 # Interfaces do not have a Collection header
220170 include_header = rel_type .bare_type
221171 link ["include_types" ].append (
@@ -253,7 +203,7 @@ def _preprocess_for_class(self, datatype):
253203 member .sub_members = self .datamodel .components [member .full_type ]["Members" ]
254204
255205 for relation in datatype ["OneToOneRelations" ]:
256- if self ._is_interface (relation .full_type ):
206+ if self ._is_in (relation .full_type , "interfaces" ):
257207 relation .interface_types = self .datamodel .interfaces [relation .full_type ]["Types" ]
258208 if self ._needs_include (relation .full_type ):
259209 fwd_declarations [relation .namespace ].append (relation .bare_type )
@@ -265,7 +215,7 @@ def _preprocess_for_class(self, datatype):
265215 includes .add ('#include "podio/RelationRange.h"' )
266216
267217 for relation in datatype ["OneToManyRelations" ]:
268- if self ._is_interface (relation .full_type ):
218+ if self ._is_in (relation .full_type , "interfaces" ):
269219 relation .interface_types = self .datamodel .interfaces [relation .full_type ]["Types" ]
270220 if self ._needs_include (relation .full_type ):
271221 includes .add (self ._build_include (relation ))
@@ -335,7 +285,7 @@ def _preprocess_for_collection(self, datatype):
335285 for relation in datatype ["OneToManyRelations" ] + datatype ["OneToOneRelations" ]:
336286 if datatype ["class" ].bare_type != relation .bare_type :
337287 include_from = self ._needs_include (relation .full_type )
338- if self ._is_interface (relation .full_type ):
288+ if self ._is_in (relation .full_type , "interfaces" ):
339289 includes_cc .add (
340290 self ._build_include_for_class (relation .bare_type , include_from )
341291 )
@@ -405,8 +355,7 @@ def _pre_process_schema_evolution(self):
405355 )
406356 comparator .read ()
407357 comparator .compare ()
408- self .old_schema_version = f"v{ comparator .datamodel_old .schema_version } "
409- self .old_schema_version_int = comparator .datamodel_old .schema_version
358+ self .old_schema_version = comparator .datamodel_old .schema_version
410359 # some sanity checks
411360 if len (comparator .errors ) > 0 :
412361 print (
@@ -431,6 +380,65 @@ def _pre_process_schema_evolution(self):
431380 # add whatever is relevant to our ROOT schema evolution
432381 self .root_schema_dict .setdefault (item .klassname , []).append (item )
433382
383+ def _preprocess_schema_evolution_datatype (self , name , datatype ):
384+ """Preprocess this datatype (and generate the necessary code) in case
385+ schema evolution is necessary
386+
387+ NOTE: currently limited to support only ROOT schema evolution needs
388+ """
389+ schema_evolution_datatype = deepcopy (datatype )
390+ needs_schema_evolution = False
391+ for member in schema_evolution_datatype ["Members" ]:
392+ member_type = member .array_type if member .is_array else member .full_type
393+ if member_type in self .root_schema_dict :
394+ needs_schema_evolution = True
395+ replace_component_in_paths (
396+ member_type ,
397+ _versioned (member_type , self .old_schema_version ),
398+ schema_evolution_datatype ["includes_data" ],
399+ )
400+ if member .is_array :
401+ member .full_type = member .full_type .replace (
402+ member .array_type , _versioned (member .array_type , self .old_schema_version )
403+ )
404+ member .array_type = _versioned (member .array_type , self .old_schema_version )
405+ else :
406+ member .full_type = _versioned (member .full_type , self .old_schema_version )
407+ member .bare_type = _versioned (member .bare_type , self .old_schema_version )
408+
409+ if needs_schema_evolution :
410+ print (f" Preparing explicit schema evolution for { name } " )
411+ schema_evolution_datatype ["class" ].bare_type = _versioned (
412+ schema_evolution_datatype ["class" ].bare_type , self .old_schema_version
413+ )
414+ self ._fill_templates ("Data" , schema_evolution_datatype )
415+ self .root_schema_datatype_names .add (_versioned (name , self .old_schema_version ))
416+
417+ def _preprocess_schema_evolution_component (self , name , component ):
418+ """Preprocess this component (and generate the necessary code) in case
419+ schema evolution is necessary
420+
421+ NOTE: currently limited to support only ROOT schema evolution needs
422+ """
423+ try :
424+ schema_evolutions = self .root_schema_dict [name ]
425+ component = deepcopy (component )
426+ for schema_evolution in schema_evolutions :
427+ if isinstance (schema_evolution , RenamedMember ):
428+ for member in component ["Members" ]:
429+ if member .name == schema_evolution .member_name_new :
430+ member .name = schema_evolution .member_name_old
431+ component ["class" ] = DataType (_versioned (name , self .old_schema_version ))
432+ else :
433+ raise NotImplementedError
434+
435+ self ._fill_templates ("Component" , component )
436+ self .root_schema_component_names .add (_versioned (name , self .old_schema_version ))
437+
438+ except KeyError :
439+ # We didn't find any schema evolution for this component
440+ pass
441+
434442 def _invert_interfaces (self ):
435443 """'Invert' the interfaces to have a mapping of types and their usage in
436444 interfaces.
@@ -465,7 +473,7 @@ def _prepare_iorules(self):
465473 iorule = RootIoRule ()
466474 iorule .sourceClass = type_name
467475 iorule .targetClass = type_name
468- iorule .version = self .old_schema_version . lstrip ( "v" )
476+ iorule .version = self .old_schema_version
469477 iorule .source = f"{ member_type } { schema_change .member_name_old } "
470478 iorule .target = schema_change .member_name_new
471479 iorule .code = f"{ iorule .target } = onfile.{ schema_change .member_name_old } ;"
@@ -596,7 +604,7 @@ def _create_selection_xml(self):
596604 "old_schema_components" : [
597605 DataType (d )
598606 for d in self .root_schema_datatype_names | self .root_schema_component_names
599- ], # noqa
607+ ],
600608 "iorules" : self .root_schema_iorules ,
601609 }
602610
0 commit comments