1+ //! Functions and types for conveniently traversing and querying a SqlSchema.
2+
3+ #![ deny( missing_docs) ]
4+
15use crate :: {
26 Column , ColumnArity , ColumnType , ColumnTypeFamily , DefaultValue , Enum , ForeignKey , Index , IndexType , PrimaryKey ,
37 SqlSchema , Table ,
48} ;
59
10+ /// Traverse all the columns in the schema.
611pub fn walk_columns < ' a > ( schema : & ' a SqlSchema ) -> impl Iterator < Item = ColumnWalker < ' a > > + ' a {
712 schema. tables . iter ( ) . flat_map ( move |table| {
813 table
@@ -12,6 +17,7 @@ pub fn walk_columns<'a>(schema: &'a SqlSchema) -> impl Iterator<Item = ColumnWal
1217 } )
1318}
1419
20+ /// Find a column by table and column name in the schema.
1521pub fn find_column < ' a > ( schema : & ' a SqlSchema , table_name : & str , column_name : & str ) -> Option < ColumnWalker < ' a > > {
1622 schema
1723 . tables
@@ -26,22 +32,29 @@ pub fn find_column<'a>(schema: &'a SqlSchema, table_name: &str, column_name: &st
2632 } )
2733}
2834
35+ /// Traverse a table column.
2936#[ derive( Debug , Clone , Copy ) ]
3037pub struct ColumnWalker < ' a > {
38+ /// The schema the column is contained in. This field will become private.
3139 pub schema : & ' a SqlSchema ,
40+ /// The underlying column struct. This field will become private.
3241 pub column : & ' a Column ,
42+ /// The underlying table struct. This field will become private.
3343 pub table : & ' a Table ,
3444}
3545
3646impl < ' a > ColumnWalker < ' a > {
47+ /// The nullability and arity of the column.
3748 pub fn arity ( & self ) -> & ColumnArity {
3849 & self . column . tpe . arity
3950 }
4051
52+ /// The type family.
4153 pub fn column_type_family ( & self ) -> & ' a ColumnTypeFamily {
4254 & self . column . tpe . family
4355 }
4456
57+ /// Extract an `Enum` column type family, or `None` if the family is something else.
4558 pub fn column_type_family_as_enum ( & self ) -> Option < & ' a Enum > {
4659 self . column_type_family ( ) . as_enum ( ) . map ( |enum_name| {
4760 self . schema ( )
@@ -51,22 +64,27 @@ impl<'a> ColumnWalker<'a> {
5164 } )
5265 }
5366
67+ /// The column name.
5468 pub fn name ( & self ) -> & ' a str {
5569 & self . column . name
5670 }
5771
72+ /// The default value for the column.
5873 pub fn default ( & self ) -> Option < & ' a DefaultValue > {
5974 self . column . default . as_ref ( )
6075 }
6176
77+ /// The full column type.
6278 pub fn column_type ( & self ) -> & ' a ColumnType {
6379 & self . column . tpe
6480 }
6581
82+ /// Is this column an auto-incrementing integer?
6683 pub fn is_autoincrement ( & self ) -> bool {
6784 self . column . auto_increment
6885 }
6986
87+ /// Returns whether two columns are named the same and belong to the same table.
7088 pub fn is_same_column ( & self , other : & ColumnWalker < ' _ > ) -> bool {
7189 self . name ( ) == other. name ( ) && self . table ( ) . name ( ) == other. table ( ) . name ( )
7290 }
@@ -79,33 +97,41 @@ impl<'a> ColumnWalker<'a> {
7997 . unwrap_or ( false )
8098 }
8199
100+ /// Traverse to the column's table.
82101 pub fn table ( & self ) -> TableWalker < ' a > {
83102 TableWalker {
84103 schema : self . schema ,
85104 table : self . table ,
86105 }
87106 }
88107
108+ /// Get a reference to the SQL schema the column is part of.
89109 pub fn schema ( & self ) -> & ' a SqlSchema {
90110 self . schema
91111 }
92112}
93113
114+ /// Traverse a table.
94115#[ derive( Clone , Copy ) ]
95116pub struct TableWalker < ' a > {
117+ /// The schema the column is contained in. This field will become private.
96118 pub schema : & ' a SqlSchema ,
119+ /// The underlying table struct. This field will become private.
97120 pub table : & ' a Table ,
98121}
99122
100123impl < ' a > TableWalker < ' a > {
124+ /// Create a TableWalker from a schema and a reference to one of its tables.
101125 pub fn new ( schema : & ' a SqlSchema , table : & ' a Table ) -> Self {
102126 Self { schema, table }
103127 }
104128
129+ /// Get a column in the table, by name.
105130 pub fn column ( & self , column_name : & str ) -> Option < ColumnWalker < ' a > > {
106131 self . columns ( ) . find ( |column| column. name ( ) == column_name)
107132 }
108133
134+ /// Traverse the table's columns.
109135 pub fn columns < ' b > ( & ' b self ) -> impl Iterator < Item = ColumnWalker < ' a > > + ' b {
110136 self . table . columns . iter ( ) . map ( move |column| ColumnWalker {
111137 column,
@@ -114,6 +140,7 @@ impl<'a> TableWalker<'a> {
114140 } )
115141 }
116142
143+ /// Traverse the indexes on the table.
117144 pub fn indexes < ' b > ( & ' b self ) -> impl Iterator < Item = IndexWalker < ' a > > + ' b {
118145 self . table . indices . iter ( ) . map ( move |index| IndexWalker {
119146 index,
@@ -122,54 +149,65 @@ impl<'a> TableWalker<'a> {
122149 } )
123150 }
124151
152+ /// Traverse the foreign keys on the table.
125153 pub fn foreign_keys ( self ) -> impl Iterator < Item = ForeignKeyWalker < ' a > > {
126154 self . table . foreign_keys . iter ( ) . map ( move |foreign_key| ForeignKeyWalker {
127155 foreign_key,
128156 table : self ,
129157 } )
130158 }
131159
160+ /// The table name.
132161 pub fn name ( & self ) -> & ' a str {
133162 & self . table . name
134163 }
135164
165+ /// Try to traverse a foreign key for a single column.
136166 pub fn foreign_key_for_column ( & self , column : & str ) -> Option < & ' a ForeignKey > {
137167 self . table . foreign_key_for_column ( column)
138168 }
139169
170+ /// Traverse to the primary key of the table.
140171 pub fn primary_key ( & self ) -> Option < & ' a PrimaryKey > {
141172 self . table . primary_key . as_ref ( )
142173 }
143174}
144175
176+ /// Traverse a foreign key.
145177pub struct ForeignKeyWalker < ' schema > {
146178 table : TableWalker < ' schema > ,
147179 foreign_key : & ' schema ForeignKey ,
148180}
149181
150182impl < ' a , ' schema > ForeignKeyWalker < ' schema > {
183+ /// The names of the foreign key columns on the referencing table.
151184 pub fn constrained_column_names ( & self ) -> & [ String ] {
152185 & self . foreign_key . columns
153186 }
154187
188+ /// The foreign key columns on the referencing table.
155189 pub fn constrained_columns < ' b > ( & ' b self ) -> impl Iterator < Item = ColumnWalker < ' schema > > + ' b {
156190 self . table ( )
157191 . columns ( )
158192 . filter ( move |column| self . foreign_key . columns . contains ( & column. column . name ) )
159193 }
160194
195+ /// The name of the foreign key constraint.
161196 pub fn constraint_name ( & self ) -> Option < & ' schema str > {
162197 self . foreign_key . constraint_name . as_deref ( )
163198 }
164199
200+ /// Access the underlying ForeignKey struct.
165201 pub fn inner ( & self ) -> & ' schema ForeignKey {
166202 self . foreign_key
167203 }
168204
205+ /// The number of columns referenced by the constraint.
169206 pub fn referenced_columns_count ( & self ) -> usize {
170207 self . foreign_key . referenced_columns . len ( )
171208 }
172209
210+ /// The table the foreign key "points to".
173211 pub fn referenced_table ( & self ) -> TableWalker < ' schema > {
174212 TableWalker {
175213 schema : self . table . schema ,
@@ -181,22 +219,26 @@ impl<'a, 'schema> ForeignKeyWalker<'schema> {
181219 }
182220 }
183221
222+ /// Traverse to the referencing table.
184223 pub fn table ( & self ) -> & TableWalker < ' schema > {
185224 & self . table
186225 }
187226}
188227
228+ /// Traverse an index.
189229pub struct IndexWalker < ' a > {
190230 schema : & ' a SqlSchema ,
191231 table : & ' a Table ,
192232 index : & ' a Index ,
193233}
194234
195235impl < ' a > IndexWalker < ' a > {
236+ /// The names of the indexed columns.
196237 pub fn column_names ( & self ) -> & [ String ] {
197238 & self . index . columns
198239 }
199240
241+ /// Traverse the indexed columns.
200242 pub fn columns < ' b > ( & ' b self ) -> impl Iterator < Item = ColumnWalker < ' a > > + ' b {
201243 self . index
202244 . columns
@@ -215,24 +257,30 @@ impl<'a> IndexWalker<'a> {
215257 } )
216258 }
217259
260+ /// Is any of the indexed columns nullable?
218261 pub fn has_nullable_columns ( & self ) -> bool {
219262 self . columns ( ) . any ( |c| c. arity ( ) . is_nullable ( ) )
220263 }
221264
265+ /// The underlying index struct.
222266 pub fn index ( & self ) -> & Index {
223267 & self . index
224268 }
225269
270+ /// The IndexType
226271 pub fn index_type ( & self ) -> & IndexType {
227272 & self . index . tpe
228273 }
229274
275+ /// The name of the index.
230276 pub fn name ( & self ) -> & str {
231277 & self . index . name
232278 }
233279}
234280
281+ /// Extension methods for the traversal of a SqlSchema.
235282pub trait SqlSchemaExt {
283+ /// Find a table by name.
236284 fn table_walker < ' a > ( & ' a self , name : & str ) -> Option < TableWalker < ' a > > ;
237285}
238286
0 commit comments