2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const   std   =   @import ( " std " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const   pg   =   @import ( " pg " ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const   _database   =   @import ( " database.zig " ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const   _sql   =   @import ( " sql.zig " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const   repository   =   @import ( " repository.zig " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const   _query   =   @import ( " query.zig " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Configure a "one to many" or "many to many" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   const   ManyConfiguration   =   union ( enum )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Direct one-to-many relation using a distant foreign key.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 direct :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The distant foreign key name pointing to the current model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 foreignKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Current model key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the current model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 modelKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Used when performing a many-to-many relation through an association table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 through :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Name of the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 table :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The local foreign key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the current model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 foreignKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The foreign key name in the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 joinForeignKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The model key name in the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 joinModelKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Associated model key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the associated model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 modelKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Make a "one to many" or "many to many" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   fn   many ( comptime   fromRepo :   anytype ,   comptime   toRepo :   anytype ,   comptime   config :   ManyConfiguration )   type   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   typedMany ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 fromRepo . ModelType ,   fromRepo . TableType ,   fromRepo . config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 toRepo . ModelType ,   toRepo . TableType ,   toRepo . config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Internal implementation of a new "one to many" or "many to many" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   fn   typedMany ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   FromModel :   type ,   comptime   FromTable :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   fromRepositoryConfig :   repository . RepositoryConfiguration ( FromModel ,   FromTable ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   ToModel :   type ,   comptime   ToTable :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   toRepositoryConfig :   repository . RepositoryConfiguration ( ToModel ,   ToTable ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   config :   ManyConfiguration )   type   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Get foreign key from relation config or repository config.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   foreignKey   =   switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . direct   = >   | direct |   direct . foreignKey , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . through   = >   | through |   if   ( through . foreignKey )   | _foreignKey |   _foreignKey   else   toRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Get model key from relation config or repository config.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   modelKey   =   switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . direct   = >   | direct |   if   ( direct . modelKey )   | _modelKey |   _modelKey   else   fromRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . through   = >   | through |   if   ( through . modelKey )   | _modelKey |   _modelKey   else   fromRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   FromKeyType   =   std . meta . fields ( FromModel ) [ std . meta . fieldIndex ( FromModel ,   fromRepositoryConfig . key [ 0 ] ) . ? ] . type ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 const   QueryType   =   _query . RepositoryQuery ( ToModel ,   ToTable ,   toRepositoryConfig ,   null ,   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 __zrm_relation_key :   FromKeyType , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 const   Self   =   @This ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   getRepositoryConfiguration ( _ :   * anyopaque )   repository . RepositoryConfiguration ( ToModel ,   ToTable )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   toRepositoryConfig ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 fn   inlineMapping ( _ :   * anyopaque )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 22:36:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   genJoin ( _ :   * anyopaque ,   comptime   _ :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 unreachable ;   // No possible join in a many relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   _genSelect ( comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 22:36:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   _sql . SelectBuild ( ToTable ,   table ,   prefix ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   genSelect ( _ :   * anyopaque ,   comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   _genSelect ( table ,   prefix ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 fn   buildQuery ( _ :   * anyopaque ,   prefix :   [ ] const   u8 ,   opaqueModels :   [ ] const   * anyopaque ,   allocator :   std . mem . Allocator ,   connector :   _database . Connector )   ! * anyopaque   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   models :   [ ] const   * FromModel   =   @ptrCast ( @alignCast ( opaqueModels ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Initialize the query to build.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   query :   * QueryType   =   try   allocator . create ( QueryType ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 errdefer   allocator . destroy ( query ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 query . *   =   QueryType . init ( allocator ,   connector ,   . { } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 errdefer   query . deinit ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Build base SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   baseSelect   =   comptime   _genSelect ( toRepositoryConfig . table ,   " " ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Prepare given models IDs.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   modelsIds   =   try   query . arena . allocator ( ) . alloc ( FromKeyType ,   models . len ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   ( models ,   modelsIds )   | model ,   * modelId |   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 modelId . *   =   @field ( model ,   fromRepositoryConfig . key [ 0 ] ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . direct   = >   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 // Add SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 query . select ( . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . sql   =   baseSelect   + +   " ,  \" "   + +   toRepositoryConfig . table   + +   " \" . \" "   + +   foreignKey   + +   " \"  AS  \" __zrm_relation_key \" " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 // Build WHERE condition.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 try   query . whereIn ( FromKeyType ,   " \" "   + +   toRepositoryConfig . table   + +   " \" . \" "   + +   foreignKey   + +   " \" " ,   modelsIds ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . through   = >   | through |   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 // Add SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 query . select ( . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . sql   =   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   baseSelect   + +   " ,  \" {s}pivot "   + +   " \" . \" "   + +   through . joinForeignKey   + +   " \"  AS  \" __zrm_relation_key \" " ,   . { prefix } ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 query . join ( . { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 . sql   =   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   " INNER JOIN  \" "   + +   through . table   + +   " \"  ON AS  \" {s}pivot "   + +   " \"   "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " \" "   + +   toRepositoryConfig . table   + +   " \" . "   + +   modelKey   + +   "  =  "   + +   " \" {s}pivot "   + +   " \" . "   + +   through . joinModelKey ,   . { prefix ,   prefix } ) , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 // Build WHERE condition.
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 try   query . whereIn ( FromKeyType ,   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   " \" {s}pivot "   + +   " \" . \" "   + +   through . joinForeignKey   + +   " \" " ,   . { prefix } ) ,   modelsIds ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   query ;   // Return built query.
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pub   fn   relation ( self :   * Self )   Relation ( ToModel ,   ToTable )   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 return   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . _interface   =   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . instance   =   self , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 . getRepositoryConfiguration   =   getRepositoryConfiguration , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 . inlineMapping   =   inlineMapping , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . genJoin   =   genJoin , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . genSelect   =   genSelect , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 15:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 . QueryType   =   QueryType , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   runtimeRelation ( self :   * Self )   RuntimeRelation   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . _interface   =   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . instance   =   self , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 . buildQuery   =   buildQuery , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Configure a "one to one" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   const   OneConfiguration   =   union ( enum )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Direct one-to-one relation using a local foreign key.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 direct :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The local foreign key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 foreignKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Associated model key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the associated model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 modelKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Reverse one-to-one relation using distant foreign key.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 reverse :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The distant foreign key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 foreignKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Current model key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the current model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 modelKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Used when performing a one-to-one relation through an association table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 through :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Name of the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 table :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The local foreign key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the current model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 foreignKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The foreign key name in the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 joinForeignKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// The model key name in the join table.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 joinModelKey :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Associated model key name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Use the default key name of the associated model.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 modelKey :   ? [ ] const   u8   =   null , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Make a "one to one" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   fn   one ( comptime   fromRepo :   anytype ,   comptime   toRepo :   anytype ,   comptime   config :   OneConfiguration )   type   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   typedOne ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 fromRepo . ModelType ,   fromRepo . TableType ,   fromRepo . config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 toRepo . ModelType ,   toRepo . TableType ,   toRepo . config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 config , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Internal implementation of a new "one to one" relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								fn   typedOne ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   FromModel :   type ,   comptime   FromTable :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   fromRepositoryConfig :   repository . RepositoryConfiguration ( FromModel ,   FromTable ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   ToModel :   type ,   comptime   ToTable :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   toRepositoryConfig :   repository . RepositoryConfiguration ( ToModel ,   ToTable ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 comptime   config :   OneConfiguration )   type   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   FromKeyType   =   std . meta . fields ( FromModel ) [ std . meta . fieldIndex ( FromModel ,   fromRepositoryConfig . key [ 0 ] ) . ? ] . type ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 const   QueryType   =   _query . RepositoryQuery ( ToModel ,   ToTable ,   toRepositoryConfig ,   null ,   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 __zrm_relation_key :   FromKeyType , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Get foreign key from relation config or repository config.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   foreignKey   =   switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . direct   = >   | direct |   direct . foreignKey , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . reverse   = >   | reverse |   reverse . foreignKey , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . through   = >   | through |   if   ( through . foreignKey )   | _foreignKey |   _foreignKey   else   fromRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Get model key from relation config or repository config.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   modelKey   =   switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . direct   = >   | direct |   if   ( direct . modelKey )   | _modelKey |   _modelKey   else   toRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . reverse   = >   | reverse |   if   ( reverse . modelKey )   | _modelKey |   _modelKey   else   toRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 . through   = >   | through |   if   ( through . modelKey )   | _modelKey |   _modelKey   else   toRepositoryConfig . key [ 0 ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 const   Self   =   @This ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   getRepositoryConfiguration ( _ :   * anyopaque )   repository . RepositoryConfiguration ( ToModel ,   ToTable )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   toRepositoryConfig ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 fn   inlineMapping ( _ :   * anyopaque )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 22:36:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   genJoin ( _ :   * anyopaque ,   comptime   alias :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 return   switch   ( config )   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 22:36:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 . direct   = >   ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " LEFT JOIN  \" "   + +   toRepositoryConfig . table   + +   " \"  AS  \" "   + +   alias   + +   " \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 " \" "   + +   fromRepositoryConfig . table   + +   " \" . "   + +   foreignKey   + +   "  =  \" "   + +   alias   + +   " \" . "   + +   modelKey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . reverse   = >   ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " LEFT JOIN  \" "   + +   toRepositoryConfig . table   + +   " \"  AS  \" "   + +   alias   + +   " \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 " \" "   + +   fromRepositoryConfig . table   + +   " \" . "   + +   modelKey   + +   "  =  \" "   + +   alias   + +   " \" . "   + +   foreignKey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . through   = >   | through |   ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " LEFT JOIN  \" "   + +   through . table   + +   " \"  AS  \" "   + +   alias   + +   " _pivot \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 " \" "   + +   fromRepositoryConfig . table   + +   " \" . "   + +   foreignKey   + +   "  =  "   + +   " \" "   + +   alias   + +   " _pivot \" . "   + +   through . joinForeignKey   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " LEFT JOIN  \" "   + +   toRepositoryConfig . table   + +   " \"  AS  \" "   + +   alias   + +   " \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 " \" "   + +   alias   + +   " _pivot \" . "   + +   through . joinModelKey   + +   "  =  "   + +   " \" "   + +   alias   + +   " \" . "   + +   modelKey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 ) , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   _genSelect ( comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 22:36:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   _sql . SelectBuild ( ToTable ,   table ,   prefix ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 fn   genSelect ( _ :   * anyopaque ,   comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   _genSelect ( table ,   prefix ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 fn   buildQuery ( _ :   * anyopaque ,   prefix :   [ ] const   u8 ,   opaqueModels :   [ ] const   * anyopaque ,   allocator :   std . mem . Allocator ,   connector :   _database . Connector )   ! * anyopaque   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   models :   [ ] const   * FromModel   =   @ptrCast ( @alignCast ( opaqueModels ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Initialize the query to build.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   query :   * QueryType   =   try   allocator . create ( QueryType ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 errdefer   allocator . destroy ( query ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 query . *   =   QueryType . init ( allocator ,   connector ,   . { } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 errdefer   query . deinit ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Build base SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   baseSelect   =   comptime   _genSelect ( toRepositoryConfig . table ,   " " ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Prepare given models IDs.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 const   modelsIds   =   try   query . arena . allocator ( ) . alloc ( FromKeyType ,   models . len ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   ( models ,   modelsIds )   | model ,   * modelId |   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 modelId . *   =   @field ( model ,   fromRepositoryConfig . key [ 0 ] ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 switch   ( config )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . direct   = >   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 // Add SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 query . select ( . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . sql   =   baseSelect   + +   " ,  \" "   + +   fromRepositoryConfig . table   + +   " \" . \" "   + +   fromRepositoryConfig . key [ 0 ]   + +   " \"  AS  \" __zrm_relation_key \" " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 query . join ( ( _sql . RawQuery { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 . sql   =   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   " INNER JOIN  \" "   + +   fromRepositoryConfig . table   + +   " \"  AS  \" {s}related "   + +   " \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " \" "   + +   toRepositoryConfig . table   + +   " \" . "   + +   modelKey   + +   "  =  \" {s}related "   + +   " \" . "   + +   foreignKey ,   . { prefix ,   prefix } ) , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 // Build WHERE condition.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 try   query . whereIn ( FromKeyType ,   " \" "   + +   fromRepositoryConfig . table   + +   " \" . \" "   + +   fromRepositoryConfig . key [ 0 ]   + +   " \" " ,   modelsIds ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . reverse   = >   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 // Add SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 query . select ( . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . sql   =   baseSelect   + +   " ,  \" "   + +   toRepositoryConfig . table   + +   " \" . \" "   + +   foreignKey   + +   " \"  AS  \" __zrm_relation_key \" " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 // Build WHERE condition.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 try   query . whereIn ( FromKeyType ,   " \" "   + +   toRepositoryConfig . table   + +   " \" . \" "   + +   foreignKey   + +   " \" " ,   modelsIds ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . through   = >   | through |   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 // Add SELECT.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 query . select ( . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . sql   =   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   baseSelect   + +   " ,  \" {s}pivot "   + +   " \" . \" "   + +   through . joinForeignKey   + +   " \"  AS  \" __zrm_relation_key \" " ,   . { prefix } ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 query . join ( . { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 . sql   =   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   " INNER JOIN  \" "   + +   through . table   + +   " \"  AS  \" {s}pivot "   + +   " \"  ON  "   + + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " \" "   + +   toRepositoryConfig . table   + +   " \" . "   + +   modelKey   + +   "  =  "   + +   " \" {s}pivot "   + +   " \" . "   + +   through . joinModelKey ,   . { prefix ,   prefix } ) , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														 . params   =   & [ 0 ] _sql . RawQueryParameter { } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 // Build WHERE condition.
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 try   query . whereIn ( FromKeyType ,   try   std . fmt . allocPrint ( query . arena . allocator ( ) ,   " \" {s}pivot "   + +   " \" . \" "   + +   through . joinForeignKey   + +   " \" " ,   . { prefix } ) ,   modelsIds ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Return built query.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   query ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pub   fn   relation ( self :   * Self )   Relation ( ToModel ,   ToTable )   { 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											 return   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . _interface   =   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . instance   =   self , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 . getRepositoryConfiguration   =   getRepositoryConfiguration , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 . inlineMapping   =   inlineMapping , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . genJoin   =   genJoin , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . genSelect   =   genSelect , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 15:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 . QueryType   =   QueryType , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   runtimeRelation ( self :   * Self )   RuntimeRelation   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 . _interface   =   . { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 . instance   =   self , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													 . buildQuery   =   buildQuery , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Generic model relation interface.
  
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								pub   fn   Relation ( comptime   ToModel :   type ,   comptime   ToTable :   type )   type   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 const   Self   =   @This ( ) ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pub   const   Model   =   ToModel ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   const   TableShape   =   ToTable ; 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 _interface :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 instance :   * anyopaque , 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 getRepositoryConfiguration :   * const   fn   ( self :   * anyopaque )   repository . RepositoryConfiguration ( ToModel ,   ToTable ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 inlineMapping :   * const   fn   ( self :   * anyopaque )   bool , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 genJoin :   * const   fn   ( self :   * anyopaque ,   comptime   alias :   [ ] const   u8 )   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 genSelect :   * const   fn   ( self :   * anyopaque ,   comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 15:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 QueryType :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-24 01:53:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 /// Read the related model repository configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   getRepositoryConfiguration ( self :   Self )   repository . RepositoryConfiguration ( ToModel ,   ToTable )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   self . _interface . getRepositoryConfiguration ( self . _interface . instance ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Relation mapping is done inline: this means that it's done at the same time the model is mapped,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// and that the associated data will be retrieved in the main query.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   inlineMapping ( self :   Self )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   self . _interface . inlineMapping ( self . _interface . instance ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// In case of inline mapping, generate a JOIN clause to retrieve the associated data.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   genJoin ( self :   Self ,   comptime   alias :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   self . _interface . genJoin ( self . _interface . instance ,   alias ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 /// Generate a SELECT clause to retrieve the associated data, with the given table and prefix.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pub   fn   genSelect ( self :   Self ,   comptime   table :   [ ] const   u8 ,   comptime   prefix :   [ ] const   u8 )   [ ] const   u8   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   self . _interface . genSelect ( self . _interface . instance ,   table ,   prefix ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-25 13:02:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/// Generic model runtime relation interface.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   const   RuntimeRelation   =   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 const   Self   =   @This ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 _interface :   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 instance :   * anyopaque , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 buildQuery :   * const   fn   ( self :   * anyopaque ,   prefix :   [ ] const   u8 ,   models :   [ ] const   * anyopaque ,   allocator :   std . mem . Allocator ,   connector :   _database . Connector )   anyerror ! * anyopaque , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Build the query to retrieve relation data.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Is always used when inline mapping is not possible, but also when loading relations lazily.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 pub   fn   buildQuery ( self :   Self ,   prefix :   [ ] const   u8 ,   models :   [ ] const   * anyopaque ,   allocator :   std . mem . Allocator ,   connector :   _database . Connector )   ! * anyopaque   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   self . _interface . buildQuery ( self . _interface . instance ,   prefix ,   models ,   allocator ,   connector ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 15:40:10 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// A model relation object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   const   ModelRelation   =   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 relation :   type , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 field :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/// Structure of an eager loaded relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								pub   const   Eager   =   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Model field to fill for the relation.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 field :   [ ] const   u8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// The relation to eager load.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 relation :   Relation , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /// Subrelations to eager load.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 with :   [ ] const   Eager , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;