(index-by-name :accessor index-by-name
:initform (make-hash-table :size 128 :test 'equal))
(meta-index :accessor meta-index :initform (make-array 5))
- (meta-meta :accessor meta-meta :initform (make-array 5))))
+ (meta-meta :accessor meta-meta :initform (make-array 5))
+ (user-log :accessor user-log :initarg :user-log)))
(defgeneric get-table (xdump-parser table-name))
(defgeneric get-table-entry (xdump-parser table-name index))
(defgeneric header-parser (xdump-parser line))
(defgeneric parse-line (xdump-parser line))
(defgeneric reset-table-parser (xdump-parser))
+(defgeneric flush-log (xdump-parser))
(defgeneric entry-from-vector (xdump-parser class meta-table entry-vector
&key array-support-p))
(defun table (table-name &optional (parser *current-parser*))
(get-table parser table-name))
+(defun checkpoint (&optional (parser *current-parser*))
+ (flush-log parser))
+
(defmethod get-table-entry ((parser xdump-parser) table-name index)
- (aref (table-entries (get-table table-name)) index))
+ (aref (table-entries (get-table parser table-name)) index))
(defmethod sym-by-value ((parser xdump-parser) table-name value)
(with-slots (table-classes-package) parser
name nil
timestamp nil)))
-(defun meta-meta-finalizer (parser)
- (with-slots (entry-buffer meta-index meta-meta) parser
+(defun define-meta-table (entry-buffer)
+ (with-slots (meta-index meta-meta user-log) *current-parser*
+ (print `(define-meta-table ,entry-buffer) user-log)
; build meta-index from integer index to
; slot symbol
(loop
do (setf (slot-value meta-meta-column slot) field))
(setf (aref meta-meta i) meta-meta-column)))))
+(defun meta-meta-finalizer (parser)
+ (with-parser parser
+ (define-meta-table (entry-buffer parser))))
+
(defun table-entry-defclass-form (name class-name package slot-list)
`(defclass ,(find-symbol class-name package) ()
,(mapcar #'(lambda (raw-slot-name)
:accessor (intern accessor-name package))))
slot-list)))
-(defun meta-finalizer (parser)
+(defun define-table (name entry-buffer)
(let ((meta-table (make-array 1 :fill-pointer 0 :adjustable t)))
- (with-slots (entry-buffer name meta-index meta-by-index index-by-name
- table-by-index)
- parser
+ (with-slots (meta-index meta-by-index index-by-name table-by-index user-log)
+ *current-parser*
+ (print `(define-table ,name ,entry-buffer) user-log)
(loop for entry across entry-buffer
do (let ((meta (make-instance 'table-column-meta)))
(loop for slot across meta-index
for field in entry
do (setf (slot-value meta slot) field))
(vector-push-extend meta meta-table)))
- (format t "~a~%~a~%~a~%" name meta-table entry-buffer)
(let ((table-index (if (string= "table" name)
; voodoo: the first column of the table of tables
; is the uid
;; create xdump-table instance and entry class
(let* ((class-name (string-upcase (format nil "~a-table-entry" name)))
- (package (table-classes-package parser))
+ (package (table-classes-package *current-parser*))
(table-instance (make-instance 'xdump-table
:name name
:index table-index
(slot-list (loop for entry across entry-buffer
collect (car entry))))
(setf (aref table-by-index table-index) table-instance)
- (format t "slot-list: ~a~%" slot-list)
(eval (table-entry-defclass-form name class-name package
slot-list)))))))
+(defun meta-finalizer (parser)
+ (with-parser parser
+ (with-slots (name entry-buffer) parser
+ (define-table name entry-buffer))))
+
(defmethod array-p ((parser xdump-parser) column)
(let ((column-len (meta-len column))
(column-type (sym-by-value parser "meta-type" (meta-type column))))
:initial-element nil))
(setf (aref entries index) entry)))
-(defun table-finalizer (parser)
- (with-slots (entry-buffer name timestamp index-by-name meta-by-index
- table-by-index table-classes-package) parser
+(defun load-table (name timestamp entry-buffer)
+ (with-slots (index-by-name meta-by-index table-by-index table-classes-package
+ user-log)
+ *current-parser*
+ (print `(load-table ,name ,timestamp ,entry-buffer) user-log)
(if (string= name "table") ; special magic: prefill index-by-name
(loop for entry across entry-buffer do
(setf (gethash (second entry) index-by-name) (first entry))))
- (format t "table-finalizer: ~a~%" name)
(let* ((table-index (gethash name index-by-name))
(meta-table (aref meta-by-index table-index))
(table (aref table-by-index table-index))
(array-support-p (not (or (string= name "table")
(string= name "meta-type")))))
(loop for entry across entry-buffer do
- (let ((entry-instance (entry-from-vector parser
+ (let ((entry-instance (entry-from-vector *current-parser*
(table-entry-class table)
meta-table
entry
(vector-push-extend entry-instance (table-entries table)))))
(setf (table-last-update table) timestamp))))
+(defun table-finalizer (parser)
+ (with-parser parser
+ (with-slots (name timestamp entry-buffer) parser
+ (load-table name timestamp entry-buffer))))
+
(defmethod finish-table ((parser xdump-parser) number-of-records)
(if (not (equal number-of-records (length (entry-buffer parser))))
(error "Table row count mismatch"))
(parse-table parser name timestamp)))))
nil)
-(defun make-parser ()
- (let ((parser (make-instance 'xdump-parser)))
+(defun make-parser (&key user-log)
+ (let ((parser (make-instance 'xdump-parser :user-log user-log)))
(setf (line-parser parser) #'header-parser)
parser))
(with-open-file (s filename)
(parse-stream parser s)))
+(defmethod flush-log ((parser xdump-parser))
+ (finish-output (user-log parser)))
+
(defun t1 ()
(let ((parser (make-parser)))
(setf *current-parser* parser)