Greg Slepak avatar Greg Slepak committed fd1f68a

new functions in util.lsp and updated Sqlite3 for DF.DB

Comments (0)

Files changed (7)

 
   * added DF.DB and ObjNL
   * updated documentation
-  * create /tmp on windows if necessary
+  * improved windows compatibility by creating /tmp if necessary
+  * improved the 'load-once' function (load replacement)
+  * added new add-to-load-path and wrap-func functions to utils.lsp
 
 Version 0.51
 

example-site/dragonfly-api/dragonfly.lsp.html

 
 
 
-
 <br/><br/><center>- &sect; -</center><br/>
 <a name="_STDOUT"></a><h3><font color=#CC0000>STDOUT</font></h3>
 <b>syntax: STDOUT</b><br/>

example-site/dragonfly-api/index.html

 <p></p>
 <a href="response.lsp.html#Response_status">status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_header">header</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_cookie">cookie</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers">send-headers</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_redirect">redirect</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers-with-status">send-headers-with-status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_content-type">content-type</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_extension->type">extension->type</a>&nbsp; &nbsp; <a href="utils.lsp.html"><br/><br/><h2>Module:&nbsp;utils.lsp</h2></a>
 <p></p>
-<a href="utils.lsp.html#_regex-captcha">regex-captcha</a>&nbsp; &nbsp; <a href="utils.lsp.html#_load-files-in-dir">load-files-in-dir</a>&nbsp; &nbsp; <a href="utils.lsp.html#_into-ctx-assoc">into-ctx-assoc</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html"><br/><br/><h2>Module:&nbsp;ObjNL.lsp</h2></a>
+<a href="utils.lsp.html#_add-to-load-path">add-to-load-path</a>&nbsp; &nbsp; <a href="utils.lsp.html#_regex-captcha">regex-captcha</a>&nbsp; &nbsp; <a href="utils.lsp.html#_load-files-in-dir">load-files-in-dir</a>&nbsp; &nbsp; <a href="utils.lsp.html#_wrap-func">wrap-func</a>&nbsp; &nbsp; <a href="utils.lsp.html#_into-ctx-assoc">into-ctx-assoc</a>&nbsp; &nbsp; <a href="utils.lsp.html#_NEWLISP64">NEWLISP64</a>&nbsp; &nbsp; <a href="utils.lsp.html#_get-ptr">get-ptr</a>&nbsp; &nbsp; <a href="utils.lsp.html#_throw-not-implemented">throw-not-implemented</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html"><br/><br/><h2>Module:&nbsp;ObjNL.lsp</h2></a>
 <p>Objective newLISP - Real Object Oriented Programming for newLISP</p>
 <a href="ObjNL.lsp.html#_ObjNL">ObjNL</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_ObjNL">ObjNL</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_dealloc">dealloc</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_equals">equals</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_new-class">new-class</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_instantiate">instantiate</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_add-interface">add-interface</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_deallocate">deallocate</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_implements?">implements?</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_retain">retain</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_release">release</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_autorelease">autorelease</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_push-autorelease-pool">push-autorelease-pool</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_pop-autorelease-pool">pop-autorelease-pool</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_.">.</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_.&">.&</a>&nbsp; &nbsp; 
 <br/><br/><center>- &part; -</center><br/>

example-site/dragonfly-api/utils.lsp.html

  Dragonfly to ensure pages are displayed properly.</p>
 
 <br/><br/><center>- &sect; -</center><br/>
