Documentation ¶
Overview ¶
Package dbutils provides an interface to databases (altho mainly just SQLite).
Index ¶
- Constants
- Variables
- func Ito09az(i int) string
- func MustExistTable(s string)
- func NowAsYM() string
- func NowAsYMDHM() string
- func TestInbatch(rowsx *sqlx.Rows, S *Inbatch)
- func WithTx(db *sql.DB, f TxFunc) (err error)
- type BLKTP
- type ContentityRecord
- type Datum
- type DbColIRL
- type DbColSpec
- type DbDescr
- type DbTblSpec
- type FLDTP
- type InUI
- type Inbatch
- type MmmcDB
- func (p *MmmcDB) Add_Inbatch(pIB *Inbatch) (int, error)
- func (pDB *MmmcDB) CreateTable_sqlite(ts TableConfig)
- func (pDB *MmmcDB) DbTblColsIRL(tableName string) []*DbColIRL
- func (pDB *MmmcDB) DumpTableSchema_sqlite(tableName string) string
- func (p *MmmcDB) DupeCurrentToBackup() error
- func (p *MmmcDB) ForceEmpty()
- func (p *MmmcDB) ForceExistDBandTables()
- func (p *MmmcDB) GetAll_Inbatch() (pp []*Inbatch)
- func (p *MmmcDB) GetContentityAll() (pp []*ContentityRecord)
- func (p *MmmcDB) InsertContentityRecord(pC *ContentityRecord) (int, error)
- func (p *MmmcDB) MoveCurrentToBackup() error
- func (p *MmmcDB) TryColumns(tableName string)
- func (p *MmmcDB) Verify()
- type TableConfig
- type Times
- type Topicref
- type TxFunc
- type TxtIntKeyEtc
Constants ¶
const ( D_TXT TxtIntKeyEtc = "A-z" // SQLite "TEXT" D_INT = "0-9" // SQLite "INT" D_KEY = "Key" // KEY (primary or foreign, SQLite "INTEGER") D_TBL = "Tbl" // This is describing a table ! D_LST = "lst" // table type, one per enumetarion ?? D_TBD = "??" // possible future expansion )
const DBNAME = "mmmc.db"
DBNAME defaults to "mmmc.db"
Variables ¶
var AllTableConfigs = []TableConfig{ TableConfig_Inbatch, TableConfig_Contentity, TableConfig_Topicref, }
var BLKTPs = []BLKTP{ {D_LST, "OLIST", "Ord'd list", "Generic ordered list"}, {D_LST, "ULIST", "Unord. list", "Generic unordered list"}, {D_LST, "RLIST", "Ranked list", "List ordered by ranking"}, {D_LST, "SLIST", "Seq. list", "List ordered as a sequence"}, {D_LST, "ELIST", "Enum. list", "List of enumerated elements"}, {D_LST, "ENUME", "Enum. item", "Element of enumeration"}, {D_LST, "XLIST", "Excl. list", "List (select one only)"}, {D_LST, "MLIST", "Mult. list", "List (select multiple)"}, {D_TBD, "TABLE", "Table", "Table / dataframe"}, {D_TBD, "UTREE", "Unord. tree", "Tree of unordered children (e.g. XML data)"}, {D_TBD, "OTREE", "Ord. tree", "Tree of ordered children (e.g. XML mixed content)"}, }
BLKTPs are data structures related to semantic field types.
var ColumnSpecs_Contentity = []DbColSpec{ D_RelFP, D_AbsFP, D_TmCre, D_TmImp, D_TmEdt, DbColSpec{D_TXT, "descr", "Description", "Content item description"}, DbColSpec{D_TXT, "mimetype", "MIME type", "MIME type"}, DbColSpec{D_TXT, "mtype", "MType", "MType"}, DbColSpec{D_TXT, "xmlcontype", "XML contype", "XML content type"}, DbColSpec{D_TXT, "xmldoctype", "XML Doctype", "XML Doctype"}, DbColSpec{D_TXT, "ditaflavor", "(Lw)DITA flavor", "(Lw)DITA flavor"}, DbColSpec{D_TXT, "ditacontype", "(Lw)DITA contype", "(Lw)DITA content type"}, }
var ColumnSpecs_Inbatch = []DbColSpec{ D_RelFP, D_AbsFP, D_TmCre, DbColSpec{D_TXT, "descr", "Batch descr.", "Inbatch description"}, DbColSpec{D_INT, "filct", "Nr. of files", "Number of files"}, }
var ColumnSpecs_Topicref = []DbColSpec{}
var D_AbsFP = DbColSpec{D_TXT, "absfp", "Abs. path", "Absolute filepath"}
var D_RelFP = DbColSpec{D_TXT, "relfp", "Rel. path", "Rel.FP (from CLI)"}
var D_TmCre = DbColSpec{D_TXT, "t_cre", "Cre. time", "Creation date+time"}
var D_TmEdt = DbColSpec{D_TXT, "t_edt", "Edit time", "Last edit date+time"}
var D_TmImp = DbColSpec{D_TXT, "t_imp", "Imp. time", "DB import date+time"}
var FLDTPs = []FLDTP{ {D_INT, "INTEG", "Integer", "Generic integer, size unspecified"}, {D_INT, "BOOL_", "Boolean", "Boolean (0|1)"}, {D_INT, "PRKEY", "Pri. key", "Primary table key (unique, non-NULL"}, {D_INT, "FRKEY", "For. key", "Foreign table key"}, {D_TBD, "FLOAT", "Float", "Generic non-integer, size unspecified"}, {D_TXT, "STRNG", "String", "Generic string, not text"}, {D_TXT, "TOKEN", "Token", "Generic token (no spaces, punc.)"}, {D_TXT, "FTEXT", "Free text", "Generic free-flowing text"}, {D_TXT, "MTEXT", "Markdown", "Markdown (or plain) text"}, {D_TXT, "JTEXT", "JSON", "JSON content"}, {D_TXT, "XTEXT", "XML text", "XML text such as (Lw)DITA"}, {D_TXT, "HTEXT", "HTML5 text", "HTML5 (or previous) text"}, {D_TXT, "MCFMT", "Microformat", "Microformat record"}, {D_TXT, "FONUM", "Phone nr.", "Telephone number"}, {D_TXT, "EMAIL", "Email", "Email address"}, {D_TXT, "URLIN", "URL/URI/URN", "Generic path ID (URL, URI, URN)"}, {D_TXT, "DATIM", "Date / Time", "Date and/or time (ISO-8601/RFC-3339)"}, {D_TXT, "SEMVR", "Sem. ver. nr.", "Semantic version number (x.y.z)"}, }
FLDTPs are semantic simple fields.
var TableConfig_Contentity = TableConfig{ "contentity", []string{"inbatch"}, ColumnSpecs_Contentity, }
var TableConfig_Inbatch = TableConfig{ "inbatch", nil, ColumnSpecs_Inbatch, }
var TableConfig_Topicref = TableConfig{ "topicref", []string{"map_contentity", "tpc_contentity"}, ColumnSpecs_Topicref, }
var TableSpec_Inbatch = DbTblSpec{D_TBL, "INB", "inbatch", "Batch import of files"}
TableSpec_Inbatch describes the table.
var TableSpec_Topicref = DbTblSpec{D_TBL,
"TRF", "topicref", "Reference from map to topic"}
TableSpec_Topicref describes the table.
Functions ¶
func Ito09az ¶
Ito09az converts its int arg (0..35) to a string of length one, in the range (for int 0..9) "0".."9", (for int 10..35) "a".."z"
func MustExistTable ¶
func MustExistTable(s string)
MustExistTable makes sure it exists but does NOT drop an already-existing table.
func NowAsYMDHM ¶
func NowAsYMDHM() string
NowAsYMDHM maps (reversibly) the current time to "YMDhm" (where m is minutes / 2).
func TestInbatch ¶
rows, _ := db.Query("select * from inbatch;")
Types ¶
type ContentityRecord ¶
type ContentityRecord struct { Idx_Contentity int Idx_Inbatch int // NOTE: Maybe rename to FILESET. And, could be multiple! Descr string FU.PathProps Times XU.AnalysisRecord // contains filtered or unexported fields }
ContentityRecord is basically the content plus its "dead properties" - properties that are set by the user, rather than dynamically determined.
func NewContentityRecord ¶
func NewContentityRecord(pPP *FU.PathProps) *ContentityRecord
NewContentityRecord works for directories and symlinks too. It used to SetError(..), but no longer does.
func (*ContentityRecord) Error ¶
func (p *ContentityRecord) Error() string
Error satisfies interface "error", but the weird thing is that "error" can be nil.
func (*ContentityRecord) GetError ¶
func (p *ContentityRecord) GetError() error
GetError is necessary cos "Error()"" dusnt tell you whether "error" is "nil", which is the indication of no error. Therefore we need this function, which can actually return the telltale "nil".
func (*ContentityRecord) HasError ¶
func (p *ContentityRecord) HasError() bool
func (*ContentityRecord) SetError ¶
func (p *ContentityRecord) SetError(e error)
func (*ContentityRecord) String ¶
func (p *ContentityRecord) String() string
type Datum ¶
type Datum struct { // TxtIntKeyEtc is only D_TXT or D_INT (or D_KEY). See this func's // comment above re. why this is sufficient, at least for SQLite. TxtIntKeyEtc // Code is a short unique string token - no spaces or punctuation. // We use string codes rather than iota-based integer values for // robustness, because values based on iota could change. // (1) When a Datum describes a DB column (or table or row's column // value or table!), Code is the actual name of the DB field/table, // and should be all lower case. // (2) In other uses, Code should be all upper case, and all Codes // in a particular enumeration "should" be of the same length. Code string // Name is a short-form name, for common use incl. column headers. Name string // Descr is a long-form description. Descr string }
Datum is a datum descriptor. It describes a single datum or field/column or field/column value, and is most useful as an element of an enumeration.
type DbColIRL ¶
type DbColIRL DbDescr
DbColIRL describes a column as-is in the DB (as obtained via reflection), and has a slot to include the value (as a string).
type DbColSpec ¶
type DbColSpec DbDescr
DbColSpec specifies a datum (i.e. struct field and/or DB column) and its generic/portable/DB-independent representation (based on the enumeration Datum.TxtIntKeyEtc). Some values for common DB columns are defined in the D_* series in the file semblox/types.go
type FLDTP ¶
type FLDTP Datum
FLDTP describes a simple field that has semantics. Field validation is highly desirable but TBD.
type Inbatch ¶
type Inbatch struct { Idx_Inbatch int FilCt int RelFP string AbsFP FU.AbsFilePath T_Cre string Descr string }
Inbatch describes a single import batch at the CLI.
type MmmcDB ¶
type MmmcDB struct { FU.PathProps // Connection *sqlx.DB // Session-level open Txn (if non-nil). Relevant API: // func (db *sqlx.DB) Beginx() (*sqlx.Tx, error) // func (db *sqlx.DB) MustBegin() *sqlx.Tx // func (tx *sql.Tx) Commit() error // func (tx *sql.Tx) Rollback() error *sqlx.Tx }
MmmcDB stores DB filepaths, DB cnxns, DB txns.
func NewMmmcDB ¶
NewMmmcDB does not open a DB, it merely checks that the given path is OK. That is to say, it initializes path-related variables but does not do more. argpath can be a relative path passed to the CLI; if it is "", the DB path is set to the CWD (current working directory).
func (*MmmcDB) Add_Inbatch ¶
Add_Inbatch adds an input batch to the DB and returns its primary index.
func (*MmmcDB) CreateTable_sqlite ¶
func (pDB *MmmcDB) CreateTable_sqlite(ts TableConfig)
CreateTable_sqlite creates a table for our simplified SQLite DB model where - Every column is either string ("TEXT") or int ("INTEGER"), - Every column is NOT NULL, - Every column has type checking (TBS), and - Every table has a primary index field, and - Every index (primary and foreign) includes the full name of the table, which simplifies column creation and cross-referencing (including JOINs).
func (*MmmcDB) DbTblColsIRL ¶
func (*MmmcDB) DumpTableSchema_sqlite ¶
func (*MmmcDB) DupeCurrentToBackup ¶
DupeCurrentToBackup makes a best effort but can fail if the backup destination is a directory or has a permissions problem. The current DB is not affected.
func (*MmmcDB) ForceEmpty ¶
func (p *MmmcDB) ForceEmpty()
ForceEmpty is a convenience function. It first makes a backup.
func (*MmmcDB) ForceExistDBandTables ¶
func (p *MmmcDB) ForceExistDBandTables()
ForceExistDBandTables creates a new empty DB with the proper schema.
func (*MmmcDB) GetAll_Inbatch ¶
GetAll_Inbatch gets all input batches in the system.
func (*MmmcDB) GetContentityAll ¶
func (p *MmmcDB) GetContentityAll() (pp []*ContentityRecord)
GetContentityAll gets all content in the DB.
func (*MmmcDB) InsertContentityRecord ¶
func (p *MmmcDB) InsertContentityRecord(pC *ContentityRecord) (int, error)
InsertContentityRecord adds a content item (i.e. a file) to the DB.
func (*MmmcDB) MoveCurrentToBackup ¶
MoveCurrentToBackup makes a best effort but can fail if the backup destination is a directory or has a permissions problem. The current DB is renamed and so "disappears" from production.
func (*MmmcDB) TryColumns ¶
TryColumns tries some sqlx stuff.
type TableConfig ¶
TableConfig assumes that when specifying the column types for a DB table, it is enough to use strings and integers. Also a primary key is assumed and foreign keys are allowed. Any field can be nil, except the first (tableName). Obviously the two fields "int*" should be the same length, and also the two fields "str*".
Date-time's are not an issue for SQLite, since either a string or an int can be used. We will favor using strings ("TEXT"), which are expected to be ISO-8601 / RFC 3339. It is the first option listed here: https://www.sqlite.org/datatype3.html#date_and_time_datatype:
- TEXT: "YYYY-MM-DD HH:MM:SS.SSS" (or with "T" in the blank position).
- REAL as Julian day numbers: the day count since 24 November 4714 BC.
- INTEGER as Unix time: the seconds count since 1970-01-01 00:00:00 UTC.
type Topicref ¶
Topicref describes a reference from a Map to a Topic. Note that this does NOT (necessarily) refer to the DITA `topictref` element!
The relationship is N-to-N btwn Maps and Topics, so `schemaTREF` might not be unique because a topic might be explicitly referenced more than once by a map. So for simplicity, let's create only one `schemaTREF` per topic per map file, and see if it creates problems elsewhere later on.
type TxtIntKeyEtc ¶
type TxtIntKeyEtc string