Grooming + examples.
This commit is contained in:
parent
779e13e83d
commit
3f1e8edf95
119
src/dodb.cl
119
src/dodb.cl
@ -17,63 +17,65 @@
|
||||
(alias ln osicat:make-link)
|
||||
(alias ls osicat:list-directory)
|
||||
|
||||
(defun to-upper-case (some-string)
|
||||
(format nil "~@:(~a~)" some-string))
|
||||
|
||||
; Example: 18 -> 000000000000018.data
|
||||
(defun number->filename (number)
|
||||
(format nil "~15,'0D.data" number))
|
||||
|
||||
; Example: "vehicle" "color" object -> (vehicle-color object) -> "Red"
|
||||
(defun get-object-attribute (struct-name attribute-name object)
|
||||
(funcall ; example: call function "VEHICLE-COLOR"
|
||||
(find-symbol (to-upper-case
|
||||
(concatenate 'string struct-name "-" attribute-name)))
|
||||
object))
|
||||
|
||||
; index = 1-1
|
||||
; partition = 1-n
|
||||
; String Path [String] [String] Int
|
||||
(defstruct db struct-name path (indexes ()) (partitions ()) (current-index 0)
|
||||
; {Int -> struct}
|
||||
(data (make-hash-table))
|
||||
(defstruct db
|
||||
struct-name ; String
|
||||
path ; Path
|
||||
(indexes ()) ; [String]
|
||||
(partitions ()) ; [String]
|
||||
(current-index 0) ; Int
|
||||
(data (make-hash-table)) ; {Int -> struct}
|
||||
)
|
||||
|
||||
(defun db/new (struct-name path)
|
||||
(ensure-directories-exist (concatenate 'string path "/data/"))
|
||||
(make-db :struct-name struct-name :path path))
|
||||
|
||||
; example: db-path/indexes/by_name/
|
||||
(defun db/new-index (database attribute-name)
|
||||
; Create a directory for the indexes.
|
||||
(ensure-directories-exist
|
||||
(concatenate 'string (db-path database) "/indexes/by_" attribute-name "/"))
|
||||
; Add this new index to the list.
|
||||
(push attribute-name (db-indexes database)))
|
||||
; Example: ./storage/cars 18 -> ./storage/cars/data/000000000000018.data
|
||||
; USAGE: when dealing with hash keys from the in-memory db.
|
||||
; The hash key is the number used to build the filename.
|
||||
(defun db/data-filepath (dbpath number)
|
||||
(concatenate 'string dbpath "/data/" (number->filename number)))
|
||||
|
||||
; example: db-path/partitions/by_color/
|
||||
(defun db/new-partition (database attribute-name)
|
||||
; Create a directory for the partitions.
|
||||
(ensure-directories-exist
|
||||
(concatenate 'string (db-path database) "/partitions/by_" attribute-name "/"))
|
||||
; Add this new index to the list.
|
||||
(push attribute-name (db-partitions database)))
|
||||
|
||||
(defun to-upper-case (some-string)
|
||||
(format nil "~@:(~a~)" some-string))
|
||||
|
||||
(defun get-object-attribute (database attribute-name object)
|
||||
(funcall ; example: call function "VEHICLE-COLOR"
|
||||
(find-symbol (to-upper-case
|
||||
(concatenate 'string (db-struct-name database) "-" attribute-name)))
|
||||
object))
|
||||
|
||||
; Example: returns "storage/cars/indexes/by_name/".
|
||||
; Example: returns "./storage/cars/indexes/by_name/".
|
||||
(defun db/index/get-directory-path (database name)
|
||||
(concatenate 'string (db-path database) "/indexes/by_" name "/" ))
|
||||
|
||||
; Example: returns "storage/cars/partitions/by_color/".
|
||||
; Example: returns "./storage/cars/partitions/by_color/Red/".
|
||||
(defun db/partition/get-directory-path (database name value)
|
||||
(concatenate 'string (db-path database) "/partitions/by_" name "/" value "/"))
|
||||
|
||||
; Example: returns "Corvet".
|
||||
(defun db/index/get-filename (database index-name object)
|
||||
(get-object-attribute database index-name object))
|
||||
(get-object-attribute (db-struct-name database) index-name object))
|
||||
|
||||
; Example: database "name" object -> "./storage/cars/indexes/by_name/Corvet".
|
||||
(defun db/index/get-symlink-path (database index-name object)
|
||||
(concatenate 'string
|
||||
(db/index/get-directory-path database index-name)
|
||||
(db/index/get-filename database index-name object)))
|
||||
|
||||
; Example: database "name" object "0000000015.data"
|
||||
; -> (ln "./storage/cars/indexes/by_name/Corvet"
|
||||
; :target "../../data/0000000015.data"
|
||||
; :hard nil)
|
||||
(defun db/index/new (database index-name object file-name)
|
||||
(let ((symlink-path
|
||||
(db/index/get-symlink-path database index-name object)))
|
||||
(let ((symlink-path (db/index/get-symlink-path database index-name object)))
|
||||
|
||||
; Works even when the database directory is moved.
|
||||
(ln symlink-path
|
||||
@ -81,14 +83,20 @@
|
||||
:hard nil)
|
||||
))
|
||||
|
||||
; Example: database "color" object
|
||||
; -> "./storage/cars/partitions/by_color/Red/0000000015.data".
|
||||
(defun db/partition/get-symlink-path (database partition-name object file-name)
|
||||
(concatenate 'string
|
||||
(db/partition/get-directory-path database partition-name
|
||||
; example: "Red"
|
||||
(get-object-attribute database partition-name object))
|
||||
; example: "000000000000018.data"
|
||||
(get-object-attribute (db-struct-name database) partition-name object))
|
||||
; example: "0000000015.data"
|
||||
file-name))
|
||||
|
||||
; Example: database "color" object "0000000015.data"
|
||||
; -> (ln "./storage/cars/partitions/by_color/Red/0000000015.data"
|
||||
; :target "../../../data/0000000015.data"
|
||||
; :hard nil)
|
||||
(defun db/partition/new (database partition-name object file-name)
|
||||
(let ((symlink-path
|
||||
(db/partition/get-symlink-path database partition-name object file-name)))
|
||||
@ -100,9 +108,37 @@
|
||||
:target (concatenate 'string "../../../data/" file-name)
|
||||
:hard nil)))
|
||||
|
||||
; Example: 000000000000018.data
|
||||
; example: db-path/indexes/by_name/
|
||||
(defun db/new-index (database attribute-name)
|
||||
; Create a directory for the indexes.
|
||||
(ensure-directories-exist
|
||||
(concatenate 'string (db-path database) "/indexes/by_" attribute-name "/"))
|
||||
|
||||
; Add this new index to the list.
|
||||
(push attribute-name (db-indexes database))
|
||||
|
||||
; Generate index for all DB elements.
|
||||
(maphash #'(lambda (number element)
|
||||
(db/index/new database attribute-name element (number->filename number)))
|
||||
(db-data database)))
|
||||
|
||||
; example: db-path/partitions/by_color/
|
||||
(defun db/new-partition (database attribute-name)
|
||||
; Create a directory for the partitions.
|
||||
(ensure-directories-exist
|
||||
(concatenate 'string (db-path database) "/partitions/by_" attribute-name "/"))
|
||||
|
||||
; Add this new index to the list.
|
||||
(push attribute-name (db-partitions database))
|
||||
|
||||
; Generate partition for all DB elements.
|
||||
(maphash #'(lambda (number element)
|
||||
(db/partition/new database attribute-name element (number->filename number)))
|
||||
(db-data database)))
|
||||
|
||||
; Example: database -> "000000000000018.data".
|
||||
(defun db/add/new-data-filename (database)
|
||||
(format nil "~15,'0D.data" (db-current-index database)))
|
||||
(number->filename (db-current-index database)))
|
||||
|
||||
; Example: {db-path}/data/000000000000018.data
|
||||
(defun db/add/new-data-filepath (database file-name)
|
||||
@ -111,6 +147,8 @@
|
||||
(defun db/add (database object)
|
||||
(incf (db-current-index database))
|
||||
(let ((file-name (db/add/new-data-filename database)))
|
||||
|
||||
; write object to file
|
||||
(util:write-object-to-file
|
||||
object
|
||||
(db/add/new-data-filepath database file-name))
|
||||
@ -124,6 +162,7 @@
|
||||
do (db/partition/new database partition object file-name)))
|
||||
|
||||
; store new in-memory data
|
||||
; database.data[database.current-index] = object
|
||||
(setf (gethash (db-current-index database) (db-data database)) object))
|
||||
|
||||
; TODO: should we search for the data from the FS or in-memory?
|
||||
@ -143,12 +182,12 @@
|
||||
|
||||
(defparameter cars (db/new "vehicle" "./storage/cars/"))
|
||||
|
||||
(db/add cars (make-vehicle :name "Corvet" :color "Red"))
|
||||
(db/add cars (make-vehicle :name "Deudeuch" :color "Beige"))
|
||||
|
||||
(db/new-index cars "name")
|
||||
(db/new-partition cars "color")
|
||||
|
||||
(db/add cars (make-vehicle :name "Corvet" :color "Red"))
|
||||
(db/add cars (make-vehicle :name "Deudeuch" :color "Beige"))
|
||||
|
||||
(format t "~&~S~&" cars)
|
||||
|
||||
(format t "db/get-by-index ~S~&" (db/get-by-index cars "name" "Corvet"))
|
||||
|
Loading…
Reference in New Issue
Block a user