+<a name="_add-to-load-path"></a><h3><font color=#CC0000>add-to-load-path</font></h3>
+<b>syntax: (<font color=#CC0000>add-to-load-path</font> <em>str-path-1</em> <em>str-path-2</em> ...)</b><br/>
+ <p>Dragonfly overrides the built-in function <tt>load</tt> so that files
+ are loaded only once. In addition it supports the concept of "load paths"
+ which can be added using this function. This means that you no longer need
+ to modify third-party code that contains <tt>load</tt> calls to files located in
+ different locations. Simply add a new load path instead.</p>
+ <b>example:</b>
+ <pre> ; the old way
+ (load "MyClass.lsp") ;=> ERROR! MyClass.lsp doesn't exist here!
+ ; we must rewrite the file to point to the new location of MyClass.lsp:
+ (load "../../myfolder/MyClass.lsp")
+ ; -------------------------------
+ ; New way, using add-to-load-path
+ ; -------------------------------
+ (add-to-load-path "../../myfolder")
+ ; no need to update any source files, it just works.</pre>
+ <b>warning:</b> Use this function sparingly as name-conflicts could
+ result in the wrong file being loaded!
+<br/><br/><center>- &sect; -</center><br/>
 <a name="_regex-captcha"></a><h3><font color=#CC0000>regex-captcha</font></h3>
 <b>syntax: (<font color=#CC0000>regex-captcha</font> <em>str-regex</em> <em>str</em> [<em>int-options</em>] [<em>int-captcha</em>])</b><br/>
 <b>parameter: </b><em>int-options</em> - options to regex, defaults to 0.<br/>
  traverse subdirectories.<br/>This is a global function.</p>
 <br/><br/>
 <br/><br/><center>- &sect; -</center><br/>
+<a name="_wrap-func"></a><h3><font color=#CC0000>wrap-func</font></h3>
+<b>syntax: (<font color=#CC0000>wrap-func</font> <em>func</em> <em>lambda</em>)</b><br/>
+ <p>Replaces <em>func</em> with <em>lambda</em>. Inside of <em>lambda</em> use <tt>wrapped-func</tt> to refer
+ to the original function. This can be very handy for "aspect oriented programming".</p>
+ <b>example:</b>
+ <pre> (wrap-func db:execute-update
+     (fn () (unless (apply wrapped-func $args)
+         (throw-error (string "execute-update failed: " $args)))))</pre>
+
+<br/><br/><center>- &sect; -</center><br/>
 <a name="_into-ctx-assoc"></a><h3><font color=#CC0000>into-ctx-assoc</font></h3>
 <b>syntax: (<font color=#CC0000>into-ctx-assoc</font> <em>ctx</em> <em>list-assoc</em>)</b><br/>
  <p>Places the key/value pairs in <em>list-assoc</em> into the context <em>ctx</em>
      ("organic?" true)
  ))</pre>
 <br/><br/>
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_NEWLISP64"></a><h3><font color=#CC0000>NEWLISP64</font></h3>
+<b>syntax: NEWLISP64</b><br/>
+ <p>A constant that is <tt>true</tt> if we're running the 64-bit version of newLISP.</p>
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_get-ptr"></a><h3><font color=#CC0000>get-ptr</font></h3>
+<b>syntax: (<font color=#CC0000>get-ptr</font> <em>symbol</em>)</b><br/>
+ <p>Alias for <tt>get-long</tt> on 64-bit systems, and <tt>get-int</tt> on 32-bit systems.</p>
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_throw-not-implemented"></a><h3><font color=#CC0000>throw-not-implemented</font></h3>
+<b>syntax: (<font color=#CC0000>throw-not-implemented</font>)</b><br/>
+ <p>Used to indicate that an ObjNL method *must* be overwritten.</p>
+
 
 <br/><br/><center>- &part; -</center><br/>
 <center><font face='Arial' size='-2' color='#444444'>

example-site/dragonfly-framework/lib/utils.lsp

 ; This may also speed up the loading of this file the second time around.
 (unless load-once
 	
+	(setf load-once.lp '()) ; empty load path initially
+	(new Tree 'load-once.loaded)
+	
+;; @syntax (add-to-load-path <str-path-1> <str-path-2> ...)
+;; <p>Dragonfly overrides the built-in function 'load' so that files
+;; are loaded only once. In addition it supports the concept of "load paths"
+;; which can be added using this function. This means that you no longer need
+;; to modify third-party code that contains 'load' calls to files located in
+;; different locations. Simply add a new load path instead.</p>
+;; <b>example:</b>
+;; <pre> ; the old way
+;; (load "MyClass.lsp") ;=> ERROR! MyClass.lsp doesn't exist here!
+;; ; we must rewrite the file to point to the new location of MyClass.lsp:
+;; (load "../../myfolder/MyClass.lsp")
+;; ; -------------------------------
+;; ; New way, using add-to-load-path
+;; ; -------------------------------
+;; (add-to-load-path "../../myfolder")
+;; ; no need to update any source files, it just works.</pre>
+;; <b>warning:</b> Use this function sparingly as name-conflicts could
+;; result in the wrong file being loaded!
+	(define (add-to-load-path)
+		(doargs (path)
+			(setf load-once.lp (unique (push (real-path path) load-once.lp)))
+		)
+	)
+	
 	(define (load-once)
 		; check if the last argument is a context (to behave like 'load' does)
-		(let (ctx (let (_ctx (last $args)) (if (context? _ctx) _ctx MAIN)))
-			(doargs (file)
-				(unless (or (context? file) (find file load-once.loaded))
-					(push file load-once.loaded)
+		(let (ctx (let (_ctx (last $args)) (if (context? _ctx) _ctx MAIN)) filename nil)
+			(doargs (file (context? file))
+				(setf filename file)
+				(dolist (lp load-once.lp (file? file))
+					(setf file (string lp "/" filename))
+				)
+				(unless (setf file (real-path file))
+					(throw-error (string "cannot load file: " filename))
+				)
+				(when (not (load-once.loaded file))
+					(load-once.loaded file true)
 					(sys-load file ctx)
 				)
 			)
 			(load-once (string dir "/" x))
 		)
 	)
+	
+;; @syntax (wrap-func <func> <lambda>)
+;; <p>Replaces <func> with <lambda>. Inside of <lambda> use 'wrapped-func' to refer
+;; to the original function. This can be very handy for "aspect oriented programming".</p>
+;; <b>example:</b>
+;; <pre> (wrap-func db:execute-update
+;;     (fn () (unless (apply wrapped-func $args)
+;;         (throw-error (string "execute-update failed: " $args)))))</pre>
+	(define-macro (wrap-func func-sym wrapper , wrapped-func)
+		(setf wrapped-func (sym (string func-sym "|wrapped#" (inc wrap-func.counter))))
+		(set wrapped-func (eval func-sym))
+		(set func-sym (eval (expand wrapper 'wrapped-func)))
+	)
 
 ;; @syntax (into-ctx-assoc <ctx> <list-assoc>)
 ;; <p>Places the key/value pairs in <list-assoc> into the context <ctx>
 ;; ))</pre>
 ;; 
 	(define (into-ctx-assoc ctx assoc-list)
-		(dolist (x assoc-list) (ctx (x 0) (x 1))) ; here dolist is slightly faster than map
+		; dolist is slightly faster than map
+		(dolist (x assoc-list) (ctx (first x) (last x)))
 	)
 	
 	; these functions should be global (define-subclass should not)
-	(global 'load-files-in-dir 'regex-captcha 'load-once 'into-ctx-assoc)
+	(global 'load-files-in-dir 'regex-captcha 'load-once
+		'wrap-func 'into-ctx-assoc 'add-to-load-path
+	)
 	
 	; swap these functions for ours and save the originals
 	(constant (global 'sys-load) load)
 	(constant (global 'sys-println) println)
 	(constant 'println Dragonfly:println)
 	
-	; some other useful globals (primarily used by database.lsp)
+;; @syntax NEWLISP64
+;; <p>A constant that is 'true' if we're running the 64-bit version of newLISP.</p>
 	(constant (global 'NEWLISP64) (not (zero? (& (sys-info -1) 256))))
-	; cache the function for getting a pointer
+;; @syntax (get-ptr <symbol>)
+;; <p>Alias for 'get-long' on 64-bit systems, and 'get-int' on 32-bit systems.</p>
 	(constant (global 'get-ptr) (if NEWLISP64 get-long get-int))
-	; used to indicate that a method *must* be overwritten
+;; @syntax (throw-not-implemented)
+;; <p>Used to indicate that an ObjNL method *must* be overwritten.</p>
 	(constant (global 'throw-not-implemented) (fn()(throw-error "not defined by subclass!")))
 )
 

example-site/dragonfly-framework/plugins-inactive/db/database_sqlite3.lsp

 ;; @module Sqlite3
 ;; @description SQLite3 subclass of DF.DB. Only lists Sqlite3 specific functions.
-;; @version 1.1
+;; @version 1.1.1
 ;; @author Greg Slepak 
 ;; @location http://www.taoeffect.com/newlisp/database_sqlite3.lsp.txt
 ;; <h3>Features not found in newLISP's sqlite3.lsp:</h3>
 ;; <h3>Requirements</h3>
 ;; See module @link http://www.taoeffect.com/newlisp/database.lsp.html DF.DB for requirements.
 ;; <h3>Version history</h3>
-;; <b>1.1</b> &bull; support for 'DF.BLOB'<br/>
-;; <b>1.0</b> &bull; initial release
+;; <b>1.1.1</b> &bull; improved readability in error logging, fixed binding of integers on 32-bit newlisp builds<br/>
+;; <b>1.1.0</b> &bull; support for 'DF.BLOB'<br/>
+;; <b>1.0.0</b> &bull; initial release
 
 (DF:activate-plugin "db/database")
 
 			(set 'error-msg nil)
 			(set 'error-msg (get-string error-msg))
 		)
-		(DF:log-err action " => " (last-error))
+		(setf action (string action))
+		(replace (string @self ":") action "") ; make it more readable
+		(DF:log-err "[" @self "] " action " => " (last-error))
 		nil ; indicate failure
 	)
 )
 	"sqlite3_column_count"   "sqlite3_finalize"      "sqlite3_bind_parameter_index"
 	"sqlite3_column_name"    "sqlite3_reset"         "sqlite3_transfer_bindings"  
 	"sqlite3_column_type"    "sqlite3_errmsg"        "sqlite3_step"
-	"sqlite3_bind_int64"     "sqlite3_column_int64"      
+	"sqlite3_bind_int64"     "sqlite3_column_int64"      "sqlite3_bind_int"
 	"sqlite3_bind_double"    "sqlite3_column_double"     
 	"sqlite3_bind_null"      "sqlite3_column_text"       
 	"sqlite3_bind_text"      "sqlite3_column_blob"       
 ;---------------------------------------------------------------
 
 (define (Sqlite3.SQL:Sqlite3.SQL _db _stmt _sql)
-	; the Sqlite3 db context (or sub-context)
-	(set 'db _db)
-	; the sqlite3_stmt pointer
-	(set 'stmt _stmt)
-	; the original SQL (in case of SQLITE_SCHEMA)
-	(set 'sql _sql)
-	; the number of columns in this table
-	(set 'num-cols (sqlite3_column_count stmt))
+	(set 'db       _db                         ; the Sqlite3 db context (or sub-context)
+	     'stmt     _stmt                       ; the sqlite3_stmt pointer
+	     'sql      _sql                        ; the original SQL (in case of SQLITE_SCHEMA)
+	     'num-cols (sqlite3_column_count stmt) ; the number of columns in this table
+	)
 	; the column types
 	(dotimes (idx num-cols)
 		; idx is a double so we use 'int' to convert it
 ; !Sqlite3.SQL - Binding
 ;---------------------------------------------------------------
 
+(define (bind-int64)
+	(failable (sqlite3_bind_int64 stmt idx value))
+)
+
+(define (bind-int32)
+	(failable (sqlite3_bind_int stmt idx value))
+)
+
+(setf bind-int (if NEWLISP64 bind-int64 bind-int32))
+
 (define (bind-param-at-index stmt value idx)
 	(cond
-		((integer? value) (failable (sqlite3_bind_int64 stmt idx value)))
+		((integer? value) (bind-int))
 		((string? value) (failable (sqlite3_bind_text stmt idx value (length value) -1)))
 		((float? value) (failable (sqlite3_bind_double stmt idx value)))
 		((nil? value) (failable (sqlite3_bind_null stmt idx)))

example-site/includes/css/screen.css

 		line-height:15px;
 		font-size: 11px;
 	}
+	
+	#api-browser blockquote em {
+		font-style: italic;
+	}
 
 	#api-browser blockquote h3 {
 		font-size:18px;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.