+(defun %select-objects (type select-fn query)
+ (mapcar (curry 'make-object-from-plist type)
+ (apply select-fn (intern (format nil "*"))
+ (if (string-equal (first query) :from)
+ query
+ (append `(:from ,type) query)))))
+
+(defun select-objects (type &rest query)
+ (%select-objects type #'select query))
+
+(defun select-only-n-objects (n type &rest query)
+ (let ((results (%query `(:limit ,(cons :select
+ (intern (format nil "*"))
+ (if (string-equal (first query) :from)
+ query
+ (append `(:from ,type) query))) ,n))))
+ (if (eql 1 n)
+ (make-object-from-plist type (first results))
+ (mapcar (curry 'make-object-from-plist type) results))))
+
+(defun make-object-from-plist (type plist)
+ (let* ((class (find-class type))
+ (object (make-instance class))
+ (slotds (class-slots class)))
+
+ (loop
+ :for (key val) :on plist :by #'cddr
+ :do
+ (dolist (slotd (remove key slotds
+ :key #'slot-definition-column-name
+ :test-not #'string-equal))
+
+ (setf (slot-value-using-class class object slotd) val))
+ :finally (return (reinitialize-instance object)))))
+
+(defun make-object (type &rest plist)
+ (make-object-from-plist type plist))
+