11import  type  {  ZModelServices  }  from  '@zenstackhq/language' 
22import  type  { 
3+     ArrayExpr , 
34    Attribute , 
45    AttributeArg , 
56    DataField , 
@@ -9,18 +10,20 @@ import type {
910    Enum , 
1011    EnumField , 
1112    Model , 
13+     ReferenceExpr , 
14+     StringLiteral , 
1215    UnsupportedFieldType 
1316}  from  '@zenstackhq/language/ast' 
17+ import  {  getStringLiteral  }  from  '@zenstackhq/language/utils' 
1418import  type  {  IntrospectedEnum ,  IntrospectedTable ,  IntrospectionProvider  }  from  './provider' 
15- import  {  getAttributeRef ,  getDbName  }  from  './utils' 
19+ import  {  getAttributeRef ,  getDbName ,   getEnumRef ,   getModelRef  }  from  './utils' 
1620
17- export  function  syncEnums ( dbEnums :  IntrospectedEnum [ ] ,  model : Model )  { 
21+ export  function  syncEnums ( {   dbEnums,  model ,  services  } :  {   dbEnums :  IntrospectedEnum [ ] ,  model : Model ,   services :  ZModelServices   } )  { 
1822    for  ( const  dbEnum  of  dbEnums )  { 
19-         let  schemaEnum  =  model . declarations . find ( 
20-             ( d )  =>  d . $type  ===  'Enum'  &&  getDbName ( d )  ===  dbEnum . enum_type 
21-         )  as  Enum  |  undefined 
23+         let  schemaEnum  =  getEnumRef ( dbEnum . enum_type ,  services ) ; 
2224
2325        if  ( ! schemaEnum )  { 
26+             console . log ( `Adding enum for type ${ dbEnum . enum_type }  ) ; 
2427            schemaEnum  =  { 
2528                $type : 'Enum'  as  const , 
2629                $container : model , 
@@ -66,17 +69,29 @@ export function syncTable({
6669    model, 
6770    provider, 
6871    table, 
72+     services
6973} : { 
7074    table : IntrospectedTable 
7175    model : Model 
7276    provider : IntrospectionProvider 
77+     services : ZModelServices 
7378} )  { 
79+     const  idAttribute  =  getAttributeRef ( '@id' ,  services ) 
80+     const  uniqueAttribute  =  getAttributeRef ( '@unique' ,  services ) 
81+     const  relationAttribute  =  getAttributeRef ( '@relation' ,  services ) 
82+     const  fieldMapAttribute  =  getAttributeRef ( '@map' ,  services ) 
83+     const  tableMapAttribute  =  getAttributeRef ( '@@map' ,  services ) 
84+ 
85+     if  ( ! idAttribute  ||  ! uniqueAttribute  ||  ! relationAttribute  ||  ! fieldMapAttribute  ||  ! tableMapAttribute )  { 
86+         throw  new  Error ( 'Cannot find required attributes in the model.' ) 
87+     } 
88+ 
7489    const  relations : Relation [ ]  =  [ ] 
75-     let  modelTable  =  model . declarations . find ( 
76-         ( d )  =>  d . $type  ===  'DataModel'  &&  getDbName ( d )  ===  table . name 
77-     )  as  DataModel  |  undefined 
90+     let  modelTable  =  getModelRef ( table . name ,  services ) 
7891
7992    if  ( ! modelTable )  { 
93+         console . log ( `Adding model for table ${ table . name }  ) ; 
94+ 
8095        modelTable  =  { 
8196            $type : 'DataModel'  as  const , 
8297            $container : model , 
@@ -96,7 +111,7 @@ export function syncTable({
96111                schema : table . schema , 
97112                table : table . name , 
98113                column : col . name , 
99-                 type : col . unique  ?  'one'   :  'many ', 
114+                 type : 'one' , 
100115                fk_name : col . foreign_key_name ! , 
101116                nullable : col . nullable , 
102117                references : { 
@@ -115,85 +130,68 @@ export function syncTable({
115130        ) 
116131        if  ( ! existingField )  { 
117132            const  builtinType  =  provider . getBuiltinType ( col . datatype ) 
118-             const  unsupported : UnsupportedFieldType  =  { 
119-                 get  $container ( )  { 
120-                     return  type 
121-                 } , 
122-                 $type : 'UnsupportedFieldType'  as  const , 
123-                 value : { 
124-                     get  $container ( )  { 
125-                         return  unsupported 
126-                     } , 
127-                     $type : 'StringLiteral' , 
128-                     value : col . datatype , 
129-                 } , 
130-             } 
131- 
132-             const  type : DataFieldType  =  { 
133-                 get  $container ( )  { 
134-                     return  field 
135-                 } , 
136-                 $type : 'DataFieldType'  as  const , 
137-                 type : builtinType . type  ===  'Unsupported'  ? undefined  : builtinType . type , 
138-                 array : builtinType . isArray , 
139-                 unsupported :
140-                     builtinType . type  ===  'Unsupported'  ? unsupported  : undefined , 
141-                 optional : col . nullable , 
142-                 reference : col . options . length 
143-                     ? { 
133+             const  field : DataField  =  { 
134+                 $type : 'DataField'  as  const , 
135+                 get  type ( )  { 
136+                     return  { 
137+                         $container : this , 
138+                         $type : 'DataFieldType'  as  const , 
139+                         type : builtinType . type  ===  'Unsupported'  ? undefined  : builtinType . type , 
140+                         array : builtinType . isArray , 
141+                         get  unsupported ( )  { 
142+                             return  builtinType . type  ===  'Unsupported'  ? { 
143+                                 $container : this , 
144+                                 $type : 'UnsupportedFieldType'  as  const , 
145+                                 get  value ( )  { 
146+                                     return  { 
147+                                         $container : this , 
148+                                         $type : 'StringLiteral' , 
149+                                         value : col . datatype , 
150+                                     }  satisfies  StringLiteral 
151+                                 } , 
152+                             }  satisfies  UnsupportedFieldType  : undefined 
153+                         } , 
154+                         optional : col . nullable , 
155+                         reference : col . options . length 
156+                             ? { 
144157                        $refText : col . datatype , 
145158                        ref : model . declarations . find ( 
146159                            ( d )  =>  d . $type  ===  'Enum'  &&  getDbName ( d )  ===  col . datatype 
147-                         )  as  Enum  |  undefined , 
148-                     } 
149-                     : undefined , 
150-             } 
151- 
152-             const  field : DataField  =  { 
153-                 $type : 'DataField'  as  const , 
154-                 type, 
160+                                 )  as  Enum  |  undefined , 
161+                             } 
162+                             : undefined , 
163+                     }  satisfies  DataFieldType 
164+                 } , 
155165                $container : modelTable ! , 
156166                name : fieldName , 
157167                get  attributes ( )  { 
158168                    if  ( fieldPrefix  !==  '' )  return  [ ] 
159169
160-                     const   attr :  DataFieldAttribute   =   { 
170+                     return   [ { 
161171                        $type : 'DataFieldAttribute'  as  const , 
162-                         get  $container ( )  { 
163-                             return  field 
164-                         } , 
172+                         $container : this , 
165173                        decl : { 
166174                            $refText : '@map' , 
167-                             ref : model . $document ?. references . find ( 
168-                                 ( r )  => 
169-                                     //@ts -ignore 
170-                                     r . ref . $type  ===  'Attribute'  &&  r . ref . name  ===  '@map' 
171-                             ) ?. ref  as  Attribute , 
175+                             ref : fieldMapAttribute , 
172176                        } , 
173177                        get  args ( )  { 
174-                             const   arg :  AttributeArg   =   { 
178+                             return   [ { 
175179                                $type : 'AttributeArg'  as  const , 
176-                                 get  $container ( )  { 
177-                                     return  attr 
178-                                 } , 
180+                                 $container : this , 
179181                                name : 'name' , 
180182                                $resolvedParam : { 
181183                                    name : 'name' , 
182184                                } , 
183185                                get  value ( )  { 
184186                                    return  { 
185187                                        $type : 'StringLiteral'  as  const , 
186-                                         $container : arg , 
188+                                         $container : this , 
187189                                        value : col . name , 
188190                                    } 
189191                                } , 
190-                             } 
191- 
192-                             return  [ arg ] 
192+                             } ]  satisfies  AttributeArg [ ] 
193193                        } , 
194-                     } 
195- 
196-                     return  [ attr ] 
194+                     } ]  satisfies  DataFieldAttribute [ ] 
197195                } , 
198196                comments : [ ] , 
199197            } 
@@ -205,10 +203,16 @@ export function syncTable({
205203    return  relations 
206204} 
207205
208- export  function  syncRelation ( model :  Model ,  relation : Relation ,  services : ZModelServices )  { 
206+ export  function  syncRelation ( {   model,  relation ,  services  } :  {   model :  Model ,  relation : Relation ,  services : ZModelServices   } )  { 
209207    const  idAttribute  =  getAttributeRef ( '@id' ,  services ) 
210208    const  uniqueAttribute  =  getAttributeRef ( '@unique' ,  services ) 
211209    const  relationAttribute  =  getAttributeRef ( '@relation' ,  services ) 
210+     const  fieldMapAttribute  =  getAttributeRef ( '@map' ,  services ) 
211+     const  tableMapAttribute  =  getAttributeRef ( '@@map' ,  services ) 
212+ 
213+     if  ( ! idAttribute  ||  ! uniqueAttribute  ||  ! relationAttribute  ||  ! fieldMapAttribute  ||  ! tableMapAttribute )  { 
214+         throw  new  Error ( 'Cannot find required attributes in the model.' ) 
215+     } 
212216
213217    if  ( ! idAttribute  ||  ! uniqueAttribute  ||  ! relationAttribute )  { 
214218        throw  new  Error ( 'Cannot find required attributes in the model.' ) 
0 commit comments