From a7afae250d4de6f18fe9e98e4ae5621e0d793477 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 1 Jun 2008 00:48:38 -0500 Subject: [PATCH 001/354] clean up code some make \# retries user configurable --- extra/db/db.factor | 4 ++-- extra/db/queries/queries.factor | 10 +++++----- extra/db/sql/sql.factor | 4 +++- extra/db/tuples/tuples.factor | 14 ++++++++------ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/extra/db/db.factor b/extra/db/db.factor index 8d1feca6c7..889eff196c 100755 --- a/extra/db/db.factor +++ b/extra/db/db.factor @@ -35,7 +35,7 @@ HOOK: db-close db ( handle -- ) handle>> db-close ] with-variable ; -TUPLE: statement handle sql in-params out-params bind-params bound? type ; +TUPLE: statement handle sql in-params out-params bind-params bound? type retries ; TUPLE: simple-statement < statement ; TUPLE: prepared-statement < statement ; @@ -89,7 +89,7 @@ M: object execute-statement* ( statement type -- ) swap >>out-params swap >>in-params swap >>sql ; - + : sql-row ( result-set -- seq ) dup #columns [ row-column ] with map ; diff --git a/extra/db/queries/queries.factor b/extra/db/queries/queries.factor index 59ee60aa1f..d524080e57 100644 --- a/extra/db/queries/queries.factor +++ b/extra/db/queries/queries.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel math namespaces sequences random strings math.parser math.intervals combinators -math.bitfields.lib namespaces.lib db db.tuples db.types ; +math.bitfields.lib namespaces.lib db db.tuples db.types +sequences.lib ; IN: db.queries GENERIC: where ( specs obj -- ) @@ -99,16 +100,15 @@ M: string where ( spec obj -- ) object-where ; ] with filter ; : where-clause ( tuple specs -- ) - dupd filter-slots - dup empty? [ - 2drop + dupd filter-slots [ + drop ] [ " where " 0% [ " and " 0% ] [ 2dup slot-name>> swap get-slot-named where ] interleave drop - ] if ; + ] if-empty ; M: db ( tuple table -- sql ) [ diff --git a/extra/db/sql/sql.factor b/extra/db/sql/sql.factor index 82c6e370bd..756aeea7c0 100755 --- a/extra/db/sql/sql.factor +++ b/extra/db/sql/sql.factor @@ -5,7 +5,9 @@ IN: db.sql SYMBOLS: insert update delete select distinct columns from as where group-by having order-by limit offset is-null desc all -any count avg table values ; +any count avg table values ? ; + +! Output an s-exp sql statement and an alist of keys/values : input-spec, 1, ; : output-spec, 2, ; diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index bac141d6d2..b7bf6a7fbe 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -55,6 +55,7 @@ SINGLETON: retryable [ make-retryable ] map ] [ retryable >>type + 10 >>retries ] if ; : regenerate-params ( statement -- statement ) @@ -69,12 +70,13 @@ SINGLETON: retryable ] 2map >>bind-params ; M: retryable execute-statement* ( statement type -- ) - drop - [ - [ query-results dispose t ] - [ ] - [ regenerate-params bind-statement* f ] cleanup - ] curry 10 retry drop ; + drop [ + [ + [ query-results dispose t ] + [ ] + [ regenerate-params bind-statement* f ] cleanup + ] curry + ] [ retries>> ] bi retry drop ; : resulting-tuple ( class row out-params -- tuple ) rot class new [ From 96ce30a534f744cc160b1075bd92de6525805f9d Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 1 Jun 2008 11:25:09 -0500 Subject: [PATCH 002/354] add advanced-select word --- extra/db/tuples/tuples.factor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index b7bf6a7fbe..09fd63b233 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -154,3 +154,7 @@ M: retryable execute-statement* ( statement type -- ) : select-tuple ( tuple -- tuple/f ) dup dup class f f f 1 do-select ?first ; + +: advanced-select ( tuple groups order offset limit -- tuples ) + >r >r >r >r dup dup class r> r> r> r> + do-select ; From b974133285990ffb7ffc9e427c3503bc08b42281 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 3 Jun 2008 11:01:04 +1200 Subject: [PATCH 003/354] Re-add jni library to unmaintained --- unmaintained/jni/jni-internals.factor | 357 ++++++++++++++++++++++++++ unmaintained/jni/jni.factor | 22 ++ unmaintained/jni/load.factor | 4 + 3 files changed, 383 insertions(+) create mode 100644 unmaintained/jni/jni-internals.factor create mode 100644 unmaintained/jni/jni.factor create mode 100644 unmaintained/jni/load.factor diff --git a/unmaintained/jni/jni-internals.factor b/unmaintained/jni/jni-internals.factor new file mode 100644 index 0000000000..49bc57b108 --- /dev/null +++ b/unmaintained/jni/jni-internals.factor @@ -0,0 +1,357 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +IN: jni-internals +USING: kernel alien arrays sequences ; + +LIBRARY: jvm + +TYPEDEF: int jint +TYPEDEF: uchar jboolean +TYPEDEF: void* JNIEnv + +C-STRUCT: jdk-init-args + { "jint" "version" } + { "void*" "properties" } + { "jint" "check-source" } + { "jint" "native-stack-size" } + { "jint" "java-stack-size" } + { "jint" "min-heap-size" } + { "jint" "max-heap-size" } + { "jint" "verify-mode" } + { "char*" "classpath" } + { "void*" "vprintf" } + { "void*" "exit" } + { "void*" "abort" } + { "jint" "enable-class-gc" } + { "jint" "enable-verbose-gc" } + { "jint" "disable-async-gc" } + { "jint" "verbose" } + { "jboolean" "debugging" } + { "jint" "debug-port" } ; + +C-STRUCT: JNIInvokeInterface + { "void*" "reserved0" } + { "void*" "reserved1" } + { "void*" "reserved2" } + { "void*" "DestroyJavaVM" } + { "void*" "AttachCurrentThread" } + { "void*" "DetachCurrentThread" } + { "void*" "GetEnv" } + { "void*" "AttachCurrentThreadAsDaemon" } ; + +C-STRUCT: JavaVM + { "JNIInvokeInterface*" "functions" } ; + +C-STRUCT: JNINativeInterface + { "void*" "reserved0" } + { "void*" "reserved1" } + { "void*" "reserved2" } + { "void*" "reserved3" } + { "void*" "GetVersion" } + { "void*" "DefineClass" } + { "void*" "FindClass" } + { "void*" "FromReflectedMethod" } + { "void*" "FromReflectedField" } + { "void*" "ToReflectedMethod" } + { "void*" "GetSuperclass" } + { "void*" "IsAssignableFrom" } + { "void*" "ToReflectedField" } + { "void*" "Throw" } + { "void*" "ThrowNew" } + { "void*" "ExceptionOccurred" } + { "void*" "ExceptionDescribe" } + { "void*" "ExceptionClear" } + { "void*" "FatalError" } + { "void*" "PushLocalFrame" } + { "void*" "PopLocalFrame" } + { "void*" "NewGlobalRef" } + { "void*" "DeleteGlobalRef" } + { "void*" "DeleteLocalRef" } + { "void*" "IsSameObject" } + { "void*" "NewLocalRef" } + { "void*" "EnsureLocalCapacity" } + { "void*" "AllocObject" } + { "void*" "NewObject" } + { "void*" "NewObjectV" } + { "void*" "NewObjectA" } + { "void*" "GetObjectClass" } + { "void*" "IsInstanceOf" } + { "void*" "GetMethodID" } + { "void*" "CallObjectMethod" } + { "void*" "CallObjectMethodV" } + { "void*" "CallObjectMethodA" } + { "void*" "CallBooleanMethod" } + { "void*" "CallBooleanMethodV" } + { "void*" "CallBooleanMethodA" } + { "void*" "CallByteMethod" } + { "void*" "CallByteMethodV" } + { "void*" "CallByteMethodA" } + { "void*" "CallCharMethod" } + { "void*" "CallCharMethodV" } + { "void*" "CallCharMethodA" } + { "void*" "CallShortMethod" } + { "void*" "CallShortMethodV" } + { "void*" "CallShortMethodA" } + { "void*" "CallIntMethod" } + { "void*" "CallIntMethodV" } + { "void*" "CallIntMethodA" } + { "void*" "CallLongMethod" } + { "void*" "CallLongMethodV" } + { "void*" "CallLongMethodA" } + { "void*" "CallFloatMethod" } + { "void*" "CallFloatMethodV" } + { "void*" "CallFloatMethodA" } + { "void*" "CallDoubleMethod" } + { "void*" "CallDoubleMethodV" } + { "void*" "CallDoubleMethodA" } + { "void*" "CallVoidMethod" } + { "void*" "CallVoidMethodV" } + { "void*" "CallVoidMethodA" } + { "void*" "CallNonvirtualObjectMethod" } + { "void*" "CallNonvirtualObjectMethodV" } + { "void*" "CallNonvirtualObjectMethodA" } + { "void*" "CallNonvirtualBooleanMethod" } + { "void*" "CallNonvirtualBooleanMethodV" } + { "void*" "CallNonvirtualBooleanMethodA" } + { "void*" "CallNonvirtualByteMethod" } + { "void*" "CallNonvirtualByteMethodV" } + { "void*" "CallNonvirtualByteMethodA" } + { "void*" "CallNonvirtualCharMethod" } + { "void*" "CallNonvirtualCharMethodV" } + { "void*" "CallNonvirtualCharMethodA" } + { "void*" "CallNonvirtualShortMethod" } + { "void*" "CallNonvirtualShortMethodV" } + { "void*" "CallNonvirtualShortMethodA" } + { "void*" "CallNonvirtualIntMethod" } + { "void*" "CallNonvirtualIntMethodV" } + { "void*" "CallNonvirtualIntMethodA" } + { "void*" "CallNonvirtualLongMethod" } + { "void*" "CallNonvirtualLongMethodV" } + { "void*" "CallNonvirtualLongMethodA" } + { "void*" "CallNonvirtualFloatMethod" } + { "void*" "CallNonvirtualFloatMethodV" } + { "void*" "CallNonvirtualFloatMethodA" } + { "void*" "CallNonvirtualDoubleMethod" } + { "void*" "CallNonvirtualDoubleMethodV" } + { "void*" "CallNonvirtualDoubleMethodA" } + { "void*" "CallNonvirtualVoidMethod" } + { "void*" "CallNonvirtualVoidMethodV" } + { "void*" "CallNonvirtualVoidMethodA" } + { "void*" "GetFieldID" } + { "void*" "GetObjectField" } + { "void*" "GetBooleanField" } + { "void*" "GetByteField" } + { "void*" "GetCharField" } + { "void*" "GetShortField" } + { "void*" "GetIntField" } + { "void*" "GetLongField" } + { "void*" "GetFloatField" } + { "void*" "GetDoubleField" } + { "void*" "SetObjectField" } + { "void*" "SetBooleanField" } + { "void*" "SetByteField" } + { "void*" "SetCharField" } + { "void*" "SetShortField" } + { "void*" "SetIntField" } + { "void*" "SetLongField" } + { "void*" "SetFloatField" } + { "void*" "SetDoubleField" } + { "void*" "GetStaticMethodID" } + { "void*" "CallStaticObjectMethod" } + { "void*" "CallStaticObjectMethodV" } + { "void*" "CallStaticObjectMethodA" } + { "void*" "CallStaticBooleanMethod" } + { "void*" "CallStaticBooleanMethodV" } + { "void*" "CallStaticBooleanMethodA" } + { "void*" "CallStaticByteMethod" } + { "void*" "CallStaticByteMethodV" } + { "void*" "CallStaticByteMethodA" } + { "void*" "CallStaticCharMethod" } + { "void*" "CallStaticCharMethodV" } + { "void*" "CallStaticCharMethodA" } + { "void*" "CallStaticShortMethod" } + { "void*" "CallStaticShortMethodV" } + { "void*" "CallStaticShortMethodA" } + { "void*" "CallStaticIntMethod" } + { "void*" "CallStaticIntMethodV" } + { "void*" "CallStaticIntMethodA" } + { "void*" "CallStaticLongMethod" } + { "void*" "CallStaticLongMethodV" } + { "void*" "CallStaticLongMethodA" } + { "void*" "CallStaticFloatMethod" } + { "void*" "CallStaticFloatMethodV" } + { "void*" "CallStaticFloatMethodA" } + { "void*" "CallStaticDoubleMethod" } + { "void*" "CallStaticDoubleMethodV" } + { "void*" "CallStaticDoubleMethodA" } + { "void*" "CallStaticVoidMethod" } + { "void*" "CallStaticVoidMethodV" } + { "void*" "CallStaticVoidMethodA" } + { "void*" "GetStaticFieldID" } + { "void*" "GetStaticObjectField" } + { "void*" "GetStaticBooleanField" } + { "void*" "GetStaticByteField" } + { "void*" "GetStaticCharField" } + { "void*" "GetStaticShortField" } + { "void*" "GetStaticIntField" } + { "void*" "GetStaticLongField" } + { "void*" "GetStaticFloatField" } + { "void*" "GetStaticDoubleField" } + { "void*" "SetStaticObjectField" } + { "void*" "SetStaticBooleanField" } + { "void*" "SetStaticByteField" } + { "void*" "SetStaticCharField" } + { "void*" "SetStaticShortField" } + { "void*" "SetStaticIntField" } + { "void*" "SetStaticLongField" } + { "void*" "SetStaticFloatField" } + { "void*" "SetStaticDoubleField" } + { "void*" "NewString" } + { "void*" "GetStringLength" } + { "void*" "GetStringChars" } + { "void*" "ReleaseStringChars" } + { "void*" "NewStringUTF" } + { "void*" "GetStringUTFLength" } + { "void*" "GetStringUTFChars" } + { "void*" "ReleaseStringUTFChars" } + { "void*" "GetArrayLength" } + { "void*" "NewObjectArray" } + { "void*" "GetObjectArrayElement" } + { "void*" "SetObjectArrayElement" } + { "void*" "NewBooleanArray" } + { "void*" "NewByteArray" } + { "void*" "NewCharArray" } + { "void*" "NewShortArray" } + { "void*" "NewIntArray" } + { "void*" "NewLongArray" } + { "void*" "NewFloatArray" } + { "void*" "NewDoubleArray" } + { "void*" "GetBooleanArrayElements" } + { "void*" "GetByteArrayElements" } + { "void*" "GetCharArrayElements" } + { "void*" "GetShortArrayElements" } + { "void*" "GetIntArrayElements" } + { "void*" "GetLongArrayElements" } + { "void*" "GetFloatArrayElements" } + { "void*" "GetDoubleArrayElements" } + { "void*" "ReleaseBooleanArrayElements" } + { "void*" "ReleaseByteArrayElements" } + { "void*" "ReleaseCharArrayElements" } + { "void*" "ReleaseShortArrayElements" } + { "void*" "ReleaseIntArrayElements" } + { "void*" "ReleaseLongArrayElements" } + { "void*" "ReleaseFloatArrayElements" } + { "void*" "ReleaseDoubleArrayElements" } + { "void*" "GetBooleanArrayRegion" } + { "void*" "GetByteArrayRegion" } + { "void*" "GetCharArrayRegion" } + { "void*" "GetShortArrayRegion" } + { "void*" "GetIntArrayRegion" } + { "void*" "GetLongArrayRegion" } + { "void*" "GetFloatArrayRegion" } + { "void*" "GetDoubleArrayRegion" } + { "void*" "SetBooleanArrayRegion" } + { "void*" "SetByteArrayRegion" } + { "void*" "SetCharArrayRegion" } + { "void*" "SetShortArrayRegion" } + { "void*" "SetIntArrayRegion" } + { "void*" "SetLongArrayRegion" } + { "void*" "SetFloatArrayRegion" } + { "void*" "SetDoubleArrayRegion" } + { "void*" "RegisterNatives" } + { "void*" "UnregisterNatives" } + { "void*" "MonitorEnter" } + { "void*" "MonitorExit" } + { "void*" "GetJavaVM" } + { "void*" "GetStringRegion" } + { "void*" "GetStringUTFRegion" } + { "void*" "GetPrimitiveArrayCritical" } + { "void*" "ReleasePrimitiveArrayCritical" } + { "void*" "GetStringCritical" } + { "void*" "ReleaseStringCritical" } + { "void*" "NewWeakGlobalRef" } + { "void*" "DeleteWeakGlobalRef" } + { "void*" "ExceptionCheck" } + { "void*" "NewDirectByteBuffer" } + { "void*" "GetDirectBufferAddress" } + { "void*" "GetDirectBufferCapacity" } ; + +C-STRUCT: JNIEnv + { "JNINativeInterface*" "functions" } ; + +FUNCTION: jint JNI_GetDefaultJavaVMInitArgs ( jdk-init-args* args ) ; +FUNCTION: jint JNI_CreateJavaVM ( void** pvm, void** penv, void* args ) ; + +: ( -- jdk-init-args ) + "jdk-init-args" HEX: 00010004 over set-jdk-init-args-version ; + +: jni1 ( -- init-args int ) + dup JNI_GetDefaultJavaVMInitArgs ; + +: jni2 ( -- vm env int ) + f f [ + jni1 drop JNI_CreateJavaVM + ] 2keep rot dup 0 = [ + >r >r 0 swap void*-nth r> 0 swap void*-nth r> + ] when ; + +: (destroy-java-vm) + "int" { "void*" } "cdecl" alien-indirect ; + +: (attach-current-thread) + "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ; + +: (detach-current-thread) + "int" { "void*" } "cdecl" alien-indirect ; + +: (get-env) + "int" { "void*" "void*" "int" } "cdecl" alien-indirect ; + +: (attach-current-thread-as-daemon) + "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ; + +: destroy-java-vm ( javavm -- int ) + dup JavaVM-functions JNIInvokeInterface-DestroyJavaVM (destroy-java-vm) ; + +: (get-version) + "jint" { "JNIEnv*" } "cdecl" alien-indirect ; + +: get-version ( jnienv -- int ) + dup JNIEnv-functions JNINativeInterface-GetVersion (get-version) ; + +: (find-class) + "void*" { "JNINativeInterface*" "char*" } "cdecl" alien-indirect ; + +: find-class ( name jnienv -- int ) + dup swapd JNIEnv-functions JNINativeInterface-FindClass (find-class) ; + +: (get-static-field-id) + "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ; + +: get-static-field-id ( class name sig jnienv -- int ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetStaticFieldID (get-static-field-id) ; + +: (get-static-object-field) + "void*" { "JNINativeInterface*" "void*" "void*" } "cdecl" alien-indirect ; + +: get-static-object-field ( class id jnienv -- int ) + dup >r >r 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-GetStaticObjectField (get-static-object-field) ; + +: (get-method-id) + "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ; + +: get-method-id ( class name sig jnienv -- int ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetMethodID (get-method-id) ; + +: (new-string) + "void*" { "JNINativeInterface*" "char*" "int" } "cdecl" alien-indirect ; + +: new-string ( str jnienv -- str ) + dup >r >r dup length 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-NewString (new-string) ; + +: (call1) + "void" { "JNINativeInterface*" "void*" "void*" "int" } "cdecl" alien-indirect ; + +: call1 ( obj method-id jstr jnienv -- ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-CallObjectMethod (call1) ; + diff --git a/unmaintained/jni/jni.factor b/unmaintained/jni/jni.factor new file mode 100644 index 0000000000..86e1670c50 --- /dev/null +++ b/unmaintained/jni/jni.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +IN: jni +USING: kernel jni-internals namespaces ; + +! High level interface for JNI to be added here... + +: test0 ( -- ) + jni2 drop nip "env" set ; + +: test1 ( -- system ) + "java/lang/System" "env" get find-class ; + +: test2 ( system -- system.out ) + dup "out" "Ljava/io/PrintStream;" "env" get get-static-field-id + "env" get get-static-object-field ; + +: test3 ( int system.out -- ) + "java/io/PrintStream" "env" get find-class ! jstr out class + "println" "(I)V" "env" get get-method-id ! jstr out id + rot "env" get call1 ; + \ No newline at end of file diff --git a/unmaintained/jni/load.factor b/unmaintained/jni/load.factor new file mode 100644 index 0000000000..f5fd45c8d9 --- /dev/null +++ b/unmaintained/jni/load.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +PROVIDE: libs/jni +{ +files+ { "jni-internals.factor" "jni.factor" } } ; From 95663e56ce0c57cf7ee7ccb2a67e823e66b4f135 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sat, 7 Jun 2008 10:48:05 -0500 Subject: [PATCH 004/354] commit local changes --- extra/db/queries/queries.factor | 47 ++++++++++++++++++++++++++--- extra/db/sql/sql.factor | 32 ++++++++++++-------- extra/db/tuples/tuples-tests.factor | 6 ++-- extra/db/tuples/tuples.factor | 22 +++++++++++--- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/extra/db/queries/queries.factor b/extra/db/queries/queries.factor index d524080e57..29abe9bddc 100644 --- a/extra/db/queries/queries.factor +++ b/extra/db/queries/queries.factor @@ -3,7 +3,7 @@ USING: accessors kernel math namespaces sequences random strings math.parser math.intervals combinators math.bitfields.lib namespaces.lib db db.tuples db.types -sequences.lib ; +sequences.lib db.sql classes words shuffle arrays ; IN: db.queries GENERIC: where ( specs obj -- ) @@ -146,7 +146,7 @@ M: db ( tuple class -- statement ) number>string " limit " prepend append ] curry change-sql drop ; -: make-advanced-statement ( tuple advanced -- tuple' ) +: make-query ( tuple query -- tuple' ) dupd { [ group>> [ do-group ] [ drop ] if* ] @@ -155,6 +155,43 @@ M: db ( tuple class -- statement ) [ offset>> [ do-offset ] [ drop ] if* ] } 2cleave ; -M: db ( tuple class group order limit offset -- tuple ) - advanced-statement boa - [ ] dip make-advanced-statement ; +M: db ( tuple class group order limit offset -- tuple ) + \ query boa + [ ] dip make-query ; + +! select ID, NAME, SCORE from EXAM limit 1 offset 3 + +: select-tuples* ( tuple -- statement ) + dup + [ + select 0, + dup class db-columns [ ", " 0, ] + [ dup column-name>> 0, 2, ] interleave + from 0, + class word-name 0, + ] { { } { } { } } nmake + >r >r parse-sql 4drop r> r> + maybe-make-retryable do-select ; + +M: db ( tuple class groups -- statement ) + f f f \ query boa + [ [ "select count(*) from " 0% 0% where-clause ] query-make ] + dip make-query ; + +: where-clause* ( tuple specs -- ) + dupd filter-slots [ + drop + ] [ + \ where 0, + [ 2dup slot-name>> swap get-slot-named where ] map 2array 0, + drop + ] if-empty ; + +: delete-tuple* ( tuple -- sql ) + dup + [ + delete 0, from 0, dup class db-table 0, + dup class db-columns where-clause* + ] { { } { } { } } nmake + >r >r parse-sql 4drop r> r> + maybe-make-retryable do-select ; diff --git a/extra/db/sql/sql.factor b/extra/db/sql/sql.factor index 756aeea7c0..dc8b5d1fb1 100755 --- a/extra/db/sql/sql.factor +++ b/extra/db/sql/sql.factor @@ -5,7 +5,7 @@ IN: db.sql SYMBOLS: insert update delete select distinct columns from as where group-by having order-by limit offset is-null desc all -any count avg table values ? ; +any count avg table values ; ! Output an s-exp sql statement and an alist of keys/values @@ -25,12 +25,27 @@ DEFER: sql% : sql-function, ( seq function -- ) sql% "(" sql% unclip sql% ")" sql% [ sql% ] each ; +: sql-where ( seq -- ) +B + [ + [ second 0, ] + [ first 0, ] + [ third 1, \ ? 0, ] tri + ] each ; + : sql-array% ( array -- ) +B unclip { + { \ create [ "create table" sql% ] } + { \ drop [ "drop table" sql% ] } + { \ insert [ "insert into" sql% ] } + { \ update [ "update" sql% ] } + { \ delete [ "delete" sql% ] } + { \ select [ B "select" sql% "," (sql-interleave) ] } { \ columns [ "," (sql-interleave) ] } { \ from [ "from" "," sql-interleave ] } - { \ where [ "where" "and" sql-interleave ] } + { \ where [ B "where" 0, sql-where ] } { \ group-by [ "group by" "," sql-interleave ] } { \ having [ "having" "," sql-interleave ] } { \ order-by [ "order by" "," sql-interleave ] } @@ -51,7 +66,7 @@ DEFER: sql% ERROR: no-sql-match ; : sql% ( obj -- ) { - { [ dup string? ] [ " " 0% 0% ] } + { [ dup string? ] [ 0, ] } { [ dup array? ] [ sql-array% ] } { [ dup number? ] [ number>string sql% ] } { [ dup symbol? ] [ unparse sql% ] } @@ -61,13 +76,4 @@ ERROR: no-sql-match ; } cond ; : parse-sql ( obj -- sql in-spec out-spec in out ) - [ - unclip { - { \ create [ "create table" sql% ] } - { \ drop [ "drop table" sql% ] } - { \ insert [ "insert into" sql% ] } - { \ update [ "update" sql% ] } - { \ delete [ "delete" sql% ] } - { \ select [ "select" sql% ] } - } case [ sql% ] each - ] { "" { } { } { } { } } nmake ; + [ [ sql% ] each ] { { } { } { } } nmake ; diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index f9a597e814..665afa6a51 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -227,7 +227,7 @@ TUPLE: exam id name score ; : random-exam ( -- exam ) f - 6 [ CHAR: a CHAR: b [a,b] random ] replicate >string + 6 [ CHAR: a CHAR: z [a,b] random ] replicate >string 100 random exam boa ; @@ -340,7 +340,9 @@ TUPLE: exam id name score ; } ] [ T{ exam } select-tuples - ] unit-test ; + ] unit-test + + [ 4 ] [ T{ exam } count-tuples ] unit-test ; TUPLE: bignum-test id m n o ; : ( m n o -- obj ) diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index 09fd63b233..d121e06445 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -42,8 +42,9 @@ HOOK: db ( class -- obj ) HOOK: db ( class -- obj ) HOOK: db ( tuple class -- obj ) HOOK: db ( tuple class -- tuple ) -TUPLE: advanced-statement group order offset limit ; -HOOK: db ( tuple class group order offset limit -- tuple ) +TUPLE: query group order offset limit ; +HOOK: db ( tuple class group order offset limit -- tuple ) +HOOK: db ( tuple class -- n ) HOOK: insert-tuple* db ( tuple statement -- ) @@ -152,9 +153,20 @@ M: retryable execute-statement* ( statement type -- ) dup dup class do-select ; : select-tuple ( tuple -- tuple/f ) - dup dup class f f f 1 + dup dup class f f f 1 do-select ?first ; -: advanced-select ( tuple groups order offset limit -- tuples ) +: query ( tuple groups order offset limit -- tuples ) >r >r >r >r dup dup class r> r> r> r> - do-select ; + do-select ; + +: do-count ( exemplar-tuple statement -- tuples ) + [ + [ bind-tuple ] [ nip default-query ] 2bi + ] with-disposal ; + +: count-tuples ( tuple groups -- n ) + >r dup dup class r> do-count + dup length 1 = [ first first string>number ] [ + [ first string>number ] map + ] if ; From a0dbee6e2a2c26e24f5a5d9ca492a684ab3d2ddf Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 8 Jun 2008 16:33:07 -0500 Subject: [PATCH 005/354] clean up html parser prettyprinter a bit --- extra/html/parser/printer/printer.factor | 47 +++++++++++++++++------- extra/html/parser/utils/utils.factor | 11 ++---- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/extra/html/parser/printer/printer.factor b/extra/html/parser/printer/printer.factor index 3078cf23a5..d352a97688 100644 --- a/extra/html/parser/printer/printer.factor +++ b/extra/html/parser/printer/printer.factor @@ -2,7 +2,7 @@ USING: assocs html.parser html.parser.utils combinators continuations hashtables hashtables.private io kernel math namespaces prettyprint quotations sequences splitting -state-parser strings ; +strings ; IN: html.parser.printer SYMBOL: no-section @@ -16,7 +16,8 @@ TUPLE: state section ; TUPLE: text-printer ; TUPLE: ui-printer ; TUPLE: src-printer ; -UNION: printer text-printer ui-printer src-printer ; +TUPLE: html-prettyprinter ; +UNION: printer text-printer ui-printer src-printer html-prettyprinter ; HOOK: print-tag printer ( tag -- ) HOOK: print-text-tag printer ( tag -- ) HOOK: print-comment-tag printer ( tag -- ) @@ -47,7 +48,7 @@ M: printer print-comment-tag ( tag -- ) tag-text write "-->" write ; -M: printer print-dtd-tag +M: printer print-dtd-tag ( tag -- ) "" write ; @@ -70,8 +71,8 @@ M: printer print-closing-named-tag ( tag -- ) M: src-printer print-opening-named-tag ( tag -- ) "<" write - dup tag-name write - tag-attributes dup assoc-empty? [ drop ] [ print-attributes ] if + [ tag-name write ] + [ tag-attributes dup assoc-empty? [ drop ] [ print-attributes ] if ] bi ">" write ; M: src-printer print-closing-named-tag ( tag -- ) @@ -79,9 +80,30 @@ M: src-printer print-closing-named-tag ( tag -- ) tag-name write ">" write ; -TUPLE: unknown-tag-error tag ; +SYMBOL: tab-width +SYMBOL: #indentations -C: unknown-tag-error +: html-pp ( vector -- ) + [ + 0 #indentations set + 2 tab-width set + + ] with-scope ; + +: print-tabs ( -- ) + tab-width get #indentations get * CHAR: \s write ; + +M: html-prettyprinter print-opening-named-tag ( tag -- ) + print-tabs "<" write + tag-name write + ">\n" write ; + +M: html-prettyprinter print-closing-named-tag ( tag -- ) + "" write ; + +ERROR: unknown-tag-error tag ; M: printer print-tag ( tag -- ) { @@ -92,15 +114,12 @@ M: printer print-tag ( tag -- ) [ print-closing-named-tag ] } { [ dup tag-name string? ] [ print-opening-named-tag ] } - [ throw ] + [ unknown-tag-error ] } cond ; -SYMBOL: tablestack - -: with-html-printer - [ - V{ } clone tablestack set - ] with-scope ; +! SYMBOL: tablestack +! : with-html-printer ( vector quot -- ) + ! [ V{ } clone tablestack set ] with-scope ; ! { { 1 2 } { 3 4 } } ! H{ { table-gap { 10 10 } } } [ diff --git a/extra/html/parser/utils/utils.factor b/extra/html/parser/utils/utils.factor index 5083b1cec2..592503e3dd 100644 --- a/extra/html/parser/utils/utils.factor +++ b/extra/html/parser/utils/utils.factor @@ -1,7 +1,7 @@ USING: assocs circular combinators continuations hashtables hashtables.private io kernel math namespaces prettyprint quotations sequences splitting -state-parser strings ; +state-parser strings sequences.lib ; IN: html.parser.utils : string-parse-end? @@ -13,7 +13,7 @@ IN: html.parser.utils dup length rot length 1- - head next* ; : trim1 ( seq ch -- newseq ) - [ ?head drop ] keep ?tail drop ; + [ ?head drop ] [ ?tail drop ] bi ; : single-quote ( str -- newstr ) >r "'" r> "'" 3append ; @@ -26,11 +26,7 @@ IN: html.parser.utils [ double-quote ] [ single-quote ] if ; : quoted? ( str -- ? ) - dup length 1 > [ - [ first ] keep peek [ = ] keep "'\"" member? and - ] [ - drop f - ] if ; + [ [ first ] [ peek ] bi [ = ] keep "'\"" member? and ] [ f ] if-seq ; : ?quote ( str -- newstr ) dup quoted? [ quote ] unless ; @@ -39,4 +35,3 @@ IN: html.parser.utils dup quoted? [ but-last-slice rest-slice >string ] when ; : quote? ( ch -- ? ) "'\"" member? ; - From a368b5ad487cfa5f1a11f9cef111576824f6d23c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 12 Jun 2008 17:08:19 -0500 Subject: [PATCH 006/354] Clarification --- core/parser/parser-docs.factor | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor index 1dc47432d3..2ec9f2de54 100755 --- a/core/parser/parser-docs.factor +++ b/core/parser/parser-docs.factor @@ -117,14 +117,18 @@ $nl { $subsection parse-tokens } ; ARTICLE: "parsing-words" "Parsing words" -"The Factor parser is follows a simple recursive-descent design. The parser reads successive tokens from the input; if the token identifies a number or an ordinary word, it is added to an accumulator vector. Otherwise if the token identifies a parsing word, the parsing word is executed immediately." +"The Factor parser follows a simple recursive-descent design. The parser reads successive tokens from the input; if the token identifies a number or an ordinary word, it is added to an accumulator vector. Otherwise if the token identifies a parsing word, the parsing word is executed immediately." $nl "Parsing words are marked by suffixing the definition with a " { $link POSTPONE: parsing } " declaration. Here is the simplest possible parsing word; it prints a greeting at parse time:" { $code ": hello \"Hello world\" print ; parsing" } -"Parsing words must have stack effect " { $snippet "( accum -- accum )" } ", where " { $snippet "accum" } " is the accumulator vector supplied by the parser. Parsing words can read input, add word definitions to the dictionary, and do anything an ordinary word can." +"Parsing words must not pop or push items from the stack; however, they are permitted to access the accumulator vector supplied by the parser at the top of the stack. That is, parsing words must have stack effect " { $snippet "( accum -- accum )" } ", where " { $snippet "accum" } " is the accumulator vector supplied by the parser." +$nl +"Parsing words can read input, add word definitions to the dictionary, and do anything an ordinary word can." +$nl +"Because of the stack restriction, parsing words cannot pass data to other words by leaving values on the stack; instead, use " { $link parsed } " to add the data to the parse tree so that it can be evaluated later." $nl "Parsing words cannot be called from the same source file where they are defined, because new definitions are only compiled at the end of the source file. An attempt to use a parsing word in its own source file raises an error:" -{ $link staging-violation } +{ $subsection staging-violation } "Tools for implementing parsing words:" { $subsection "reading-ahead" } { $subsection "parsing-word-nest" } From 5f9aca57251855e866260af313b60548755a5bea Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 12 Jun 2008 18:04:01 -0500 Subject: [PATCH 007/354] refactor add url objects --- extra/db/postgresql/lib/lib.factor | 4 +++- extra/db/postgresql/postgresql.factor | 1 + extra/db/queries/queries.factor | 10 +++++----- extra/db/sqlite/lib/lib.factor | 4 +++- extra/db/sqlite/sqlite.factor | 1 + extra/db/tuples/tuples-tests.factor | 2 +- extra/db/tuples/tuples.factor | 22 ++++++++-------------- extra/db/types/types.factor | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/extra/db/postgresql/lib/lib.factor b/extra/db/postgresql/lib/lib.factor index e99bc41449..9d2ced3afa 100755 --- a/extra/db/postgresql/lib/lib.factor +++ b/extra/db/postgresql/lib/lib.factor @@ -5,7 +5,7 @@ quotations sequences db.postgresql.ffi alien alien.c-types db.types tools.walker ascii splitting math.parser combinators libc shuffle calendar.format byte-arrays destructors prettyprint accessors strings serialize io.encodings.binary io.encodings.utf8 -alien.strings io.streams.byte-array inspector ; +alien.strings io.streams.byte-array inspector present urls ; IN: db.postgresql.lib : postgresql-result-error-message ( res -- str/f ) @@ -84,6 +84,7 @@ M: postgresql-result-null summary ( obj -- str ) { TIME [ dup [ timestamp>hms ] when default-param-value ] } { DATETIME [ dup [ timestamp>ymdhms ] when default-param-value ] } { TIMESTAMP [ dup [ timestamp>ymdhms ] when default-param-value ] } + { URL [ dup [ present ] when default-param-value ] } [ drop default-param-value ] } case 2array ] 2map flip dup empty? [ @@ -164,6 +165,7 @@ M: postgresql-malloc-destructor dispose ( obj -- ) { TIMESTAMP [ pq-get-string dup [ ymdhms>timestamp ] when ] } { DATETIME [ pq-get-string dup [ ymdhms>timestamp ] when ] } { BLOB [ pq-get-blob ] } + { URL [ pq-get-string dup [ >url ] when ] } { FACTOR-BLOB [ pq-get-blob dup [ bytes>object ] when ] } diff --git a/extra/db/postgresql/postgresql.factor b/extra/db/postgresql/postgresql.factor index f55897db88..1734fb6df4 100755 --- a/extra/db/postgresql/postgresql.factor +++ b/extra/db/postgresql/postgresql.factor @@ -239,6 +239,7 @@ M: postgresql-db persistent-table ( -- hashtable ) { TIMESTAMP { "timestamp" "timestamp" f } } { BLOB { "bytea" "bytea" f } } { FACTOR-BLOB { "bytea" "bytea" f } } + { URL { "string" "string" f } } { +foreign-id+ { f f "references" } } { +autoincrement+ { f f "autoincrement" } } { +unique+ { f f "unique" } } diff --git a/extra/db/queries/queries.factor b/extra/db/queries/queries.factor index 29abe9bddc..807aeda74a 100644 --- a/extra/db/queries/queries.factor +++ b/extra/db/queries/queries.factor @@ -149,14 +149,13 @@ M: db ( tuple class -- statement ) : make-query ( tuple query -- tuple' ) dupd { - [ group>> [ do-group ] [ drop ] if* ] - [ order>> [ do-order ] [ drop ] if* ] + [ group>> [ do-group ] [ drop ] if-seq ] + [ order>> [ do-order ] [ drop ] if-seq ] [ limit>> [ do-limit ] [ drop ] if* ] [ offset>> [ do-offset ] [ drop ] if* ] } 2cleave ; -M: db ( tuple class group order limit offset -- tuple ) - \ query boa +M: db ( tuple class query -- tuple ) [ ] dip make-query ; ! select ID, NAME, SCORE from EXAM limit 1 offset 3 @@ -174,7 +173,8 @@ M: db ( tuple class group order limit offset -- tuple ) maybe-make-retryable do-select ; M: db ( tuple class groups -- statement ) - f f f \ query boa + \ query new + swap >>group [ [ "select count(*) from " 0% 0% where-clause ] query-make ] dip make-query ; diff --git a/extra/db/sqlite/lib/lib.factor b/extra/db/sqlite/lib/lib.factor index b652e8fed7..4c440acc55 100755 --- a/extra/db/sqlite/lib/lib.factor +++ b/extra/db/sqlite/lib/lib.factor @@ -4,7 +4,7 @@ USING: alien.c-types arrays assocs kernel math math.parser namespaces sequences db.sqlite.ffi db combinators continuations db.types calendar.format serialize io.streams.byte-array byte-arrays io.encodings.binary -io.backend db.errors ; +io.backend db.errors present urls ; IN: db.sqlite.lib ERROR: sqlite-error < db-error n string ; @@ -107,6 +107,7 @@ ERROR: sqlite-sql-error < sql-error n string ; object>bytes sqlite-bind-blob-by-name ] } + { URL [ present sqlite-bind-text-by-name ] } { +db-assigned-id+ [ sqlite-bind-int-by-name ] } { +random-id+ [ sqlite-bind-int64-by-name ] } { NULL [ sqlite-bind-null-by-name ] } @@ -147,6 +148,7 @@ ERROR: sqlite-sql-error < sql-error n string ; { TIMESTAMP [ sqlite3_column_text dup [ ymdhms>timestamp ] when ] } { DATETIME [ sqlite3_column_text dup [ ymdhms>timestamp ] when ] } { BLOB [ sqlite-column-blob ] } + { URL [ sqlite3_column_text dup [ >url ] when ] } { FACTOR-BLOB [ sqlite-column-blob dup [ bytes>object ] when diff --git a/extra/db/sqlite/sqlite.factor b/extra/db/sqlite/sqlite.factor index cc4e4d116a..c7c9065b43 100755 --- a/extra/db/sqlite/sqlite.factor +++ b/extra/db/sqlite/sqlite.factor @@ -182,6 +182,7 @@ M: sqlite-db persistent-table ( -- assoc ) { DOUBLE { "real" "real" } } { BLOB { "blob" "blob" } } { FACTOR-BLOB { "blob" "blob" } } + { URL { "text" "text" } } { +autoincrement+ { f f "autoincrement" } } { +unique+ { f f "unique" } } { +default+ { f f "default" } } diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index 665afa6a51..7ccee7c637 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -342,7 +342,7 @@ TUPLE: exam id name score ; T{ exam } select-tuples ] unit-test - [ 4 ] [ T{ exam } count-tuples ] unit-test ; + [ 4 ] [ T{ exam } f count-tuples ] unit-test ; TUPLE: bignum-test id m n o ; : ( m n o -- obj ) diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index b7cc6c81c2..4903adff5c 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -43,8 +43,8 @@ HOOK: db ( class -- obj ) HOOK: db ( tuple class -- obj ) HOOK: db ( tuple class -- tuple ) TUPLE: query group order offset limit ; -HOOK: db ( tuple class group order offset limit -- tuple ) -HOOK: db ( tuple class -- n ) +HOOK: db ( tuple class query -- statement' ) +HOOK: db ( tuple class groups -- n ) HOOK: insert-tuple* db ( tuple statement -- ) @@ -149,19 +149,14 @@ M: retryable execute-statement* ( statement type -- ) : do-select ( exemplar-tuple statement -- tuples ) [ [ bind-tuple ] [ query-tuples ] 2bi ] with-disposal ; +: query ( tuple query -- tuples ) + >r dup dup class r> do-select ; + : select-tuples ( tuple -- tuples ) dup dup class do-select ; -: count-tuples ( tuple -- n ) - select-tuples length ; - : select-tuple ( tuple -- tuple/f ) - dup dup class f f f 1 - do-select ?first ; - -: query ( tuple groups order offset limit -- tuples ) - >r >r >r >r dup dup class r> r> r> r> - do-select ; + dup dup class \ query new 1 >>limit do-select ?first ; : do-count ( exemplar-tuple statement -- tuples ) [ @@ -170,6 +165,5 @@ M: retryable execute-statement* ( statement type -- ) : count-tuples ( tuple groups -- n ) >r dup dup class r> do-count - dup length 1 = [ first first string>number ] [ - [ first string>number ] map - ] if ; + dup length 1 = + [ first first string>number ] [ [ first string>number ] map ] if ; diff --git a/extra/db/types/types.factor b/extra/db/types/types.factor index 03e6b15bdb..f6d54404de 100755 --- a/extra/db/types/types.factor +++ b/extra/db/types/types.factor @@ -65,7 +65,7 @@ SYMBOLS: +autoincrement+ +serial+ +unique+ +default+ +null+ +not-null+ SYMBOLS: INTEGER BIG-INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER DOUBLE REAL BOOLEAN TEXT VARCHAR DATE TIME DATETIME TIMESTAMP BLOB -FACTOR-BLOB NULL ; +FACTOR-BLOB NULL URL ; : spec>tuple ( class spec -- tuple ) 3 f pad-right From a226bf5de846eb74fb6f2cb9d8d207fd2f83b8db Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 12 Jun 2008 18:20:15 -0500 Subject: [PATCH 008/354] fix url objects, use new accessors more in db.tuples-tests --- extra/db/postgresql/postgresql.factor | 2 +- extra/db/tuples/tuples-tests.factor | 47 ++++++++++++++------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/extra/db/postgresql/postgresql.factor b/extra/db/postgresql/postgresql.factor index 1734fb6df4..e57efbc360 100755 --- a/extra/db/postgresql/postgresql.factor +++ b/extra/db/postgresql/postgresql.factor @@ -239,7 +239,7 @@ M: postgresql-db persistent-table ( -- hashtable ) { TIMESTAMP { "timestamp" "timestamp" f } } { BLOB { "bytea" "bytea" f } } { FACTOR-BLOB { "bytea" "bytea" f } } - { URL { "string" "string" f } } + { URL { "varchar" "varchar" f } } { +foreign-id+ { f f "references" } } { +autoincrement+ { f f "autoincrement" } } { +unique+ { f f "unique" } } diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index 7ccee7c637..b5b80355fe 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -8,22 +8,23 @@ math.ranges strings sequences.lib ; IN: db.tuples.tests TUPLE: person the-id the-name the-number the-real -ts date time blob factor-blob ; +ts date time blob factor-blob url ; -: ( name age real ts date time blob factor-blob -- person ) - { - set-person-the-name - set-person-the-number - set-person-the-real - set-person-ts - set-person-date - set-person-time - set-person-blob - set-person-factor-blob - } person construct ; +: ( name age real ts date time blob factor-blob url -- person ) + person new + swap >>url + swap >>factor-blob + swap >>blob + swap >>time + swap >>date + swap >>ts + swap >>the-real + swap >>the-number + swap >>the-name ; -: ( id name age real ts date time blob factor-blob -- person ) - [ set-person-the-id ] keep ; +: ( id name age real ts date time blob factor-blob url -- person ) + + swap >>the-id ; SYMBOL: person1 SYMBOL: person2 @@ -120,19 +121,20 @@ SYMBOL: person4 { "time" "T" TIME } { "blob" "B" BLOB } { "factor-blob" "FB" FACTOR-BLOB } + { "url" "U" URL } } define-persistent - "billy" 10 3.14 f f f f f person1 set - "johnny" 10 3.14 f f f f f person2 set + "billy" 10 3.14 f f f f f f person1 set + "johnny" 10 3.14 f f f f f f person2 set "teddy" 10 3.14 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } - B{ 115 116 111 114 101 105 110 97 98 108 111 98 } f person3 set + B{ 115 116 111 114 101 105 110 97 98 108 111 98 } f f person3 set "eddie" 10 3.14 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } - f H{ { 1 2 } { 3 4 } { 5 "lol" } } person4 set ; + f H{ { 1 2 } { 3 4 } { 5 "lol" } } f person4 set ; : user-assigned-person-schema ( -- ) person "PERSON" @@ -146,20 +148,21 @@ SYMBOL: person4 { "time" "T" TIME } { "blob" "B" BLOB } { "factor-blob" "FB" FACTOR-BLOB } + { "url" "U" URL } } define-persistent - 1 "billy" 10 3.14 f f f f f person1 set - 2 "johnny" 10 3.14 f f f f f person2 set + 1 "billy" 10 3.14 f f f f f f person1 set + 2 "johnny" 10 3.14 f f f f f f person2 set 3 "teddy" 10 3.14 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } B{ 115 116 111 114 101 105 110 97 98 108 111 98 } - f person3 set + f f person3 set 4 "eddie" 10 3.14 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } - f H{ { 1 2 } { 3 4 } { 5 "lol" } } person4 set ; + f H{ { 1 2 } { 3 4 } { 5 "lol" } } f person4 set ; TUPLE: paste n summary author channel mode contents timestamp annotations ; TUPLE: annotation n paste-id summary author mode contents ; From 216bf23e6c6687123ef8af4ece65ad0f889c7e7c Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 12 Jun 2008 18:23:46 -0500 Subject: [PATCH 009/354] test url objects --- extra/db/tuples/tuples-tests.factor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index b5b80355fe..36e84187eb 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -4,7 +4,7 @@ USING: io.files kernel tools.test db db.tuples classes db.types continuations namespaces math math.ranges prettyprint calendar sequences db.sqlite math.intervals db.postgresql accessors random math.bitfields.lib -math.ranges strings sequences.lib ; +math.ranges strings sequences.lib urls ; IN: db.tuples.tests TUPLE: person the-id the-name the-number the-real @@ -104,6 +104,7 @@ SYMBOL: person4 T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } f H{ { 1 2 } { 3 4 } { 5 "lol" } } + URL" http://www.google.com/search?hl=en&q=trailer+park+boys&btnG=Google+Search" } ] [ T{ person f 4 } select-tuple ] unit-test @@ -134,7 +135,7 @@ SYMBOL: person4 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } - f H{ { 1 2 } { 3 4 } { 5 "lol" } } f person4 set ; + f H{ { 1 2 } { 3 4 } { 5 "lol" } } URL" http://www.google.com/search?hl=en&q=trailer+park+boys&btnG=Google+Search" person4 set ; : user-assigned-person-schema ( -- ) person "PERSON" @@ -162,7 +163,7 @@ SYMBOL: person4 T{ timestamp f 2008 3 5 16 24 11 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f 2008 11 22 0 0 0 T{ duration f 0 0 0 0 0 0 } } T{ timestamp f f f f 12 34 56 T{ duration f 0 0 0 0 0 0 } } - f H{ { 1 2 } { 3 4 } { 5 "lol" } } f person4 set ; + f H{ { 1 2 } { 3 4 } { 5 "lol" } } URL" http://www.google.com/search?hl=en&q=trailer+park+boys&btnG=Google+Search" person4 set ; TUPLE: paste n summary author channel mode contents timestamp annotations ; TUPLE: annotation n paste-id summary author mode contents ; From a89c9758df900de8faace1661ec9e3a2e4310e3c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 12 Jun 2008 18:53:53 -0500 Subject: [PATCH 010/354] Check port number --- extra/http/http-tests.factor | 8 ++++---- extra/http/http.factor | 9 +-------- extra/http/server/server.factor | 26 +++++++++++++++++++++----- extra/io/server/server.factor | 10 ++++++---- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 81ada558f3..aa11dd6798 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -7,7 +7,7 @@ IN: http.tests : lf>crlf "\n" split "\r\n" join ; STRING: read-request-test-1 -POST http://foo/bar HTTP/1.1 +POST /bar HTTP/1.1 Some-Header: 1 Some-Header: 2 Content-Length: 4 @@ -18,7 +18,7 @@ blah [ TUPLE{ request - url: TUPLE{ url protocol: "http" port: 80 path: "/bar" } + url: TUPLE{ url path: "/bar" } method: "POST" version: "1.1" header: H{ { "some-header" "1; 2" } { "content-length" "4" } { "content-type" "application/octet-stream" } } @@ -49,14 +49,14 @@ read-request-test-1' 1array [ ] unit-test STRING: read-request-test-2 -HEAD http://foo/bar HTTP/1.1 +HEAD /bar HTTP/1.1 Host: www.sex.com ; [ TUPLE{ request - url: TUPLE{ url protocol: "http" port: 80 host: "www.sex.com" path: "/bar" } + url: TUPLE{ url host: "www.sex.com" path: "/bar" } method: "HEAD" version: "1.1" header: H{ { "host" "www.sex.com" } } diff --git a/extra/http/http.factor b/extra/http/http.factor index d7fc1b766e..521c18c703 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -6,8 +6,7 @@ assocs sequences splitting sorting sets debugger strings vectors hashtables quotations arrays byte-arrays math.parser calendar calendar.format present -io io.server io.sockets.secure -io.encodings.iana io.encodings.binary io.encodings.8-bit +io io.encodings.iana io.encodings.binary io.encodings.8-bit unicode.case unicode.categories qualified @@ -142,7 +141,6 @@ cookies ; request new "1.1" >>version - "http" >>protocol H{ } clone >>query >>url H{ } clone >>header @@ -202,7 +200,6 @@ TUPLE: post-data raw content content-type ; : extract-host ( request -- request ) [ ] [ url>> ] [ "host" header parse-host ] tri [ >>host ] [ >>port ] bi* - ensure-port drop ; : extract-cookies ( request -- request ) @@ -214,9 +211,6 @@ TUPLE: post-data raw content content-type ; : parse-content-type ( content-type -- type encoding ) ";" split1 parse-content-type-attributes "charset" swap at ; -: detect-protocol ( request -- request ) - dup url>> remote-address get secure? "https" "http" ? >>protocol drop ; - : read-request ( -- request ) read-method @@ -224,7 +218,6 @@ TUPLE: post-data raw content content-type ; read-request-version read-request-header read-post-data - detect-protocol extract-host extract-cookies ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 792757b182..642e9f77f0 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -2,16 +2,18 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors sequences arrays namespaces splitting vocabs.loader destructors assocs debugger continuations -tools.vocabs math +combinators tools.vocabs math io io.server +io.sockets +io.sockets.secure io.encodings io.encodings.utf8 io.encodings.ascii io.encodings.binary io.streams.limited io.timeouts -fry logging calendar +fry logging calendar urls http http.server.responses html.elements @@ -88,12 +90,26 @@ LOG: httpd-hit NOTICE : dispatch-request ( request -- response ) url>> path>> split-path main-responder get call-responder ; +: prepare-request ( request -- request ) + [ + local-address get + [ secure? "https" "http" ? >>protocol ] + [ port>> '[ , or ] change-port ] + bi + ] change-url ; + +: valid-request? ( request -- ? ) + url>> port>> local-address get port>> = ; + : do-request ( request -- response ) '[ , - [ init-request ] - [ log-request ] - [ dispatch-request ] tri + { + [ init-request ] + [ prepare-request ] + [ log-request ] + [ dup valid-request? [ dispatch-request ] [ drop <400> ] if ] + } cleave ] [ [ \ do-request log-error ] [ <500> ] bi ] recover ; : ?refresh-all ( -- ) diff --git a/extra/io/server/server.factor b/extra/io/server/server.factor index 359b9c6fb4..c855fba6be 100755 --- a/extra/io/server/server.factor +++ b/extra/io/server/server.factor @@ -4,7 +4,7 @@ USING: io io.sockets io.sockets.secure io.files io.streams.duplex logging continuations destructors kernel math math.parser namespaces parser sequences strings prettyprint debugger quotations calendar threads concurrency.combinators -assocs fry ; +assocs fry accessors ; IN: io.server SYMBOL: servers @@ -15,9 +15,10 @@ SYMBOL: remote-address LOG: accepted-connection NOTICE -: with-connection ( client remote quot -- ) +: with-connection ( client remote local quot -- ) '[ , [ remote-address set ] [ accepted-connection ] bi + , local-address set @ ] with-stream ; inline @@ -25,7 +26,8 @@ LOG: accepted-connection NOTICE : accept-loop ( server quot -- ) [ - >r accept r> '[ , , , with-connection ] "Client" spawn drop + [ [ accept ] [ addr>> ] bi ] dip + '[ , , , , with-connection ] "Client" spawn drop ] 2keep accept-loop ; inline : server-loop ( addrspec encoding quot -- ) @@ -59,7 +61,7 @@ LOG: received-datagram NOTICE : datagram-loop ( quot datagram -- ) [ - [ receive dup received-datagram >r swap call r> ] keep + [ receive dup received-datagram [ swap call ] dip ] keep pick [ send ] [ 3drop ] if ] 2keep datagram-loop ; inline From 9aadcace246947ccadd04c7ca122ea5162230991 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 12 Jun 2008 18:54:38 -0500 Subject: [PATCH 011/354] Fix pool behavior with image save/restart --- extra/io/pools/pools.factor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/io/pools/pools.factor b/extra/io/pools/pools.factor index 033ba3cbfb..0e37e41a76 100644 --- a/extra/io/pools/pools.factor +++ b/extra/io/pools/pools.factor @@ -10,7 +10,7 @@ TUPLE: pool connections disposed expired ; dup check-disposed dup expired>> expired? [ ALIEN: 31337 >>expired - connections>> [ delete-all ] [ dispose-each ] bi + connections>> delete-all ] [ drop ] if ; : ( class -- pool ) @@ -34,6 +34,7 @@ GENERIC: make-connection ( pool -- conn ) dup check-pool [ make-connection ] keep return-connection ; : acquire-connection ( pool -- conn ) + dup check-pool [ dup connections>> empty? ] [ dup new-connection ] [ ] while connections>> pop ; From 3358381510851552d7c3d3005dff884bf303d11f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 12 Jun 2008 18:54:50 -0500 Subject: [PATCH 012/354] Better support for rest parameters on URLs --- extra/furnace/furnace.factor | 51 ++++++++++++++---------------- extra/webapps/blogs/blogs.factor | 2 ++ extra/webapps/blogs/edit-post.xml | 4 +-- extra/webapps/blogs/list-posts.xml | 6 ++-- extra/webapps/blogs/user-posts.xml | 8 ++--- extra/webapps/blogs/view-post.xml | 8 ++--- extra/webapps/wiki/articles.xml | 2 +- extra/webapps/wiki/changes.xml | 32 ++++++++++++------- extra/webapps/wiki/diff.xml | 4 +-- extra/webapps/wiki/page-common.xml | 8 ++--- extra/webapps/wiki/revisions.xml | 10 +++--- extra/webapps/wiki/user-edits.xml | 6 ++-- extra/webapps/wiki/view.xml | 2 +- extra/webapps/wiki/wiki.factor | 42 +++++++++++------------- 14 files changed, 93 insertions(+), 92 deletions(-) diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 99ccf33eec..6ddd84a254 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -97,15 +97,21 @@ SYMBOL: exit-continuation dup empty? [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ; -CHLOE: atom - [ children>string ] - [ "href" required-attr ] - [ "query" optional-attr parse-query-attr ] tri - - swap >>query - swap >>path - adjust-url relative-to-request - add-atom-feed ; +: a-url-path ( tag -- string ) + [ "href" required-attr ] [ "rest" optional-attr value ] bi + [ [ "/" ?tail drop "/" ] dip present 3append ] when* ; + +: a-url ( tag -- url ) + dup "value" optional-attr [ ] [ + + swap + [ a-url-path >>path ] + [ "query" optional-attr parse-query-attr >>query ] + bi + ] ?if + adjust-url relative-to-request ; + +CHLOE: atom [ children>string ] [ a-url ] bi add-atom-feed ; CHLOE: write-atom drop write-atom-feeds ; @@ -114,23 +120,11 @@ GENERIC: link-attr ( tag responder -- ) M: object link-attr 2drop ; : link-attrs ( tag -- ) + #! Side-effects current namespace. '[ , _ link-attr ] each-responder ; : a-start-tag ( tag -- ) - [ - - swap >>query - swap >>path - adjust-url relative-to-request =href - a> - ] with-scope ; + [ ] with-scope ; CHLOE: a [ a-start-tag ] @@ -158,11 +152,12 @@ CHLOE: a [ [
] [ form-magic ] bi diff --git a/extra/webapps/blogs/blogs.factor b/extra/webapps/blogs/blogs.factor index 8dbf7db690..882584f014 100644 --- a/extra/webapps/blogs/blogs.factor +++ b/extra/webapps/blogs/blogs.factor @@ -164,6 +164,8 @@ M: comment entity-url : ( -- action ) + "id" >>rest + [ validate-integer-id "id" value select-tuple from-object diff --git a/extra/webapps/blogs/edit-post.xml b/extra/webapps/blogs/edit-post.xml index da88a78ab0..4522f8606b 100644 --- a/extra/webapps/blogs/edit-post.xml +++ b/extra/webapps/blogs/edit-post.xml @@ -15,13 +15,13 @@ diff --git a/extra/webapps/blogs/list-posts.xml b/extra/webapps/blogs/list-posts.xml index 9c9685fe74..94a5a69775 100644 --- a/extra/webapps/blogs/list-posts.xml +++ b/extra/webapps/blogs/list-posts.xml @@ -7,7 +7,7 @@

- +

@@ -18,13 +18,13 @@