1 5 package org.h2.result; 6 7 import java.sql.SQLException ; 8 9 import org.h2.engine.Constants; 10 import org.h2.engine.Database; 11 import org.h2.expression.Expression; 12 import org.h2.util.ObjectArray; 13 import org.h2.util.StringUtils; 14 import org.h2.value.Value; 15 import org.h2.value.ValueNull; 16 17 20 21 public class SortOrder { 22 public static final int ASCENDING = 0, DESCENDING = 1; 23 public static final int NULLS_FIRST = 2, NULLS_LAST = 4; 24 25 private Database database; 26 private int len; 27 private int[] indexes; 28 private int[] sortTypes; 29 30 public SortOrder(Database database, int[] index, int[] sortType) { 31 this.database = database; 32 this.indexes = index; 33 this.sortTypes = sortType; 34 len = index.length; 35 } 36 37 public String getSQL(Expression[] list, int visible) { 38 StringBuffer buff = new StringBuffer (); 39 for (int i = 0; i < len; i++) { 40 if (i > 0) { 41 buff.append(", "); 42 } 43 int idx = indexes[i]; 44 if (idx < visible) { 45 buff.append(idx + 1); 46 } else { 47 buff.append("="); 48 buff.append(StringUtils.unEnclose(list[idx].getSQL())); 49 } 50 int type = sortTypes[i]; 51 if ((type & DESCENDING) != 0) { 52 buff.append(" DESC"); 53 } 54 if ((type & NULLS_FIRST) != 0) { 55 buff.append(" NULLS FIRST"); 56 } else if ((type & NULLS_LAST) != 0) { 57 buff.append(" NULLS LAST"); 58 } 59 } 60 return buff.toString(); 61 } 62 63 public int compare(Value[] a, Value[] b) throws SQLException { 64 for (int i = 0; i < len; i++) { 65 int idx = indexes[i]; 66 int type = sortTypes[i]; 67 Value o1 = a[idx]; 68 Value o2 = b[idx]; 69 boolean b1 = o1 == ValueNull.INSTANCE, b2 = o2 == ValueNull.INSTANCE; 70 if (b1 || b2) { 71 if (b1 == b2) { 72 continue; 73 } 74 if ((type & NULLS_FIRST) != 0) { 75 return b1 ? -1 : 1; 76 } else if ((type & NULLS_LAST) != 0) { 77 return b1 ? 1 : -1; 78 } else { 79 int comp; 81 if (Constants.NULL_SORT_DEFAULT == Constants.NULL_SORT_LOW) { 82 comp = b1 ? -1 : 1; 83 return (type & DESCENDING) == 0 ? comp : -comp; 84 } else if (Constants.NULL_SORT_DEFAULT == Constants.NULL_SORT_HIGH) { 85 comp = b1 ? 1 : -1; 86 return (type & DESCENDING) == 0 ? comp : -comp; 87 } else if (Constants.NULL_SORT_DEFAULT == Constants.NULL_SORT_START) { 88 return b1 ? 1 : -1; 89 } else { 90 return b1 ? -1 : 1; 91 } 92 } 93 } 94 int comp = database.compare(o1, o2); 95 if (comp != 0) { 96 return (type & DESCENDING) == 0 ? comp : -comp; 97 } 98 } 99 return 0; 100 } 101 102 public void sort(ObjectArray rows) throws SQLException { 103 sort(rows, 0, rows.size() - 1); 104 } 105 106 private void swap(ObjectArray rows, int a, int b) { 107 Object t = rows.get(a); 108 rows.set(a, rows.get(b)); 109 rows.set(b, t); 110 } 111 112 private void sort(ObjectArray rows, int l, int r) throws SQLException { 113 int i, j; 114 while (r - l > 10) { 115 i = (r + l) >> 1; 116 if (compare((Value[]) rows.get(l), (Value[]) rows.get(r)) > 0) { 117 swap(rows, l, r); 118 } 119 if (compare((Value[]) rows.get(i), (Value[]) rows.get(l)) < 0) { 120 swap(rows, l, i); 121 } else if (compare((Value[]) rows.get(i), (Value[]) rows.get(r)) > 0) { 122 swap(rows, i, r); 123 } 124 j = r - 1; 125 swap(rows, i, j); 126 Value[] p = (Value[]) rows.get(j); 127 i = l; 128 while (true) { 129 do { 130 ++i; 131 } while (compare((Value[]) rows.get(i), p) < 0); 132 do { 133 --j; 134 } while (compare((Value[]) rows.get(j), p) > 0); 135 if (i >= j) { 136 break; 137 } 138 swap(rows, i, j); 139 } 140 swap(rows, i, r - 1); 141 sort(rows, l, i - 1); 142 l = i + 1; 143 } 144 for (i = l + 1; i <= r; i++) { 145 Value[] t = (Value[]) rows.get(i); 146 for (j = i - 1; j >= l && (compare((Value[]) rows.get(j), t) > 0); j--) { 147 rows.set(j + 1, rows.get(j)); 148 } 149 rows.set(j + 1, t); 150 } 151 } 152 153 public int[] getIndexes() { 154 return indexes; 155 } 156 157 public int[] getSortTypes() { 158 return sortTypes; 159 } 160 161 } 162 | Popular Tags |