metadata.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package splitable
  15. import (
  16. "database/sql"
  17. "time"
  18. "yunion.io/x/pkg/errors"
  19. "yunion.io/x/sqlchemy"
  20. )
  21. type STableMetadata struct {
  22. Id int64 `primary:"true" auto_increment:"true"`
  23. Table string `width:"64" charset:"ascii"`
  24. Start int64 `nullable:"true"`
  25. End int64 `nullable:"true"`
  26. Count uint64 `nullable:"true"`
  27. StartDate time.Time `nullable:"true"`
  28. EndDate time.Time `nullable:"true"`
  29. Deleted bool `nullable:"false"`
  30. DeleteAt time.Time `nullable:"true"`
  31. CreatedAt time.Time `nullable:"false" created_at:"true"`
  32. }
  33. func (spec *SSplitTableSpec) getTableLastMeta() (*STableMetadata, error) {
  34. return spec.GetTableMetaByTime(time.Time{})
  35. }
  36. func (spec *SSplitTableSpec) GetTableMetaByTime(recordTime time.Time) (*STableMetadata, error) {
  37. q := spec.metaSpec.Query().Desc("id").IsFalse("deleted")
  38. if !recordTime.IsZero() {
  39. q = q.LE("start_date", recordTime.Add(time.Second))
  40. }
  41. meta := new(STableMetadata)
  42. err := q.First(meta)
  43. return meta, err
  44. }
  45. type ISplitTableObject interface {
  46. GetRecordTime() time.Time
  47. }
  48. func (spec *SSplitTableSpec) GetTableMetaByObject(obj ISplitTableObject) (*STableMetadata, error) {
  49. return spec.GetTableMetaByTime(obj.GetRecordTime())
  50. }
  51. func (spec *SSplitTableSpec) getTableMetasForInit() ([]STableMetadata, error) {
  52. q := spec.metaSpec.Query().Asc("id").IsFalse("deleted")
  53. q = q.AppendField(q.Field("table"))
  54. q = q.AppendField(q.Field("start"))
  55. metas := make([]STableMetadata, 0)
  56. err := q.All(&metas)
  57. if err != nil && errors.Cause(err) != sql.ErrNoRows {
  58. return nil, errors.Wrap(err, "query metadata")
  59. }
  60. return metas, nil
  61. }
  62. func (spec *SSplitTableSpec) GetTableMetas() ([]STableMetadata, error) {
  63. q := spec.metaSpec.Query().Asc("id").IsFalse("deleted")
  64. metas := make([]STableMetadata, 0)
  65. err := q.All(&metas)
  66. if err != nil && errors.Cause(err) != sql.ErrNoRows {
  67. return nil, errors.Wrap(err, "query metadata")
  68. }
  69. for i := 0; i < len(metas); i++ {
  70. if metas[i].Count <= 0 {
  71. // fix count
  72. tbl := spec.GetTableSpec(metas[i]).Instance()
  73. cnt, err := tbl.Query().CountWithError()
  74. if err != nil {
  75. return nil, errors.Wrap(err, "CountWithError")
  76. }
  77. spec.metaSpec.Update(&metas[i], func() error {
  78. metas[i].Count = uint64(cnt)
  79. return nil
  80. })
  81. }
  82. }
  83. return metas, nil
  84. }
  85. func (spec *SSplitTableSpec) GetTableSpec(meta STableMetadata) *sqlchemy.STableSpec {
  86. tbSpec := *spec.tableSpec
  87. return tbSpec.Clone(meta.Table, meta.Start)
  88. }