concept CSnippet { long snippetID; S type; S title, md5, transpilationMD5; bool isPublic; File file() { ret snippetDB_textFile(snippetID); } S text() { ret loadTextFile(file()); } bool hasText() { ret fileExists(file()); } void setText(S text) { S oldText = text(); if (eq(text, oldText)) ret; thread { logStructure(javaxBackupDir("snippet-text-changes.log"), ll(now(), snippetID, type, title, md5, "old", oldText, "new", text)); } saveTextFile(file(), text); } int textLength() { ret hasText() ? (int) fileSize(file()) : -1; } S snippetID() { ret fsI(snippetID); } }