JobLog.java
package edu.ucsb.cs156.jobs.entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import java.time.ZonedDateTime;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* One line of a {@link Job}'s log, stored as its own row rather than appended into a single growing
* TEXT column on {@code jobs}. Each {@code ctx.log()} call is an INSERT here (O(1)), instead of a
* read-modify-write of the whole accumulated log (O(N) per call, O(N^2) total across N lines) —
* Postgres and MySQL both rewrite a TEXT column's full new value on every UPDATE under MVCC, so
* there is no way to make "append to one big column" cheap at the database layer either.
*
* <p>{@code id} is a real, ordered, per-line sequence, which is what makes incremental "tail -f"
* style fetching possible: a client can ask for everything with {@code id > lastSeenId}.
*/
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Entity(name = "job_logs")
public class JobLog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "job_id")
private Long jobId;
@Column(columnDefinition = "TEXT")
private String message;
private ZonedDateTime createdAt;
@PrePersist
void onCreate() {
createdAt = ZonedDateTime.now();
}
}