1+ import Foundation
2+
13/// A table that is managed by the user instead of being auto-created and migrated by the PowerSync SDK.
24///
35/// These tables give application developers full control over the table (including table and column constraints).
1113///
1214/// Note that raw tables are only supported when ``ConnectOptions/newClientImplementation``
1315/// is enabled.
14- public struct RawTable : BaseTableProtocol {
16+ public struct RawTable : BaseTableProtocol , Encodable {
1517 /// The name of the table as it appears in sync rules.
1618 ///
1719 /// This doesn't necessarily have to match the statement that ``RawTable/put`` and ``RawTable/delete``
@@ -58,11 +60,52 @@ public struct RawTable: BaseTableProtocol {
5860 /// The output of this can be passed to the `powersync_create_raw_table_crud_trigger` SQL
5961 /// function to define triggers for this table.
6062 public func jsonDescription( ) -> String {
61- return KotlinAdapter . Table. toKotlin ( self ) . jsonDescription ( )
63+ let encoder = JSONEncoder ( )
64+ do {
65+ let serialized = try encoder. encode ( self )
66+ return String ( data: serialized, encoding: . utf8) !
67+ } catch {
68+ // An older version of the Swift SDK used to implement this method in Kotlin.
69+ // That could also throw an exception (which would crash the process), but that
70+ // was overlooked due to a missing @Throws annotation.
71+ // Now, we can't mark this as throws without breaking backwards compatibility.
72+ // We should convert this to be throwing in a future major release.
73+ fatalError ( " Serializing a raw table failed: \( error) " )
74+ }
75+ }
76+
77+ internal func validate( ) throws ( TableError) {
78+ if let schema {
79+ try schema. options. validate ( tableName: name)
80+ }
81+ }
82+
83+ public func encode( to encoder: any Encoder ) throws {
84+ enum CodingKeys : String , CodingKey {
85+ case name
86+ case put
87+ case delete
88+ case clear
89+ // For schema
90+ case tableName = " table_name "
91+ case syncedColumns = " synced_columns "
92+ }
93+ typealias Keys = TableOptionsCodingKeys < CodingKeys >
94+
95+ var container = encoder. container ( keyedBy: Keys . self)
96+ try container. encode ( name, forKey: . outer( . name) )
97+ try container. encodeIfPresent ( put, forKey: . outer( . put) )
98+ try container. encodeIfPresent ( delete, forKey: . outer( . delete) )
99+ try container. encodeIfPresent ( clear, forKey: . outer( . clear) )
100+ if let schema {
101+ try container. encode ( schema. tableName ?? name, forKey: . outer( . tableName) )
102+ try container. encodeIfPresent ( schema. syncedColumns, forKey: . outer( . syncedColumns) )
103+ try schema. options. serializeTo ( container)
104+ }
62105 }
63106}
64107
65- /// THe schema of a ``RawTable`` in the local database.
108+ /// The schema of a ``RawTable`` in the local database.
66109///
67110/// This information is optional when declaring raw tables. However, providing it allows the sync
68111/// client to infer ``RawTable/put`` and ``RawTable/delete`` statements automatically.
@@ -95,7 +138,7 @@ public struct RawTableSchema: Sendable {
95138}
96139
97140/// A statement to run to sync server-side changes into a local raw table.
98- public struct PendingStatement : Sendable {
141+ public struct PendingStatement : Sendable , Encodable {
99142 /// The SQL statement to execute.
100143 public let sql : String
101144 /// For parameters in the prepared statement, the values to fill in.
@@ -108,10 +151,21 @@ public struct PendingStatement: Sendable {
108151 self . sql = sql
109152 self . parameters = parameters
110153 }
154+
155+ public func encode( to encoder: any Encoder ) throws {
156+ enum CodingKeys : String , CodingKey {
157+ case sql
158+ case parameters = " params "
159+ }
160+
161+ var container = encoder. container ( keyedBy: CodingKeys . self)
162+ try container. encode ( self . sql, forKey: . sql)
163+ try container. encode ( self . parameters, forKey: . parameters)
164+ }
111165}
112166
113167/// A parameter that can be used in a ``PendingStatement``.
114- public enum PendingStatementParameter : Sendable {
168+ public enum PendingStatementParameter : Sendable , Encodable {
115169 /// A value that resolves to the textual id of the row to insert, update or delete.
116170 case id
117171 /// A value that resolves to the value of a column in a `PUT` operation for inserts or updates.
@@ -122,4 +176,22 @@ public enum PendingStatementParameter: Sendable {
122176 /// Resolves to a JSON object containing all columns from the synced row that haven't been matched
123177 /// by a ``PendingStatementParameter/column`` value in the same statement.
124178 case rest
179+
180+ public func encode( to encoder: any Encoder ) throws {
181+ switch self {
182+ case . id:
183+ var container = encoder. singleValueContainer ( )
184+ try container. encode ( " Id " )
185+ case . column( let name) :
186+ enum CodingKeys : String , CodingKey {
187+ case column = " Column "
188+ }
189+
190+ var container = encoder. container ( keyedBy: CodingKeys . self)
191+ try container. encode ( name, forKey: . column)
192+ case . rest:
193+ var container = encoder. singleValueContainer ( )
194+ try container. encode ( " Rest " )
195+ }
196+ }
125197}
0 commit comments