Class: Parse::Schema::SchemaDiff
- Inherits:
-
Object
- Object
- Parse::Schema::SchemaDiff
- Defined in:
- lib/parse/schema.rb
Overview
Represents the difference between local model and server schema.
Instance Attribute Summary collapse
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#server_schema ⇒ Object
readonly
Returns the value of attribute server_schema.
Instance Method Summary collapse
-
#in_sync? ⇒ Boolean
Check if schemas are in sync.
-
#initialize(model_class, server_schema) ⇒ SchemaDiff
constructor
A new instance of SchemaDiff.
-
#missing_locally ⇒ Hash
Fields on server but not defined locally.
-
#missing_on_server ⇒ Hash
Fields defined locally but missing on server.
-
#server_covers_local? ⇒ Boolean
Check whether the server schema covers every locally-defined field.
-
#server_exists? ⇒ Boolean
Check if server schema exists.
-
#summary ⇒ String
Generate a human-readable summary.
-
#type_mismatches ⇒ Hash
Fields with type mismatches.
Constructor Details
#initialize(model_class, server_schema) ⇒ SchemaDiff
Returns a new instance of SchemaDiff.
222 223 224 225 |
# File 'lib/parse/schema.rb', line 222 def initialize(model_class, server_schema) @model_class = model_class @server_schema = server_schema end |
Instance Attribute Details
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
220 221 222 |
# File 'lib/parse/schema.rb', line 220 def model_class @model_class end |
#server_schema ⇒ Object (readonly)
Returns the value of attribute server_schema.
220 221 222 |
# File 'lib/parse/schema.rb', line 220 def server_schema @server_schema end |
Instance Method Details
#in_sync? ⇒ Boolean
Check if schemas are in sync.
Strict / bidirectional: requires the local and server schemas to match in BOTH directions — no fields missing on the server, no fields missing locally, and no type mismatches. A server that is a strict superset of the local model is NOT "in sync" by this measure (use #server_covers_local? for the one-way local ⊆ server check).
312 313 314 |
# File 'lib/parse/schema.rb', line 312 def in_sync? missing_on_server.empty? && missing_locally.empty? && type_mismatches.empty? end |
#missing_locally ⇒ Hash
Fields on server but not defined locally.
257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/parse/schema.rb', line 257 def missing_locally return {} unless server_exists? server = @server_schema.fields local = local_field_names missing = {} server.each do |name, info| # Skip core fields next if %w[objectId createdAt updatedAt ACL].include?(name) missing[name] = info[:type] unless local.include?(name) || local.include?(name.underscore.to_sym) end missing end |
#missing_on_server ⇒ Hash
Fields defined locally but missing on server.
Iterates the model's field_map (one entry per canonical property,
canonical name => wire column name) rather than fields (which carries
both the snake_case and camelCase keys for every property and therefore
double-counts multi-word fields). The wire name resolved from
field_map is the authoritative server column — including custom
field: mappings — so this both dedupes and fixes custom-column
detection. Result is keyed by the CANONICAL (snake) name with the type
taken from fields[name].
244 245 246 247 248 249 250 251 252 253 |
# File 'lib/parse/schema.rb', line 244 def missing_on_server server = server_exists? ? server_field_names : [] missing = {} @model_class.field_map.each do |name, wire| next if core_field?(name) next if server.include?(wire.to_s) missing[name] = @model_class.fields[name] end missing end |
#server_covers_local? ⇒ Boolean
Check whether the server schema covers every locally-defined field.
One-way (local ⊆ server): true when nothing the model declares is missing on the server and there are no type mismatches. Unlike #in_sync?, this ignores server-only columns, so a server that is a strict superset of the local model still satisfies it. This is the predicate that determines whether a migration has any work to do — extra server columns are not something the migrator would add.
325 326 327 |
# File 'lib/parse/schema.rb', line 325 def server_covers_local? missing_on_server.empty? && type_mismatches.empty? end |
#server_exists? ⇒ Boolean
Check if server schema exists.
229 230 231 |
# File 'lib/parse/schema.rb', line 229 def server_exists? !@server_schema.nil? end |
#summary ⇒ String
Generate a human-readable summary.
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/parse/schema.rb', line 331 def summary lines = ["Schema diff for #{@model_class.parse_class}:"] if !server_exists? lines << " - Class does not exist on server" elsif in_sync? lines << " - Schemas are in sync" else unless missing_on_server.empty? lines << " Missing on server:" missing_on_server.each { |n, t| lines << " + #{n}: #{t}" } end unless missing_locally.empty? lines << " Missing locally:" missing_locally.each { |n, t| lines << " - #{n}: #{t}" } end unless type_mismatches.empty? lines << " Type mismatches:" type_mismatches.each { |n, m| lines << " ~ #{n}: local=#{m[:local]}, server=#{m[:server]}" } end end lines.join("\n") end |
#type_mismatches ⇒ Hash
Fields with type mismatches.
Iterates field_map (canonical name => wire column) rather than
deriving the server key with camelize(:lower), so a property with a
custom field: wire column (e.g. property :post_id, field:
"postIdentifier") resolves to its real server column instead of a
camelized guess. This both dedupes multi-word fields (which appear
under two keys in fields) and matches the missing_on_server
resolution path, so type drift on custom-mapped columns is no longer
silently skipped.
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/parse/schema.rb', line 282 def type_mismatches return {} unless server_exists? mismatches = {} @model_class.field_map.each do |name, wire| next if core_field?(name) local_type = @model_class.fields[name] next if local_type.nil? server_type = @server_schema.field_type(wire.to_s) next unless server_type # Normalize types for comparison normalized_local = normalize_type(local_type) normalized_server = normalize_type(server_type) if normalized_local != normalized_server mismatches[name] = { local: local_type, server: server_type } end end mismatches end |