@@ -77,30 +77,44 @@ def _parse_php_array(self, content: str) -> Dict:
7777 """
7878 relations = {}
7979
80- # Split by table entries (looking for 'table_name' => [)
81- table_entries = re .findall (
82- r"'([^']+)'\s*=>\s*\[(.*?)(?=\n\s*'[^']+'\s*=>\s*\[|\n\s*\],?\s*$)" ,
83- content ,
84- re .DOTALL
85- )
86-
87- for table_name , table_relations in table_entries :
88- relations [table_name ] = self ._parse_table_relations (
80+ # Find all top-level keys in the array
81+ key_iter = re .finditer (r"'([^']+)'\s*=>\s*\[" , content )
82+ for m in key_iter :
83+ key_name = m .group (1 )
84+
85+ # Check nesting level to ensure it's a top-level array
86+ prefix = content [:m .start ()]
87+ nesting = prefix .count ('[' ) - prefix .count (']' )
88+ if nesting != 0 :
89+ # This is an inner array (nested). Skip it for top-level
90+ # table extraction.
91+ continue
92+
93+ # Find matching closing bracket for this '[' starting at m.end()-1
94+ start_idx = content .find ('[' , m .start ())
95+ if start_idx == - 1 :
96+ continue
97+
98+ depth = 0
99+ end_idx = None
100+ for i in range (start_idx , len (content )):
101+ ch = content [i ]
102+ if ch == '[' :
103+ depth += 1
104+ elif ch == ']' :
105+ depth -= 1
106+ if depth == 0 :
107+ end_idx = i
108+ break
109+
110+ if end_idx is None :
111+ # Unbalanced brackets — skip this key
112+ continue
113+
114+ table_relations = content [start_idx + 1 :end_idx ]
115+ relations [key_name ] = self ._parse_table_relations (
89116 table_relations )
90117
91- # If no matches found, try a simpler approach
92- if not table_entries :
93- # Look for individual table entries
94- table_entries = re .findall (
95- r"'([^']+)'\s*=>\s*\[(.*?)\]," ,
96- content ,
97- re .DOTALL
98- )
99-
100- for table_name , table_relations in table_entries :
101- relations [table_name ] = self ._parse_table_relations (
102- table_relations )
103-
104118 return relations
105119
106120 def _parse_table_relations (self , table_relations : str ) -> List [Dict ]:
@@ -196,26 +210,30 @@ def get_dbml_relations(self) -> List[Dict]:
196210 continue
197211
198212 # For simple foreign key relations, create DBML ref
199- # The target table is the one with the foreign key, source is
200- # the referenced table (corrected logic)
213+ # We want the DBML `Ref` to have the table containing the
214+ # foreign key on the left and the referenced table (usually
215+ # with primary key `id`) on the right. In our parsed structure
216+ # `source_table` is the outer key from the PHP array (the
217+ # referenced table) and `target_table` is the inner key (the
218+ # table that contains the foreign key columns). To produce
219+ # DBML like `appliances.users_id > users.id` we set the
220+ # left-hand side (source_table) to the table with the FK.
201221 if len (foreign_keys ) == 1 :
202222 dbml_relations .append ({
203- 'source_table' : source_table , # Referenced table
204- 'target_table' : target_table , # Table with foreign key
205- 'source_column' : 'id' , # Primary key of referenced table
206- 'target_column' : foreign_keys [ 0 ] , # Foreign key column
223+ 'source_table' : target_table , # Table with foreign key
224+ 'target_table' : source_table , # Referenced table
225+ 'source_column' : foreign_keys [ 0 ] , # Foreign key column
226+ 'target_column' : 'id' , # PK of referenced table
207227 'relation_type' : '1:n' # One-to-many relationship
208228 })
209229 elif len (foreign_keys ) == 2 :
210- # Handle composite foreign keys (like many-to-many relations)
211- # This is a simplified approach - in reality, these might
212- # be more complex
230+ # Handle composite foreign keys (simplified)
213231 dbml_relations .append ({
214- 'source_table' : source_table , # Referenced table
215- 'target_table' : target_table , # Table with foreign keys
216- # Assuming both point to id columns
217- 'source_columns' : [ 'id' , 'id' ],
218- 'target_columns' : foreign_keys , # Foreign key columns
232+ 'source_table' : target_table , # Table with foreign keys
233+ 'target_table' : source_table , # Referenced table
234+ # Assuming both reference id on referenced table
235+ 'source_columns' : foreign_keys , # Foreign key columns
236+ 'target_columns' : [ 'id' , 'id' ],
219237 'relation_type' : 'm:n'
220238 })
221239
0 commit comments