|
1 | 1 | namespace PowerSync.Common.DB.Schema; |
2 | 2 |
|
| 3 | +using System.Collections.Generic; |
3 | 4 | using System.Text.RegularExpressions; |
4 | 5 |
|
5 | 6 | using Newtonsoft.Json; |
@@ -62,54 +63,61 @@ public class TrackPreviousOptions |
62 | 63 |
|
63 | 64 | public class Table |
64 | 65 | { |
65 | | - public static readonly Regex InvalidSQLCharacters = new Regex(@"[""'%,.#\s\[\]]", RegexOptions.Compiled); |
| 66 | + public const int MAX_AMOUNT_OF_COLUMNS = 1999; |
66 | 67 |
|
| 68 | + public static readonly Regex InvalidSQLCharacters = new Regex(@"[""'%,.#\s\[\]]", RegexOptions.Compiled); |
67 | 69 |
|
| 70 | + public string Name { get; init; } = null!; |
68 | 71 | protected TableOptions Options { get; init; } = null!; |
| 72 | + public IReadOnlyDictionary<string, ColumnType> Columns { get; init; } |
| 73 | + public IReadOnlyDictionary<string, List<string>> Indexes { get; init; } |
69 | 74 |
|
70 | | - public Dictionary<string, ColumnType> Columns; |
71 | | - public Dictionary<string, List<string>> Indexes; |
72 | | - |
73 | | - private readonly List<Column> ConvertedColumns; |
74 | | - private readonly List<Index> ConvertedIndexes; |
| 75 | + private readonly ColumnJSON[] ColumnsJSON; |
| 76 | + private readonly IndexJSON[] IndexesJSON; |
75 | 77 |
|
76 | | - public Table(Dictionary<string, ColumnType> columns, TableOptions? options = null) |
| 78 | + public Table(string name, Dictionary<string, ColumnType> columns, TableOptions? options = null) |
77 | 79 | { |
78 | | - ConvertedColumns = [.. columns.Select(kv => new Column(new ColumnOptions(kv.Key, kv.Value)))]; |
79 | | - |
80 | | - ConvertedIndexes = |
81 | | - [ |
82 | | - .. (Options?.Indexes ?? []) |
83 | | - .Select(kv => |
84 | | - new Index(new IndexOptions( |
85 | | - kv.Key, |
86 | | - [ |
87 | | - .. kv.Value.Select(name => |
88 | | - new IndexedColumn(new IndexColumnOptions( |
89 | | - name.Replace("-", ""), !name.StartsWith("-"))) |
90 | | - ) |
91 | | - ] |
| 80 | + ColumnsJSON = |
| 81 | + columns |
| 82 | + .Select(kvp => new ColumnJSON(new ColumnJSONOptions(kvp.Key, kvp.Value))) |
| 83 | + .ToArray(); |
| 84 | + |
| 85 | + IndexesJSON = |
| 86 | + (Options?.Indexes ?? []) |
| 87 | + .Select(kvp => |
| 88 | + new IndexJSON(new IndexJSONOptions( |
| 89 | + kvp.Key, |
| 90 | + kvp.Value.Select(name => |
| 91 | + new IndexedColumnJSON(new IndexedColumnJSONOptions( |
| 92 | + name.Replace("-", ""), !name.StartsWith("-"))) |
| 93 | + ).ToArray() |
92 | 94 | )) |
93 | 95 | ) |
94 | | - ]; |
| 96 | + .ToArray(); |
95 | 97 |
|
96 | 98 | Options = options ?? new TableOptions(); |
97 | 99 |
|
| 100 | + Name = name; |
98 | 101 | Columns = columns; |
99 | 102 | Indexes = Options?.Indexes ?? []; |
100 | 103 | } |
101 | 104 |
|
102 | 105 | public void Validate() |
103 | 106 | { |
| 107 | + if (string.IsNullOrWhiteSpace(Name)) |
| 108 | + { |
| 109 | + throw new Exception($"Table name is required."); |
| 110 | + } |
| 111 | + |
104 | 112 | if (!string.IsNullOrWhiteSpace(Options.ViewName) && InvalidSQLCharacters.IsMatch(Options.ViewName!)) |
105 | 113 | { |
106 | 114 | throw new Exception($"Invalid characters in view name: {Options.ViewName}"); |
107 | 115 | } |
108 | 116 |
|
109 | | - if (Columns.Count > Column.MAX_AMOUNT_OF_COLUMNS) |
| 117 | + if (Columns.Count > MAX_AMOUNT_OF_COLUMNS) |
110 | 118 | { |
111 | 119 | throw new Exception( |
112 | | - $"Table has too many columns. The maximum number of columns is {Column.MAX_AMOUNT_OF_COLUMNS}."); |
| 120 | + $"Table has too many columns. The maximum number of columns is {MAX_AMOUNT_OF_COLUMNS}."); |
113 | 121 | } |
114 | 122 |
|
115 | 123 | if (Options.TrackMetadata && Options.LocalOnly) |
@@ -168,8 +176,8 @@ public string ToJSON(string Name = "") |
168 | 176 | view_name = Options.ViewName ?? Name, |
169 | 177 | local_only = Options.LocalOnly, |
170 | 178 | insert_only = Options.InsertOnly, |
171 | | - columns = ConvertedColumns.Select(c => JsonConvert.DeserializeObject<object>(c.ToJSON())).ToList(), |
172 | | - indexes = ConvertedIndexes.Select(e => JsonConvert.DeserializeObject<object>(e.ToJSON(this))).ToList(), |
| 179 | + columns = ColumnsJSON.Select(c => c.ToJSONObject()).ToList(), |
| 180 | + indexes = IndexesJSON.Select(i => i.ToJSONObject(this)).ToList(), |
173 | 181 |
|
174 | 182 | include_metadata = Options.TrackMetadata, |
175 | 183 | ignore_empty_update = Options.IgnoreEmptyUpdates, |
|
0 commit comments