github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/drivers/relationships.go (about)

     1  package drivers
     2  
     3  // ToOneRelationship describes a relationship between two tables where the local
     4  // table has no id, and the foreign table has an id that matches a column in the
     5  // local table, that column can also be unique which changes the dynamic into a
     6  // one-to-one style, not a to-many.
     7  type ToOneRelationship struct {
     8  	Name string `json:"name"`
     9  
    10  	Table    string `json:"table"`
    11  	Column   string `json:"column"`
    12  	Nullable bool   `json:"nullable"`
    13  	Unique   bool   `json:"unique"`
    14  
    15  	ForeignTable          string `json:"foreign_table"`
    16  	ForeignColumn         string `json:"foreign_column"`
    17  	ForeignColumnNullable bool   `json:"foreign_column_nullable"`
    18  	ForeignColumnUnique   bool   `json:"foreign_column_unique"`
    19  }
    20  
    21  // ToManyRelationship describes a relationship between two tables where the
    22  // local table has no id, and the foreign table has an id that matches a column
    23  // in the local table.
    24  type ToManyRelationship struct {
    25  	Name string `json:"name"`
    26  
    27  	Table    string `json:"table"`
    28  	Column   string `json:"column"`
    29  	Nullable bool   `json:"nullable"`
    30  	Unique   bool   `json:"unique"`
    31  
    32  	ForeignTable          string `json:"foreign_table"`
    33  	ForeignColumn         string `json:"foreign_column"`
    34  	ForeignColumnNullable bool   `json:"foreign_column_nullable"`
    35  	ForeignColumnUnique   bool   `json:"foreign_column_unique"`
    36  
    37  	ToJoinTable bool   `json:"to_join_table"`
    38  	JoinTable   string `json:"join_table"`
    39  
    40  	JoinLocalFKeyName       string `json:"join_local_fkey_name"`
    41  	JoinLocalColumn         string `json:"join_local_column"`
    42  	JoinLocalColumnNullable bool   `json:"join_local_column_nullable"`
    43  	JoinLocalColumnUnique   bool   `json:"join_local_column_unique"`
    44  
    45  	JoinForeignFKeyName       string `json:"join_foreign_fkey_name"`
    46  	JoinForeignColumn         string `json:"join_foreign_column"`
    47  	JoinForeignColumnNullable bool   `json:"join_foreign_column_nullable"`
    48  	JoinForeignColumnUnique   bool   `json:"join_foreign_column_unique"`
    49  }
    50  
    51  // ToOneRelationships relationship lookups
    52  // Input should be the sql name of a table like: videos
    53  func ToOneRelationships(table string, tables []Table) []ToOneRelationship {
    54  	localTable := GetTable(tables, table)
    55  	return toOneRelationships(localTable, tables)
    56  }
    57  
    58  // ToManyRelationships relationship lookups
    59  // Input should be the sql name of a table like: videos
    60  func ToManyRelationships(table string, tables []Table) []ToManyRelationship {
    61  	localTable := GetTable(tables, table)
    62  	return toManyRelationships(localTable, tables)
    63  }
    64  
    65  func toOneRelationships(table Table, tables []Table) []ToOneRelationship {
    66  	var relationships []ToOneRelationship
    67  
    68  	for _, t := range tables {
    69  		for _, f := range t.FKeys {
    70  			if f.ForeignTable == table.Name && !t.IsJoinTable && f.Unique {
    71  				relationships = append(relationships, buildToOneRelationship(table, f, t, tables))
    72  			}
    73  
    74  		}
    75  	}
    76  
    77  	return relationships
    78  }
    79  
    80  func toManyRelationships(table Table, tables []Table) []ToManyRelationship {
    81  	var relationships []ToManyRelationship
    82  
    83  	for _, t := range tables {
    84  		for _, f := range t.FKeys {
    85  			if f.ForeignTable == table.Name && (t.IsJoinTable || !f.Unique) {
    86  				relationships = append(relationships, buildToManyRelationship(table, f, t, tables))
    87  			}
    88  		}
    89  	}
    90  
    91  	return relationships
    92  }
    93  
    94  func buildToOneRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToOneRelationship {
    95  	return ToOneRelationship{
    96  		Name:     foreignKey.Name,
    97  		Table:    localTable.Name,
    98  		Column:   foreignKey.ForeignColumn,
    99  		Nullable: foreignKey.ForeignColumnNullable,
   100  		Unique:   foreignKey.ForeignColumnUnique,
   101  
   102  		ForeignTable:          foreignTable.Name,
   103  		ForeignColumn:         foreignKey.Column,
   104  		ForeignColumnNullable: foreignKey.Nullable,
   105  		ForeignColumnUnique:   foreignKey.Unique,
   106  	}
   107  }
   108  
   109  func buildToManyRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToManyRelationship {
   110  	if !foreignTable.IsJoinTable {
   111  		return ToManyRelationship{
   112  			Name:                  foreignKey.Name,
   113  			Table:                 localTable.Name,
   114  			Column:                foreignKey.ForeignColumn,
   115  			Nullable:              foreignKey.ForeignColumnNullable,
   116  			Unique:                foreignKey.ForeignColumnUnique,
   117  			ForeignTable:          foreignTable.Name,
   118  			ForeignColumn:         foreignKey.Column,
   119  			ForeignColumnNullable: foreignKey.Nullable,
   120  			ForeignColumnUnique:   foreignKey.Unique,
   121  			ToJoinTable:           false,
   122  		}
   123  	}
   124  
   125  	relationship := ToManyRelationship{
   126  		Table:    localTable.Name,
   127  		Column:   foreignKey.ForeignColumn,
   128  		Nullable: foreignKey.ForeignColumnNullable,
   129  		Unique:   foreignKey.ForeignColumnUnique,
   130  
   131  		ToJoinTable: true,
   132  		JoinTable:   foreignTable.Name,
   133  
   134  		JoinLocalFKeyName:       foreignKey.Name,
   135  		JoinLocalColumn:         foreignKey.Column,
   136  		JoinLocalColumnNullable: foreignKey.Nullable,
   137  		JoinLocalColumnUnique:   foreignKey.Unique,
   138  	}
   139  
   140  	for _, fk := range foreignTable.FKeys {
   141  		if fk.Name == foreignKey.Name {
   142  			continue
   143  		}
   144  
   145  		relationship.JoinForeignFKeyName = fk.Name
   146  		relationship.JoinForeignColumn = fk.Column
   147  		relationship.JoinForeignColumnNullable = fk.Nullable
   148  		relationship.JoinForeignColumnUnique = fk.Unique
   149  
   150  		relationship.ForeignTable = fk.ForeignTable
   151  		relationship.ForeignColumn = fk.ForeignColumn
   152  		relationship.ForeignColumnNullable = fk.ForeignColumnNullable
   153  		relationship.ForeignColumnUnique = fk.ForeignColumnUnique
   154  	}
   155  
   156  	return relationship
   157  }