github.com/mailru/activerecord@v1.12.2/internal/pkg/generator/tmpl/meta.tmpl (about) 1 package repository 2 3 import ( 4 "fmt" 5 "github.com/mailru/activerecord/pkg/octopus" 6 ) 7 8 type SpaceMeta struct { 9 PackageName string 10 Unpacker func(ctx context.Context, tuple octopus.TupleData) (any, error) 11 FixtureUnpacker func(ctx context.Context, source []byte) ([]any, error) 12 Fields []FieldMeta 13 PK IndexMeta 14 Indexes map[string]IndexMeta 15 } 16 17 type IndexMeta struct { 18 Name string 19 Unpacker func(packedKeys [][][]byte) (any, error) 20 } 21 22 type FieldMeta struct { 23 Name string 24 Unpacker func(packedField []byte) (any, error) 25 } 26 27 type NSPackage map[string]SpaceMeta 28 29 func (ns NSPackage) meta(n uint32) (SpaceMeta, bool) { 30 v, ok := ns[strconv.Itoa(int(n))] 31 return v, ok 32 } 33 34 {{ $nss := .Namespaces }} 35 var NamespacePackages = NSPackage { 36 {{ range $_, $ns := $nss -}} 37 {{ $serializers := $ns.SerializerMap -}} 38 "{{ $ns.Namespace.ObjectName }}": { 39 PackageName: "{{ $ns.Namespace.PackageName }}", 40 Unpacker: func(ctx context.Context, tuple octopus.TupleData) (any, error) { 41 obj, err := {{ $ns.Namespace.PackageName }}.TupleToStruct(ctx, tuple) 42 if err != nil { 43 return nil, fmt.Errorf("can't decode tuple: %s", err) 44 } 45 46 return {{ $ns.Namespace.PackageName }}.MarshalFixtures([]*{{ $ns.Namespace.PackageName }}.{{ $ns.Namespace.PublicName }}{obj}) 47 }, 48 FixtureUnpacker: func(ctx context.Context, source []byte) (res []any, err error) { 49 fxts, err := {{ $ns.Namespace.PackageName }}.UnmarshalFixtures(source) 50 if err != nil { 51 return nil, fmt.Errorf("can't decode tuple: %s", err) 52 } 53 54 for _, v := range fxts { 55 res = append(res, v) 56 } 57 58 return 59 }, 60 Fields: []FieldMeta{ 61 {{- range $_, $field := $ns.Fields }} 62 {{ $sname := $field.Serializer.Name }} 63 { 64 Name: "{{ $field.Name }}", 65 Unpacker: func(packedField []byte) (any, error){ 66 {{ if ne $sname "" -}} 67 field, err := {{ $ns.Namespace.PackageName }}.Unpack{{ $field.Name }}(bytes.NewReader(packedField)) 68 if err != nil { 69 return nil, err 70 } 71 72 return {{ $ns.Namespace.PackageName }}.Marshal{{ $field.Name }}(field) 73 {{- else }} 74 return {{ $ns.Namespace.PackageName }}.Unpack{{ $field.Name }}(bytes.NewReader(packedField)) 75 {{- end }} 76 }, 77 }, 78 {{- end }} 79 }, 80 Indexes: map[string]IndexMeta{ 81 {{ if $ns.Indexes }} 82 {{- $pk := index $ns.Indexes 0 }} 83 {{- range $num, $ind := $ns.Indexes }} 84 {{- if $ind.Primary }}{{ $pk = $ind }}{{ end }} 85 "{{ $ind.Num }}.{{ len $ind.Fields }}": { 86 Name: "{{ $ind.Name }}", 87 Unpacker: func(packedKeys [][][]byte) (any, error) { return {{ $ns.Namespace.PackageName }}.UnpackKeyIndex{{ $ind.Name }}(packedKeys)}, 88 }, 89 {{- end }} 90 {{- end }} 91 }, 92 PK: IndexMeta{ 93 {{ if $ns.Indexes }} 94 {{- $pk := index $ns.Indexes 0 }} 95 Name: "{{ $pk.Name }}", 96 Unpacker: func(packedKeys [][][]byte) (any, error) { return {{ $ns.Namespace.PackageName }}.UnpackKeyIndex{{ $pk.Name }}(packedKeys)}, 97 {{- end }} 98 }, 99 }, 100 {{ end }} 101 } 102 103 func (n NSPackage) GetSelectDebugInfo(ns uint32, indexnum uint32, offset uint32, limit uint32, keys [][][]byte, fixture ...octopus.SelectMockFixture) string { 104 spacemeta, ex := n.meta(ns) 105 if !ex { 106 return fmt.Sprintf("unknown space %d, index: %d, offset: %d, limit: %d, Keys: %+v", ns, indexnum, offset, limit, keys) 107 } 108 109 fmtStr := "\n" + n.formatSelectMockFixture(ns, spacemeta, indexnum, offset, limit, keys) + "\n" 110 fmtStr = fmt.Sprintf("%s\n--------------Installed 'Select' fixtures %s --------------\n", fmtStr, spacemeta.PackageName) 111 for _, f := range fixture { 112 fmtStr = fmtStr + "\n" + n.formatSelectMockFixture(ns, spacemeta, f.Indexnum, f.Offset, f.Limit, f.Keys) + " \n" 113 114 for _, tuple := range f.RespTuples { 115 strRespObj, err := spacemeta.Unpacker(context.TODO(), tuple) 116 if err != nil { 117 return fmt.Sprintf("Space: %d (%s), tuple: %+v (err unpack: %s)", ns, spacemeta.PackageName, tuple, err) 118 } 119 120 fmtStr = fmtStr + "\n" + fmt.Sprintf("%s", strRespObj) + "\n" 121 122 } 123 } 124 125 fmtStr = fmt.Sprintf("%s\n--------------End Installed 'Select' fixtures %s-----------\n\n\n\n", fmtStr, spacemeta.PackageName) 126 127 return fmtStr 128 } 129 130 func (n NSPackage) formatSelectMockFixture(ns uint32, spacemeta SpaceMeta, indexnum uint32, offset uint32, limit uint32, keys [][][]byte) string { 131 if len(keys) == 0 { 132 return fmt.Sprintf("Space: %d (%s), index: %d, offset: %d, limit: %d, Empty Key Values", ns, spacemeta.PackageName, indexnum, offset, limit) 133 } 134 135 ind, ex := spacemeta.Indexes[fmt.Sprintf("%d.%d", indexnum, len(keys[0]))] 136 if !ex { 137 return fmt.Sprintf("space %d (%s), unknown index: %d (%d.%d), offset: %d, limit: %d, Keys: %+v", ns, spacemeta.PackageName, indexnum, indexnum, len(keys[0]), offset, limit, keys) 138 } 139 140 unpackedKeys, err := ind.Unpacker(keys) 141 if err != nil { 142 return fmt.Sprintf("Space: %d (%s), index: %d (%s), offset: %d, limit: %d, Keys: %+v (error unpack: %s)", ns, spacemeta.PackageName, indexnum, ind.Name, offset, limit, keys, err) 143 } 144 145 return fmt.Sprintf("Space: %d (%s), index: %d (%s), offset: %d, limit: %d, Keys: %+v", ns, spacemeta.PackageName, indexnum, ind.Name, offset, limit, unpackedKeys) 146 } 147 148 func (n NSPackage) GetUpdateDebugInfo(ns uint32, primaryKey [][]byte, updateOps []octopus.Ops, fixture ...octopus.UpdateMockFixture) string { 149 spacemeta, ex := n.meta(ns) 150 if !ex { 151 return fmt.Sprintf("unknown space %d, primaryKey: %+v, updateOps: %+v", ns, primaryKey, updateOps) 152 } 153 154 fmtStr := "\n" + n.formatUpdateMockFixture(ns, spacemeta, primaryKey, updateOps) + "\n" 155 fmtStr = fmt.Sprintf("%s\n--------------Installed 'Update' fixtures %s --------------\n", fmtStr, spacemeta.PackageName) 156 for _, f := range fixture { 157 fmtStr = fmtStr + "\n" + n.formatUpdateMockFixture(ns, spacemeta, f.PrimaryKey, f.UpdateOps) + "\n" 158 } 159 160 fmtStr = fmt.Sprintf("%s\n--------------End Installed 'Update' fixtures %s-----------\n\n\n\n", fmtStr, spacemeta.PackageName) 161 162 return fmtStr 163 } 164 165 func (n NSPackage) formatUpdateMockFixture(ns uint32, spacemeta SpaceMeta, primaryKey [][]byte, updateOps []octopus.Ops) string { 166 unpackedKeys, err := spacemeta.PK.Unpacker([][][]byte{primaryKey}) 167 if err != nil { 168 return fmt.Sprintf("Space: %d (%s), primaryKey: %+v, updateOps: %+v (error unpack: %s)", ns, spacemeta.PackageName, primaryKey, updateOps, err) 169 } 170 171 updateFields := "" 172 173 for _, op := range updateOps { 174 val, err := spacemeta.Fields[op.Field].Unpacker(op.Value) 175 if err != nil { 176 val = fmt.Sprintf("% X (can't unpack: %s)", op.Value, err) 177 } 178 179 updateFields += fmt.Sprintf("%s %s <= `%v`; ", octopus.GetOpCodeName(op.Op), spacemeta.Fields[op.Field].Name, val) 180 } 181 182 return fmt.Sprintf("Space: %d (%s), primaryKey: %s (%+v), updateOps: %s", ns, spacemeta.PackageName, spacemeta.PK.Name, unpackedKeys, updateFields) 183 } 184 185 func (n NSPackage) GetDeleteDebugInfo(ns uint32, primaryKey [][]byte, fixture ...octopus.DeleteMockFixture) string { 186 spacemeta, ex := n.meta(ns) 187 if !ex { 188 return fmt.Sprintf("unknown space %d, primaryKey: %+v", ns, primaryKey) 189 } 190 191 fmtStr := "\n" + n.formatDeleteMockFixture(ns, spacemeta, primaryKey) + "\n" 192 fmtStr = fmt.Sprintf("%s\n--------------Installed 'Delete' fixtures %s --------------\n", fmtStr, spacemeta.PackageName) 193 for _, f := range fixture { 194 fmtStr = fmtStr + "\n" + n.formatDeleteMockFixture(ns, spacemeta, f.PrimaryKey) + "\n" 195 } 196 197 fmtStr = fmt.Sprintf("%s\n--------------End Installed 'Delete' fixtures %s-----------\n\n\n\n", fmtStr, spacemeta.PackageName) 198 199 return fmtStr 200 } 201 202 func (n NSPackage) formatDeleteMockFixture(ns uint32, spacemeta SpaceMeta, primaryKey [][]byte) string { 203 unpackedKeys, err := spacemeta.PK.Unpacker([][][]byte{primaryKey}) 204 if err != nil { 205 return fmt.Sprintf("Space: %d (%s), primaryKey: %+v (error unpack: %s)", ns, spacemeta.PackageName, primaryKey, err) 206 } 207 208 return fmt.Sprintf("Space: %d (%s), primaryKey: %s (%+v)", ns, spacemeta.PackageName, spacemeta.PK.Name, unpackedKeys) 209 } 210 211 func (n NSPackage) GetInsertDebugInfo(ns uint32, needRetVal bool, insertMode octopus.InsertMode, tuple octopus.TupleData, fixture ...octopus.InsertMockFixture) string { 212 strMode := octopus.GetInsertModeName(insertMode) 213 214 spacemeta, ex := n.meta(ns) 215 if !ex { 216 return fmt.Sprintf("unknown space %d, insertMode: %s, tuple: %+v", ns, strMode, tuple) 217 } 218 219 fmtStr := "\n" + n.formatInsertMockFixture(ns, spacemeta, needRetVal, insertMode, tuple) + "\n" 220 fmtStr = fmt.Sprintf("%s\n--------------Installed 'Insert' fixtures %s --------------\n", fmtStr, spacemeta.PackageName) 221 for _, f := range fixture { 222 fmtStr = fmtStr + "\n" + n.formatInsertMockFixture(ns, spacemeta, f.NeedRetVal, f.InsertMode, f.Tuple) + "\n" 223 } 224 225 fmtStr = fmt.Sprintf("%s\n--------------End Installed 'Insert' fixtures %s------------\n\n\n\n", fmtStr, spacemeta.PackageName) 226 227 return fmtStr 228 } 229 230 func (n NSPackage) formatInsertMockFixture(ns uint32, spacemeta SpaceMeta, needRetVal bool, insertMode octopus.InsertMode, tuple octopus.TupleData) string { 231 strMode := octopus.GetInsertModeName(insertMode) 232 233 strObj, err := spacemeta.Unpacker(context.TODO(), tuple) 234 if err != nil { 235 return fmt.Sprintf("Space: %d (%s), insertMode: %s, tuple: %+v (err unpack: %s)", ns, spacemeta.PackageName, strMode, tuple, err) 236 } 237 238 return fmt.Sprintf("Space: %d (%s), insertMode: %s, tuple: \n%s", ns, spacemeta.PackageName, strMode, strObj) 239 } 240 241 242 func (n NSPackage) GetCallDebugInfo(ns string, args [][]byte, fixture ...octopus.CallMockFixture) string { 243 spacemeta, ex := n[ns] 244 if !ex { 245 return fmt.Sprintf("unknown procedure %s, arguments: %+v", ns, args) 246 } 247 248 fmtStr := "\n" + n.formatCallMockFixture(ns, args) + "\n" 249 fmtStr = fmt.Sprintf("%s\n--------------Installed 'Call' fixtures %s --------------\n", fmtStr, spacemeta.PackageName) 250 for _, f := range fixture { 251 fmtStr = fmtStr + "\n" + n.formatCallMockFixture(ns, f.Args) + " \n" 252 253 for _, tuple := range f.RespTuples { 254 strRespObj, err := spacemeta.Unpacker(context.TODO(), tuple) 255 if err != nil { 256 return fmt.Sprintf("Procedure: %s, tuple: %+v (err unpack: %s)", ns, tuple, err) 257 } 258 259 fmtStr = fmtStr + "\n" + fmt.Sprintf("%s", strRespObj) + "\n" 260 } 261 } 262 263 fmtStr = fmt.Sprintf("%s\n--------------End Installed 'Call' fixtures %s-----------\n\n\n\n", fmtStr, spacemeta.PackageName) 264 265 return fmtStr 266 } 267 268 func (n NSPackage) formatCallMockFixture(ns string, args [][]byte) string { 269 var unpackedArgs []string 270 271 for _, arg := range args { 272 unpackedArgs = append(unpackedArgs, string(arg)) 273 } 274 275 return fmt.Sprintf("Procedure: %s, arguments: %s", ns, unpackedArgs) 276 }