github.com/octohelm/storage@v0.0.0-20240516030302-1ac2cc1ea347/pkg/sqlbuilder/stmt_with_test.go (about) 1 package sqlbuilder_test 2 3 import ( 4 "testing" 5 6 "github.com/octohelm/storage/internal/testutil" 7 . "github.com/octohelm/storage/pkg/sqlbuilder" 8 ) 9 10 func TestWithStmt(t *testing.T) { 11 gr := &GroupRelation{} 12 g := &Group{} 13 14 t.Run("simple with", func(t *testing.T) { 15 testutil.ShouldBeExpr(t, 16 With((&GroupWithParent{}).T(), func(tmpTableGroupWithParent Table) SqlExpr { 17 s := Select(MultiMayAutoAlias( 18 TypedColOf[int](g.T(), "f_group_id"), 19 TypedColOf[int](gr.T(), "f_group_id"), 20 )). 21 From(gr.T(), 22 RightJoin(g.T()).On( 23 TypedColOf[int](g.T(), "f_group_id").V(EqCol(TypedColOf[int](gr.T(), "f_group_id")))), 24 ) 25 return s 26 }).With((&GroupWithParent{}).T(), func(tmpTableGroupWithParent Table) SqlExpr { 27 s := Select(MultiMayAutoAlias( 28 TypedColOf[int](g.T(), "f_group_id"), 29 TypedColOf[int](gr.T(), "f_group_id"), 30 )). 31 From(gr.T(), 32 RightJoin(g.T()).On( 33 TypedColOf[int](g.T(), "f_group_id").V( 34 EqCol(TypedColOf[int](gr.T(), "f_group_id")), 35 ), 36 ), 37 ) 38 return s 39 }). 40 Exec(func(tables ...Table) SqlExpr { 41 return Select(nil).From(tables[0]) 42 }), 43 ` 44 WITH t_group_with_parent(f_group_id,f_parent_group_id) AS ( 45 SELECT t_group.f_group_id AS t_group__f_group_id, t_group_relation.f_group_id AS t_group_relation__f_group_id FROM t_group_relation 46 RIGHT JOIN t_group ON t_group.f_group_id = t_group_relation.f_group_id 47 ), t_group_with_parent(f_group_id,f_parent_group_id) AS ( 48 SELECT t_group.f_group_id AS t_group__f_group_id, t_group_relation.f_group_id AS t_group_relation__f_group_id FROM t_group_relation 49 RIGHT JOIN t_group ON t_group.f_group_id = t_group_relation.f_group_id 50 ) 51 SELECT * FROM t_group_with_parent 52 `) 53 }) 54 t.Run("WithRecursive", func(t *testing.T) { 55 testutil.ShouldBeExpr(t, 56 WithRecursive((&GroupWithParentAndChildren{}).T(), func(tmpTableGroupWithParentAndChildren Table) SqlExpr { 57 return With((&GroupWithParent{}).T(), func(tmpTableGroupWithParent Table) SqlExpr { 58 s := Select(MultiMayAutoAlias( 59 TypedColOf[int](g.T(), "f_group_id"), 60 TypedColOf[int](gr.T(), "f_parent_group_id"), 61 )). 62 From(gr.T(), RightJoin(g.T()).On( 63 TypedColOf[int](g.T(), "f_group_id").V( 64 EqCol(TypedColOf[int](gr.T(), "f_group_id"))), 65 )) 66 return s 67 }).Exec(func(tables ...Table) SqlExpr { 68 tmpTableGroupWithParent := tables[0] 69 return Select( 70 MultiMayAutoAlias( 71 tmpTableGroupWithParent.F("f_group_id"), 72 tmpTableGroupWithParent.F("f_parent_group_id"), 73 Alias(Expr("0"), "f_depth"), 74 ), 75 ).From( 76 tmpTableGroupWithParent, 77 Where( 78 TypedColOf[int](tmpTableGroupWithParent, "f_group_id").V(Eq(1201375536060956676)), 79 ), 80 Union().All( 81 Select(MultiMayAutoAlias( 82 tmpTableGroupWithParent.F("f_group_id"), 83 tmpTableGroupWithParent.F("f_parent_group_id"), 84 Alias(tmpTableGroupWithParentAndChildren.F("f_depth").Expr("# + 1"), "f_depth"), 85 )).From( 86 tmpTableGroupWithParent, 87 CrossJoin(tmpTableGroupWithParentAndChildren), 88 Where( 89 And( 90 TypedColOf[int](tmpTableGroupWithParent, "f_group_id").V(NeqCol(TypedColOf[int](tmpTableGroupWithParentAndChildren, "f_group_id"))), 91 TypedColOf[int](tmpTableGroupWithParent, "f_parent_group_id").V(EqCol(TypedColOf[int](tmpTableGroupWithParentAndChildren, "f_group_id"))), 92 ), 93 ), 94 ), 95 ), 96 ) 97 }) 98 }).Exec(func(tables ...Table) SqlExpr { 99 return Select(nil).From(tables[0]) 100 }), 101 ` 102 WITH RECURSIVE t_group_with_parent_and_children(f_group_id,f_parent_group_id,f_depth) AS ( 103 WITH t_group_with_parent(f_group_id,f_parent_group_id) AS ( 104 SELECT t_group.f_group_id AS t_group__f_group_id, t_group_relation.f_parent_group_id AS t_group_relation__f_parent_group_id FROM t_group_relation 105 RIGHT JOIN t_group ON t_group.f_group_id = t_group_relation.f_group_id 106 ) 107 SELECT f_group_id, f_parent_group_id, 0 AS f_depth FROM t_group_with_parent 108 WHERE f_group_id = ? 109 UNION ALL SELECT t_group_with_parent.f_group_id AS t_group_with_parent__f_group_id, t_group_with_parent.f_parent_group_id AS t_group_with_parent__f_parent_group_id, t_group_with_parent_and_children.f_depth + 1 AS f_depth FROM t_group_with_parent 110 CROSS JOIN t_group_with_parent_and_children 111 WHERE (t_group_with_parent.f_group_id <> t_group_with_parent_and_children.f_group_id) AND (t_group_with_parent.f_parent_group_id = t_group_with_parent_and_children.f_group_id) 112 ) 113 SELECT * FROM t_group_with_parent_and_children 114 `, 1201375536060956676) 115 }) 116 } 117 118 var tableGroup = TableFromModel(&Group{}) 119 120 type Group struct { 121 GroupID int `db:"f_group_id"` 122 } 123 124 func (g *Group) TableName() string { 125 return "t_group" 126 } 127 128 func (g *Group) T() Table { 129 return tableGroup 130 } 131 132 var tableGroupRelation = TableFromModel(&GroupRelation{}) 133 134 type GroupRelation struct { 135 GroupID int `db:"f_group_id"` 136 ParentGroupID int `db:"f_parent_group_id"` 137 } 138 139 func (g *GroupRelation) TableName() string { 140 return "t_group_relation" 141 } 142 143 func (g *GroupRelation) T() Table { 144 return tableGroupRelation 145 } 146 147 var tableGroupWithParent = TableFromModel(&GroupWithParent{}) 148 149 type GroupWithParent struct { 150 GroupID int `db:"f_group_id"` 151 ParentGroupID int `db:"f_parent_group_id"` 152 } 153 154 func (g *GroupWithParent) TableName() string { 155 return "t_group_with_parent" 156 } 157 158 func (g *GroupWithParent) T() Table { 159 return tableGroupWithParent 160 } 161 162 var tableGroupWithParentAndChildren = TableFromModel(&GroupWithParentAndChildren{}) 163 164 type GroupWithParentAndChildren struct { 165 GroupWithParent 166 Depth int `db:"f_depth"` 167 } 168 169 func (g *GroupWithParentAndChildren) TableName() string { 170 return "t_group_with_parent_and_children" 171 } 172 173 func (g *GroupWithParentAndChildren) T() Table { 174 return tableGroupWithParentAndChildren 175 }