summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-01-09 02:59:57 +0000
committerRich Hickey <richhickey@gmail.com>2008-01-09 02:59:57 +0000
commit2a12d40a8e26af95b614fa420591039a37f06626 (patch)
treecfdb2f8b069d7a6c7ef45bac06d8ffa59dfa20e6 /src
parentf7c87e059355badcfbc8d80c2ed6ab8acb3c1d73 (diff)
added construct, resultset-seq, keyword fn, vars in namespace tables
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj23
-rw-r--r--src/jvm/clojure/lang/PersistentStructMap.java89
-rw-r--r--src/jvm/clojure/lang/Var.java24
3 files changed, 96 insertions, 40 deletions
diff --git a/src/boot.clj b/src/boot.clj
index 6ac33e35..7c9b8b5a 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -95,6 +95,10 @@
([name] (. clojure.lang.Symbol (intern name)))
([ns name] (. clojure.lang.Symbol (intern ns name))))
+(defn keyword
+ ([name] (. clojure.lang.Keyword (intern nil name)))
+ ([ns name] (. clojure.lang.Keyword (intern ns name))))
+
(defn gensym
([] (thisfn "G__"))
([prefix-string] (. clojure.lang.Symbol (intern (strcat prefix-string (str (. clojure.lang.RT (nextID))))))))
@@ -952,6 +956,9 @@
(defn struct [s & inits]
(. clojure.lang.PersistentStructMap (create s inits)))
+(defn construct [s & vals]
+ (. clojure.lang.PersistentStructMap (construct s vals)))
+
(defn accessor [s key]
(. clojure.lang.PersistentStructMap (getAccessor s key)))
@@ -964,6 +971,17 @@
(defn load [rdr]
(. clojure.lang.Compiler (load rdr)))
+(defn resultset-seq [#^java.sql.ResultSet rs]
+ (let [rsmeta (. rs (getMetaData))
+ idxs (range 1 (inc (. rsmeta (getColumnCount))))
+ keys (map (comp keyword (memfn toLowerCase))
+ (map (fn [i] (. rsmeta (getColumnName i))) idxs))
+ row-struct (apply create-struct keys)
+ row-values (fn [] (map (fn [#^Integer i] (. rs (getObject i))) idxs))
+ rows (fn []
+ (when (. rs (next))
+ (fnseq (apply construct row-struct (row-values)) thisfn)))]
+ (rows)))
(def *exports*
'(clojure
@@ -983,7 +1001,7 @@
scan touch
key val
line-seq sort sort-by comparator
- rseq sym name namespace locking .. ->
+ rseq sym keyword name namespace locking .. ->
defmulti defmethod remove-method
binding find-var
ref deref commute alter set ensure sync !
@@ -1009,9 +1027,10 @@
max min
bit-shift-left bit-shift-right
bit-and bit-or bit-xor bit-not
- defstruct struct accessor create-struct
+ defstruct struct accessor create-struct construct
subvec
false? true?
*warn-on-reflection*
+ resultset-seq
))
diff --git a/src/jvm/clojure/lang/PersistentStructMap.java b/src/jvm/clojure/lang/PersistentStructMap.java
index 3ceba52c..28d46426 100644
--- a/src/jvm/clojure/lang/PersistentStructMap.java
+++ b/src/jvm/clojure/lang/PersistentStructMap.java
@@ -17,52 +17,71 @@ import java.util.Map;
public class PersistentStructMap extends APersistentMap{
-final IPersistentMap keyslots;
+public static class Def{
+ final ISeq keys;
+ final IPersistentMap keyslots;
+
+ Def(ISeq keys, IPersistentMap keyslots){
+ this.keys = keys;
+ this.keyslots = keyslots;
+ }
+}
+
+final Def def;
final Object[] vals;
final IPersistentMap ext;
-static public IPersistentMap createSlotMap(ISeq keys){
+static public Def createSlotMap(ISeq keys){
if(keys == null)
throw new IllegalArgumentException("Must supply keys");
- PersistentHashMap temp = PersistentHashMap.EMPTY;
- for(ISeq s = keys; s != null; s = s.rest())
- {
- temp = (PersistentHashMap) temp.assoc(s.first(), null);
- }
- int i = 0;
PersistentHashMap ret = PersistentHashMap.EMPTY;
- for(ISeq s = RT.keys(temp); s != null; s = s.rest(), i++)
+ int i=0;
+ for(ISeq s = keys; s != null; s = s.rest(),i++)
+ {
ret = (PersistentHashMap) ret.assoc(s.first(), i);
- return ret;
+ }
+ return new Def(keys,ret);
}
-static public PersistentStructMap create(IPersistentMap keyslots, ISeq init){
- Object[] vals = new Object[keyslots.count()];
+static public PersistentStructMap create(Def def, ISeq keyvals){
+ Object[] vals = new Object[def.keyslots.count()];
IPersistentMap ext = PersistentHashMap.EMPTY;
- for(; init != null; init = init.rest().rest())
+ for(; keyvals != null; keyvals = keyvals.rest().rest())
{
- if(init.rest() == null)
- throw new IllegalArgumentException(String.format("No value supplied for key: %s", init.first()));
- Object k = init.first();
- Object v = RT.second(init);
- Map.Entry e = keyslots.entryAt(k);
+ if(keyvals.rest() == null)
+ throw new IllegalArgumentException(String.format("No value supplied for key: %s", keyvals.first()));
+ Object k = keyvals.first();
+ Object v = RT.second(keyvals);
+ Map.Entry e = def.keyslots.entryAt(k);
if(e != null)
vals[(Integer) e.getValue()] = v;
else
ext = ext.assoc(k, v);
}
- return new PersistentStructMap(null, keyslots, vals, ext);
+ return new PersistentStructMap(null, def, vals, ext);
+}
+
+static public PersistentStructMap construct(Def def, ISeq valseq){
+ Object[] vals = new Object[def.keyslots.count()];
+ IPersistentMap ext = PersistentHashMap.EMPTY;
+ for(int i=0;i<vals.length && valseq != null; valseq = valseq.rest(),i++)
+ {
+ vals[i] = valseq.first();
+ }
+ if(valseq != null)
+ throw new IllegalArgumentException("Too many arguments to struct constructor");
+ return new PersistentStructMap(null, def, vals, ext);
}
-static public IFn getAccessor(final IPersistentMap keyslots, Object key){
- Map.Entry e = keyslots.entryAt(key);
+static public IFn getAccessor(final Def def, Object key){
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
{
final int i = (Integer) e.getValue();
return new AFn(){
public Object invoke(Object arg1) throws Exception{
PersistentStructMap m = (PersistentStructMap) arg1;
- if(m.keyslots != keyslots)
+ if(m.def != def)
throw new Exception("Accessor/struct mismatch");
return m.vals[i];
}
@@ -71,10 +90,10 @@ static public IFn getAccessor(final IPersistentMap keyslots, Object key){
throw new IllegalArgumentException("Not a key of struct");
}
-PersistentStructMap(IPersistentMap meta, IPersistentMap keys, Object[] vals, IPersistentMap ext){
+PersistentStructMap(IPersistentMap meta, Def def, Object[] vals, IPersistentMap ext){
super(meta);
this.ext = ext;
- this.keyslots = keys;
+ this.def = def;
this.vals = vals;
}
@@ -82,15 +101,15 @@ PersistentStructMap(IPersistentMap meta, IPersistentMap keys, Object[] vals, IPe
public Obj withMeta(IPersistentMap meta){
if(meta == _meta)
return this;
- return new PersistentStructMap(meta, keyslots, vals, ext);
+ return new PersistentStructMap(meta, def, vals, ext);
}
public boolean containsKey(Object key){
- return keyslots.containsKey(key) || ext.containsKey(key);
+ return def.keyslots.containsKey(key) || ext.containsKey(key);
}
public IMapEntry entryAt(Object key){
- Map.Entry e = keyslots.entryAt(key);
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
{
return new MapEntry(key, vals[(Integer) e.getValue()]);
@@ -99,19 +118,19 @@ public IMapEntry entryAt(Object key){
}
public IPersistentMap assoc(Object key, Object val){
- Map.Entry e = keyslots.entryAt(key);
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
{
int i = (Integer) e.getValue();
Object[] newVals = vals.clone();
newVals[i] = val;
- return new PersistentStructMap(_meta, keyslots, newVals, ext);
+ return new PersistentStructMap(_meta, def, newVals, ext);
}
- return new PersistentStructMap(_meta, keyslots, vals, ext.assoc(key, val));
+ return new PersistentStructMap(_meta, def, vals, ext.assoc(key, val));
}
public Object valAt(Object key){
- Map.Entry e = keyslots.entryAt(key);
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
{
return vals[(Integer) e.getValue()];
@@ -120,7 +139,7 @@ public Object valAt(Object key){
}
public Object valAt(Object key, Object notFound){
- Map.Entry e = keyslots.entryAt(key);
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
{
return vals[(Integer) e.getValue()];
@@ -135,13 +154,13 @@ public IPersistentMap assocEx(Object key, Object val) throws Exception{
}
public IPersistentMap without(Object key) throws Exception{
- Map.Entry e = keyslots.entryAt(key);
+ Map.Entry e = def.keyslots.entryAt(key);
if(e != null)
throw new Exception("Can't remove struct key");
IPersistentMap newExt = ext.without(key);
if(newExt == ext)
return this;
- return new PersistentStructMap(_meta, keyslots, vals, newExt);
+ return new PersistentStructMap(_meta, def, vals, newExt);
}
public Iterator iterator(){
@@ -154,7 +173,7 @@ public int count(){
}
public ISeq seq(){
- return new Seq(null, RT.keys(keyslots), vals, 0, ext);
+ return new Seq(null, def.keys, vals, 0, ext);
}
static class Seq extends ASeq{
diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java
index 3c1dd3f4..36ebd915 100644
--- a/src/jvm/clojure/lang/Var.java
+++ b/src/jvm/clojure/lang/Var.java
@@ -50,13 +50,17 @@ final public Symbol sym;
boolean macroFlag = false;
Symbol tag;
-static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>();
+static ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>> namespaces =
+ new ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>>();
+
+//static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>();
public static Var intern(Symbol sym, Object root){
return intern(sym, root, true);
}
public static Var intern(Symbol sym, Object root, boolean replaceRoot){
+ ConcurrentHashMap<Symbol, Var> table = table(sym);
Var dvout = table.get(sym);
boolean present = dvout != null;
@@ -79,6 +83,7 @@ public String toString(){
}
public static Var intern(Symbol sym){
+ ConcurrentHashMap<Symbol, Var> table = table(sym);
Var dvout = table.get(sym);
if(dvout != null)
return dvout;
@@ -90,13 +95,26 @@ public static Var intern(Symbol sym){
}
public static void unintern(Symbol sym){
- table.remove(sym);
+ table(sym).remove(sym);
}
public static Var find(Symbol sym){
- return table.get(sym);
+ return table(sym).get(sym);
+}
+
+static ConcurrentHashMap<Symbol, Var> table(Symbol sym){
+ String name = sym.ns;
+ if(name == null)
+ throw new IllegalArgumentException("Var names must have namespace");
+ ConcurrentHashMap<Symbol, Var> ns = namespaces.get(name);
+ if(ns != null)
+ return ns;
+ ConcurrentHashMap<Symbol, Var> newns = new ConcurrentHashMap<Symbol, Var>();
+ ns = namespaces.putIfAbsent(name,newns);
+ return ns == null?newns:ns;
}
+
public static Var create(){
return new Var(null);
}