]> gitweb.factorcode.org Git - factor.git/commitdiff
New furnace.alloy vocab makes things easier; add expiration for asides and flash...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 14 Jun 2008 01:54:52 +0000 (20:54 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 14 Jun 2008 01:54:52 +0000 (20:54 -0500)
18 files changed:
extra/furnace/alloy/alloy.factor [new file with mode: 0644]
extra/furnace/asides/asides.factor
extra/furnace/auth/providers/db/db-tests.factor
extra/furnace/auth/providers/db/db.factor
extra/furnace/cache/cache.factor [new file with mode: 0644]
extra/furnace/flash/flash.factor
extra/furnace/sessions/sessions-tests.factor
extra/furnace/sessions/sessions.factor
extra/http/http-tests.factor
extra/http/server/server.factor
extra/persistent-vectors/persistent-vectors-tests.factor
extra/webapps/blogs/blogs.factor
extra/webapps/factor-website/factor-website.factor
extra/webapps/pastebin/pastebin.factor
extra/webapps/planet/planet.factor
extra/webapps/todo/todo.factor
extra/webapps/wee-url/wee-url.factor
extra/webapps/wiki/wiki.factor

diff --git a/extra/furnace/alloy/alloy.factor b/extra/furnace/alloy/alloy.factor
new file mode 100644 (file)
index 0000000..24b47cc
--- /dev/null
@@ -0,0 +1,24 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences db.tuples alarms calendar db fry
+furnace.cache
+furnace.asides
+furnace.flash
+furnace.sessions
+furnace.db
+furnace.auth.providers ;
+IN: furnace.alloy
+
+: <alloy> ( responder db params -- responder' )
+    [ <asides> <flash-scopes> <sessions> ] 2dip <db-persistence> ;
+
+: state-classes { session flash-scope aside } ; inline
+
+: init-furnace-tables ( -- )
+    state-classes ensure-tables
+    user ensure-table ;
+
+: start-expiring ( db params -- )
+    '[
+        , , [ state-classes [ expire-state ] each ] with-db
+    ] 5 minutes every drop ;
index f6b4e2c15f3df4677faae5e66a265360437cf792..fc767e050d5e2a60c540f2e311a1dac43d978764 100644 (file)
@@ -2,37 +2,60 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors namespaces sequences arrays kernel
 assocs assocs.lib hashtables math.parser urls combinators
-furnace http http.server http.server.filters furnace.sessions
-html.elements html.templates.chloe.syntax ;
+html.elements html.templates.chloe.syntax db.types db.tuples
+http http.server http.server.filters 
+furnace furnace.cache furnace.sessions ;
 IN: furnace.asides
 
-TUPLE: asides < filter-responder ;
+TUPLE: aside < server-state session method url post-data ;
 
-C: <asides> asides
+: <aside> ( id -- aside )
+    aside new-server-state ;
+
+aside "ASIDES"
+{
+    { "session" "SESSION" BIG-INTEGER +not-null+ }
+    { "method" "METHOD" { VARCHAR 10 } +not-null+ }
+    { "url" "URL" URL +not-null+ }
+    { "post-data" "POST_DATA" FACTOR-BLOB }
+} define-persistent
+
+TUPLE: asides < server-state-manager ;
+
+: <asides> ( responder -- responder' )
+    asides new-server-state-manager ;
 
 : begin-aside* ( -- id )
-    request get
-    [ url>> ] [ post-data>> ] [ method>> ] tri 3array
-    asides sget set-at-unique
-    session-changed ;
+    f <aside>
+        session get id>> >>session
+        request get
+        [ method>> >>method ]
+        [ url>> >>url ]
+        [ post-data>> >>post-data ]
+        tri
+    [ asides get touch-state ] [ insert-tuple ] [ id>> ] tri ;
 
-: end-aside-post ( url post-data -- response )
+: end-aside-post ( aside -- response )
     request [
         clone
-            swap >>post-data
-            swap >>url
+            over post-data>> >>post-data
+            over url>> >>url
     ] change
-    request get url>> path>> split-path
+    url>> path>> split-path
     asides get responder>> call-responder ;
 
 ERROR: end-aside-in-get-error ;
 
+: get-aside ( id -- aside )
+    dup [ aside get-state ] when
+    dup [ dup session>> session get id>> = [ drop f ] unless ] when ;
+
 : end-aside* ( url id -- response )
     request get method>> "POST" = [ end-aside-in-get-error ] unless
-    asides sget at [
-        first3 {
-            { "GET" [ drop <redirect> ] }
-            { "HEAD" [ drop <redirect> ] }
+    aside get-state [
+        dup method>> {
+            { "GET" [ url>> <redirect> ] }
+            { "HEAD" [ url>> <redirect> ] }
             { "POST" [ end-aside-post ] }
         } case
     ] [ <redirect> ] ?if ;
@@ -47,13 +70,12 @@ SYMBOL: aside-id
 : end-aside ( default -- response )
     aside-id [ f ] change end-aside* ;
 
+: request-aside-id ( request -- aside-id )
+    aside-id-key swap request-params at string>number ;
+
 M: asides call-responder*
     dup asides set
-    aside-id-key request get request-params at aside-id set
-    call-next-method ;
-
-M: asides init-session*
-    H{ } clone asides sset
+    request get request-aside-id aside-id set
     call-next-method ;
 
 M: asides link-attr ( tag -- )
index 714dcb416fb1b73a34bf32c92a877aeddbcbf976..e5914c7ab336ff0d4988472df525ac65d8cbed45 100755 (executable)
@@ -14,7 +14,7 @@ login set
 \r
 "auth-test.db" temp-file sqlite-db [\r
 \r
-    init-users-table\r
+    user ensure-table\r
 \r
     [ t ] [\r
         "slava" <user>\r
index 66c1b3ec99d3daef5e4e44c2c793d762da6b460f..72eb0d462a18a50dbc63dac6b823edb5132a9695 100755 (executable)
@@ -18,8 +18,6 @@ user "USERS"
     { "deleted" "DELETED" INTEGER +not-null+ }
 } define-persistent
 
-: init-users-table ( -- ) user ensure-table ;
-
 SINGLETON: users-in-db
 
 M: users-in-db get-user
diff --git a/extra/furnace/cache/cache.factor b/extra/furnace/cache/cache.factor
new file mode 100644 (file)
index 0000000..a614a52
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors math.intervals
+calendar alarms fry
+random db db.tuples db.types
+http.server.filters ;
+IN: furnace.cache
+
+TUPLE: server-state id expires ;
+
+: new-server-state ( id class -- server-state )
+    new swap >>id ; inline
+
+server-state f
+{
+    { "id" "ID" +random-id+ system-random-generator }
+    { "expires" "EXPIRES" TIMESTAMP +not-null+ }
+} define-persistent
+
+: get-state ( id class -- state )
+    new-server-state select-tuple ;
+
+: expire-state ( class -- )
+    new
+        -1.0/0.0 now [a,b] >>expires
+    delete-tuples ;
+
+TUPLE: server-state-manager < filter-responder timeout ;
+
+: new-server-state-manager ( responder class -- responder' )
+    new
+        swap >>responder
+        20 minutes >>timeout ; inline
+    
+: touch-state ( state manager -- )
+    timeout>> from-now >>expires drop ;
index 21fd20ccb484181240fbe02535507739381d7a7e..43e0d293a5a82415315415555a133ac456d35ac0 100644 (file)
@@ -1,38 +1,59 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces assocs assocs.lib kernel sequences urls
+USING: namespaces assocs assocs.lib kernel sequences accessors
+urls db.types db.tuples math.parser fry
 http http.server http.server.filters http.server.redirection
-furnace furnace.sessions ;
+furnace furnace.cache furnace.sessions ;
 IN: furnace.flash
 
+TUPLE: flash-scope < server-state session namespace ;
+
+: <flash-scope> ( id -- aside )
+    flash-scope new-server-state ;
+
+flash-scope "FLASH_SCOPES" {
+    { "session" "SESSION" BIG-INTEGER +not-null+ }
+    { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ }
+} define-persistent
+
 : flash-id-key "__f" ;
 
-TUPLE: flash-scopes < filter-responder ;
+TUPLE: flash-scopes < server-state-manager ;
 
-C: <flash-scopes> flash-scopes
+: <flash-scopes> ( responder -- responder' )
+    flash-scopes new-server-state-manager ;
 
 SYMBOL: flash-scope
 
 : fget ( key -- value ) flash-scope get at ;
 
-M: flash-scopes call-responder*
-    flash-id-key
-    request get request-params at
-    flash-scopes sget at flash-scope set
-    call-next-method ;
+: get-flash-scope ( id -- flash-scope )
+    dup [ flash-scope get-state ] when
+    dup [ dup session>> session get id>> = [ drop f ] unless ] when ;
+
+: request-flash-scope ( request -- flash-scope )
+    flash-id-key swap request-params at string>number get-flash-scope ;
 
-M: flash-scopes init-session*
-    H{ } clone flash-scopes sset
+M: flash-scopes call-responder*
+    dup flash-scopes set
+    request get request-flash-scope flash-scope set
     call-next-method ;
 
 : make-flash-scope ( seq -- id )
-    [ dup get ] H{ } map>assoc flash-scopes sget set-at-unique
-    session-changed ;
+    f <flash-scope>
+        session get id>> >>session
+        swap [ dup get ] H{ } map>assoc >>namespace
+    [ flash-scopes get touch-state ] [ insert-tuple ] [ id>> ] tri ;
 
 : <flash-redirect> ( url seq -- response )
-    make-flash-scope
-    [ clone ] dip flash-id-key set-query-param
+    [ clone ] dip
+    make-flash-scope flash-id-key set-query-param
     <redirect> ;
 
 : restore-flash ( seq -- )
-    [ flash-scope get key? ] filter [ [ fget ] keep set ] each ;
+    flash-scope get dup [
+        namespace>>
+        [ '[ , key? ] filter ]
+        [ '[ [ , at ] keep set ] each ]
+        bi
+    ] [ 2drop ] if ;
index a7a663ffa88f915efe0ae75d02f8b9e99392c64a..e203a6fd40643b1e71839d87fe289a5d6250513a 100755 (executable)
@@ -3,7 +3,7 @@ USING: tools.test http furnace.sessions
 furnace.actions http.server http.server.responses\r
 math namespaces kernel accessors\r
 prettyprint io.streams.string io.files splitting destructors\r
-sequences db db.sqlite continuations urls math.parser\r
+sequences db db.tuples db.sqlite continuations urls math.parser\r
 furnace ;\r
 \r
 : with-session\r
@@ -54,7 +54,7 @@ M: foo call-responder*
 "auth-test.db" temp-file sqlite-db [\r
 \r
     <request> init-request\r
-    init-sessions-table\r
+    session ensure-table\r
 \r
     [ ] [\r
         <foo> <sessions>\r
index b046ee40eb63c5691688bc62310c8c662553d8d0..0c0788a1e62cda788562c2061b56ffb65176a496 100755 (executable)
@@ -5,36 +5,23 @@ random accessors quotations hashtables sequences continuations
 fry calendar combinators destructors alarms
 db db.tuples db.types
 http http.server http.server.dispatchers http.server.filters
-html.elements furnace ;
+html.elements
+furnace furnace.cache ;
 IN: furnace.sessions
 
-TUPLE: session id expires uid namespace changed? ;
+TUPLE: session < server-state uid namespace changed? ;
 
 : <session> ( id -- session )
-    session new
-        swap >>id ;
+    session new-server-state ;
 
 session "SESSIONS"
 {
-    { "id" "ID" +random-id+ system-random-generator }
-    { "expires" "EXPIRES" TIMESTAMP +not-null+ }
     { "uid" "UID" { VARCHAR 255 } }
-    { "namespace" "NAMESPACE" FACTOR-BLOB }
+    { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ }
 } define-persistent
 
 : get-session ( id -- session )
-    dup [ <session> select-tuple ] when ;
-
-: init-sessions-table ( -- ) session ensure-table ;
-
-: start-expiring-sessions ( db seq -- )
-    '[
-        , , [
-            session new
-                -1.0/0.0 now [a,b] >>expires
-            delete-tuples
-        ] with-db
-    ] 5 minutes every drop ;
+    dup [ session get-state ] when ;
 
 GENERIC: init-session* ( responder -- )
 
@@ -47,9 +34,7 @@ M: filter-responder init-session* responder>> init-session* ;
 TUPLE: sessions < filter-responder timeout domain ;
 
 : <sessions> ( responder -- responder' )
-    sessions new
-        swap >>responder
-        20 minutes >>timeout ;
+    sessions new-server-state-manager ;
 
 : (session-changed) ( session -- )
     t >>changed? drop ;
@@ -78,11 +63,8 @@ TUPLE: sessions < filter-responder timeout domain ;
 : init-session ( session -- )
     session [ sessions get init-session* ] with-variable ;
 
-: cutoff-time ( -- time )
-    sessions get timeout>> from-now ;
-
 : touch-session ( session -- )
-    cutoff-time >>expires drop ;
+    sessions get touch-state ;
 
 : empty-session ( -- session )
     f <session>
index aa11dd67987a87196677c9b4cacd993ea11753d3..d9b26341e7614bd1d8b1cdea2c1d82175068249f 100755 (executable)
@@ -121,12 +121,12 @@ read-response-test-1' 1array [
 ] unit-test
 
 ! Live-fire exercise
-USING: http.server http.server.static furnace.sessions
+USING: http.server http.server.static furnace.sessions furnace.alloy
 furnace.actions furnace.auth.login furnace.db http.client
 io.server io.files io io.encodings.ascii
 accessors namespaces threads
 http.server.responses http.server.redirection
-http.server.dispatchers ;
+http.server.dispatchers db.tuples ;
 
 : add-quit-action
     <action>
@@ -138,7 +138,7 @@ http.server.dispatchers ;
 [ test-db drop delete-file ] ignore-errors
 
 test-db [
-    init-sessions-table
+    init-furnace-tables
 ] with-db
 
 [ ] [
@@ -269,7 +269,7 @@ SYMBOL: a
 ! Test flash scope
 [ "xyz" ] [
     H{ { "a" "xyz" } { "__u" "http://localhost:1237/" } } "session-id" get session-id-key associate assoc-union
-    "http://localhost:1237/" <post-request> "cookies" get >>cookies http-request nip test-a
+    "http://localhost:1237/" <post-request> "cookies" get >>cookies http-request nip test-a
 ] unit-test
 
 [ 4 ] [ a get-global ] unit-test
index 376889b46b65c0ee940ca3908702e403b2a72860..8e3d1a586a51a0639831aaf8ed057825e0ce2446 100755 (executable)
@@ -90,13 +90,13 @@ LOG: httpd-hit NOTICE
 : dispatch-request ( request -- response )
     url>> path>> split-path main-responder get call-responder ;
 
-: prepare-request ( request -- request )
+: prepare-request ( request -- )
     [
         local-address get
         [ secure? "https" "http" ? >>protocol ]
         [ port>> '[ , or ] change-port ]
         bi
-    ] change-url ;
+    ] change-url drop ;
 
 : valid-request? ( request -- ? )
     url>> port>> local-address get port>> = ;
index f871c95e1678d2257a10dd740f7d83dd140484aa..a4e4ad33fe6ae127c8d6f435a83970e939f6f862 100644 (file)
@@ -24,7 +24,7 @@ random namespaces vectors math math.order ;
     [ t ] swap [ dup >persistent-vector sequence= ] curry unit-test
 ] each
 
-[ ] [ 10000 [ drop 16 random-bits ] PV{ } map-as "1" set ] unit-test
+[ ] [ 10000 [ 16 random-bits ] PV{ } replicate-as "1" set ] unit-test
 [ ] [ "1" get >vector "2" set ] unit-test
 
 [ t ] [
index 100d4226b7849092898d3caa67bf6fc626f6fcff..38bf065e563f54af75c29aa3baffba4d45969fdf 100644 (file)
@@ -59,8 +59,6 @@ M: post entity-url
 
 : <post> ( id -- post ) \ post new swap >>id ;
 
-: init-posts-table ( -- ) \ post ensure-table ;
-
 TUPLE: comment < entity parent ;
 
 comment "COMMENTS" {
@@ -78,8 +76,6 @@ M: comment entity-url
         swap >>id
         swap >>parent ;
 
-: init-comments-table ( -- ) comment ensure-table ;
-
 : post ( id -- post )
     [ <post> select-tuple ] [ f <comment> select-tuples ] bi
     >>comments ;
index f56a9b5c6f01a0f786bb4e392cb29f7668b90cec..55f7ec7ffa28650ad0034a397f37d26f319308eb 100644 (file)
@@ -2,9 +2,10 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel sequences assocs io.files io.sockets
 io.server
-namespaces db db.sqlite smtp
+namespaces db db.tuples db.sqlite smtp
 http.server
 http.server.dispatchers
+furnace.alloy
 furnace.db
 furnace.asides
 furnace.flash
@@ -25,24 +26,16 @@ IN: webapps.factor-website
 
 : init-factor-db ( -- )
     test-db [
-        init-users-table
-        init-sessions-table
+        init-furnace-tables
 
-        init-pastes-table
-        init-annotations-table
-
-        init-blog-table
-        init-postings-table
-
-        init-todo-table
-
-        init-articles-table
-        init-revisions-table
-
-        init-postings-table
-        init-comments-table
-
-        init-short-url-table
+        {
+            post comment
+            paste annotation
+            blog posting
+            todo
+            short-url
+            article revision
+        } ensure-tables
     ] with-db ;
 
 TUPLE: factor-website < dispatcher ;
@@ -63,8 +56,7 @@ TUPLE: factor-website < dispatcher ;
         allow-edit-profile
     <boilerplate>
         { factor-website "page" } >>template
-    <asides> <flash-scopes> <sessions>
-    test-db <db-persistence> ;
+    test-db <alloy> ;
 
 : init-factor-website ( -- )
     "factorcode.org" 25 <inet> smtp-server set-global
@@ -75,6 +67,6 @@ TUPLE: factor-website < dispatcher ;
     <factor-website> main-responder set-global ;
 
 : start-factor-website ( -- )
-    test-db start-expiring-sessions
+    test-db start-expiring
     test-db start-update-task
     8812 httpd ;
index f6b604c06da3a5cff46b97f52fa98648046bb374..d381adafcd234b8235dceea8087e27e45fa3c78d 100644 (file)
@@ -236,7 +236,3 @@ M: annotation entity-url
         <delete-annotation-action> "delete-annotation" add-responder
     <boilerplate>
         { pastebin "pastebin-common" } >>template ;
-
-: init-pastes-table ( -- ) \ paste ensure-table ;
-
-: init-annotations-table ( -- ) annotation ensure-table ;
index 888d4bd14563ad33911e612518a9d4495a94457a..90b2411fc1f146fa936fc0809475582959f20ad5 100755 (executable)
@@ -49,10 +49,6 @@ posting "POSTINGS"
     { "date" "DATE" TIMESTAMP +not-null+ }
 } define-persistent
 
-: init-blog-table ( -- ) blog ensure-table ;
-
-: init-postings-table ( -- ) posting ensure-table ;
-
 : <blog> ( id -- todo )
     blog new
         swap >>id ;
index 7cad1eb6ae960f29edb2e84295e7d3f61cdea810..077076575435c3ff7bf5a2bedb86a28335d82ddc 100755 (executable)
@@ -28,8 +28,6 @@ todo "TODO"
     { "description" "DESCRIPTION" { VARCHAR 256 } }
 } define-persistent
 
-: init-todo-table ( -- ) todo ensure-table ;
-
 : <todo> ( id -- todo )
     todo new
         swap >>id
index d408c645f3ccc08b4b3893ae5a14b9c6b22b29f0..29c4a60befb9f04b940278005626ff2628decc0c 100644 (file)
@@ -16,9 +16,6 @@ short-url "SHORT_URLS" {
     { "url" "URL" TEXT +not-null+ }
 } define-persistent
 
-: init-short-url-table ( -- )
-    short-url ensure-table ;
-
 : letter-bank ( -- seq )
     CHAR: a CHAR: z [a,b]
     CHAR: A CHAR: Z [a,b]
index 18130f514433b17276931e60b7e04ea851c53705..eb3048a26ce18301b4f934dcd97e5ee79a8a5894 100644 (file)
@@ -46,8 +46,6 @@ article "ARTICLES" {
 
 : <article> ( title -- article ) article new swap >>title ;
 
-: init-articles-table ( -- ) article ensure-table ;
-
 TUPLE: revision id title author date content ;
 
 revision "REVISIONS" {
@@ -71,8 +69,6 @@ M: revision feed-entry-url id>> revision-url ;
 : <revision> ( id -- revision )
     revision new swap >>id ;
 
-: init-revisions-table ( -- ) revision ensure-table ;
-
 : validate-title ( -- )
     { { "title" [ v-one-line ] } } validate-params ;