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  }