001: /*
002: * Utils.java
003: * tinySQL, some helper methods
004: *
005: * $Author: davis $
006: * $Date: 2004/12/18 21:27:20 $
007: * $Revision: 1.1 $
008: */
009: package com.sqlmagic.tinysql;
010:
011: import java.util.*;
012: import java.lang.*;
013: import java.io.*;
014: import java.sql.Types;
015:
016: /**
017: Some helper methods for tinySQL
018: @author Brian Jepson <bjepson@home.com>
019: @author Marcel Ruff <ruff@swand.lake.de> Added write access to dBase and JDK 2 support
020: */
021: public class Utils {
022: // JLex (the lexical analyzer) doesn´t support unicode
023: // so we must play around with the different code pages:
024: // "Cp437" = 7 bit MS-DOS, US-ASCII
025: // "Cp850" = 8 bit MS-DOS, Multilingual Latin 1, ä = 0x83 = 131
026: // "Cp1252" = 8 bit Windows Multilingual, ä = 0xe4 = 228
027: // In future the code page should be passed at connection time using the URL
028: final static String encode = "Cp1252"; // dBase encoding
029:
030: /**
031: * Converts a long to a little-endian four-byte array
032: *
033: */
034: public final static byte[] intToLittleEndian(int val) {
035: byte[] b = new byte[4];
036: for (int i = 0; i < 4; i++) {
037: b[i] = (byte) (val % 256);
038: val = val / 256;
039: }
040: return b;
041: }
042:
043: /**
044: * Converts a long to a little-endian two-byte array
045: *
046: */
047: public final static byte[] shortToLittleEndian(short val) {
048: byte[] b = new byte[2];
049: for (int i = 0; i < 2; i++) {
050: b[i] = (byte) (val % 256);
051: val = (short) (val / 256);
052: }
053: return b;
054: }
055:
056: /**
057: *
058: * Converts a little-endian four-byte array to a long,
059: * represented as a double, since long is signed.
060: *
061: * I don't know why Java doesn't supply this. It could
062: * be that it's there somewhere, but I looked and couldn't
063: * find it.
064: *
065: */
066: public final static double vax_to_long(byte[] b) {
067:
068: //existing code that has been commented out
069: //return fixByte(b[0]) + ( fixByte(b[1]) * 256) +
070: //( fixByte(b[2]) * (256^2)) + ( fixByte(b[3]) * (256^3));
071:
072: // Fix courtesy Preetha Suri <Preetha.Suri@sisl.co.in>
073: //
074: long lngTmp = (long) (0x0ffL & b[0])
075: | ((0x0ffL & (long) b[1]) << 8)
076: | ((0x0ffL & (long) b[2]) << 16)
077: | ((0x0ffL & (long) b[3]) << 24);
078:
079: return ((double) lngTmp);
080:
081: }
082:
083: /**
084: *
085: * Converts a little-endian four-byte array to a short,
086: * represented as an int, since short is signed.
087: *
088: * I don't know why Java doesn't supply this. It could
089: * be that it's there somewhere, but I looked and couldn't
090: * find it.
091: *
092: */
093: public final static int vax_to_short(byte[] b) {
094: return (int) (fixByte(b[0]) + (fixByte(b[1]) * 256));
095: }
096:
097: /*
098: *
099: * bytes are signed; let's fix them...
100: *
101: */
102: public final static short fixByte(byte b) {
103:
104: if (b < 0) {
105: return (short) (b + 256);
106: }
107: return b;
108: }
109:
110: /**
111: Cut or padd the string to the given size
112: @param a string
113: @param size the wanted length
114: @param padChar char to use for padding (must be of length()==1!)
115: @return the string with correct lenght, padded with pad if necessary
116: */
117: public final static String forceToSize(String str, int size,
118: String padChar) {
119: if (str != null && str.length() == size)
120: return str;
121:
122: StringBuffer tmp;
123: if (str == null)
124: tmp = new StringBuffer(size);
125: else
126: tmp = new StringBuffer(str);
127:
128: if (tmp.length() > size) {
129: return tmp.toString().substring(0, size); // do cutting
130: } else {
131: // or add some padding to the end of the string
132: StringBuffer pad = new StringBuffer(size);
133: int numBlanks = size - tmp.length();
134: for (int p = 0; p < numBlanks; p++) {
135: pad.append(padChar);
136: }
137: return tmp.append(pad).toString();
138: }
139: }
140:
141: /**
142: Cut or padd the string to the given size
143: @param a string
144: @param size the wanted length
145: @param padByte char to use for padding
146: @return the string with correct lenght, padded with pad if necessary
147: */
148: public final static byte[] forceToSize(String str, int size,
149: byte padByte) throws java.io.UnsupportedEncodingException {
150: if (str != null && str.length() == size)
151: return str.getBytes(encode);
152:
153: byte[] result = new byte[size];
154:
155: if (str == null) {
156: for (int ii = 0; ii < size; ii++)
157: result[ii] = padByte;
158: return result;
159: }
160:
161: if (str.length() > size)
162: return str.substring(0, size).getBytes(encode); // do cutting
163:
164: // do padding
165: byte[] tmp = str.getBytes(encode);
166: for (int jj = 0; jj < tmp.length; jj++)
167: result[jj] = tmp[jj];
168: for (int kk = tmp.length; kk < size; kk++)
169: result[kk] = padByte;
170: return result;
171: }
172:
173: /*
174: * Delete a file in the data directory
175: */
176: public final static void delFile(String fname)
177: throws NullPointerException, IOException {
178: File f = new File(fname);
179:
180: // only delete a file that exists
181: //
182: if (f.exists()) {
183: // try the delete. If it fails, complain
184: //
185: if (!f.delete()) {
186: throw new IOException("Could not delete: "
187: + f.getAbsolutePath() + ".");
188: }
189: }
190: }
191:
192: public final static void delFile(String dataDir, String fname)
193: throws NullPointerException, IOException {
194:
195: File f = new File(dataDir + File.separator + fname);
196:
197: // only delete a file that exists
198: //
199: if (f.exists()) {
200: // try the delete. If it fails, complain
201: //
202: if (!f.delete()) {
203: throw new IOException("Could not delete file: "
204: + dataDir + "/" + fname + ".");
205: }
206: }
207: }
208:
209: /**
210: rename a file
211: @return true if succeeded
212: */
213: public final static boolean renameFile(String oldName,
214: String newName) {
215: File f_old = new File(oldName);
216: File f_new = new File(newName);
217: boolean ret = f_old.renameTo(f_new);
218: return ret;
219: }
220:
221: /**
222: Strip the path and suffix of a file name
223: @param file "/usr/local/dbase/test.DBF"
224: @return "test"
225: */
226: public final static String stripPathAndExtension(final String file) {
227: String sep = File.separator;
228: int begin = file.lastIndexOf(sep);
229: if (begin < 0)
230: begin = 0;
231: else
232: begin++;
233: int end = file.lastIndexOf(".");
234: if (end < 0)
235: end = file.length();
236: String str = file.substring(begin, end);
237: return str;
238: }
239:
240: /*
241: * Scan the given directory for files containing the substrMatch<br>
242: * Small case extensions '.dbf' are recognized and returned as '.DBF'
243: */
244: public final static Vector getAllFiles(final String path,
245: final String suffix) {
246: Vector vec = (Vector) null;
247: String[] fileNameList;
248: File currentDir, f;
249: String fileName, upperSuffix;
250: int i;
251: upperSuffix = suffix.toUpperCase();
252: currentDir = new File(path);
253: fileNameList = currentDir.list();
254: if (fileNameList == null) {
255: System.out.println("*** null for " + path);
256: } else {
257: vec = new Vector(fileNameList.length);
258: for (i = 0; i < fileNameList.length; i++) {
259: f = new File(fileNameList[i]);
260: if (!f.isDirectory()) {
261: fileName = f.getPath().toString().toUpperCase();
262: // lastModified = new java.util.Date(f.lastModified());
263: if (upperSuffix == null
264: | fileName.endsWith(upperSuffix)) {
265: vec.addElement(f);
266: }
267: }
268: }
269: }
270: return vec;
271: }
272:
273: public static boolean isDateColumn(int columnType) {
274: if (columnType == Types.DATE | columnType == Types.TIMESTAMP)
275: return true;
276: else
277: return false;
278: }
279:
280: public static boolean isCharColumn(int columnType) {
281: if (columnType == Types.CHAR | columnType == Types.VARCHAR
282: | columnType == Types.LONGVARCHAR)
283: return true;
284: else
285: return false;
286: }
287:
288: public static boolean isNumberColumn(int columnType) {
289: if (columnType == Types.NUMERIC | columnType == Types.INTEGER
290: | columnType == Types.TINYINT
291: | columnType == Types.SMALLINT
292: | columnType == Types.BIGINT
293: | columnType == Types.FLOAT
294: | columnType == Types.DOUBLE | columnType == Types.REAL)
295: return true;
296: else
297: return false;
298: }
299:
300: public static boolean isFunctionName(String inputName) {
301: int i;
302: String[] functionNames = { "COUNT", "SUM", "MIN", "MAX",
303: "UPPER", "TRIM", "SUBSTR", "CONCAT", "TO_DATE" };
304: for (i = 0; i < functionNames.length; i++)
305: if (inputName.equalsIgnoreCase(functionNames[i]))
306: return true;
307: return false;
308: }
309:
310: public static boolean endsWithFunctionName(String inputName) {
311: int i;
312: String upperName;
313: String[] functionNames = { "COUNT", "SUM", "MIN", "MAX",
314: "UPPER", "TRIM", "SUBSTR", "CONCAT", "TO_DATE" };
315: upperName = inputName.toUpperCase();
316: for (i = 0; i < functionNames.length; i++)
317: if (upperName.endsWith(functionNames[i]))
318: return true;
319: return false;
320: }
321:
322: /*
323: * This function indicates which functions should be set to null if any
324: * of its arguments are null.
325: */
326: public static boolean clearFunction(String inputName) {
327: int i;
328: String[] functionNames = { "UPPER", "TRIM", "SUBSTR" };
329: for (i = 0; i < functionNames.length; i++)
330: if (inputName.equalsIgnoreCase(functionNames[i]))
331: return true;
332: return false;
333: }
334:
335: /*
336: * Move the input table to the top of the selection list.
337: */
338: public static void setPriority(Vector inputList, String inputTable) {
339: String tableName;
340: int i;
341: if (inputList == (Vector) null)
342: return;
343: for (i = 0; i < inputList.size(); i++) {
344: tableName = (String) inputList.elementAt(i);
345: if (tableName.equals(inputTable)) {
346: if (i > 0) {
347: inputList.removeElementAt(i);
348: inputList.insertElementAt(tableName, 0);
349: }
350: break;
351: }
352: }
353: }
354:
355: /**
356: For debugging/tracing
357: Switch the debug mode on/off:
358: */
359: final static boolean debug = false;
360:
361: final static void log(String id, String str) {
362: if (debug)
363: log(id + ": " + str);
364: }
365:
366: final static void log(String str) {
367: if (debug)
368: System.out.println(str);
369: }
370:
371: }
|