1   /*
2   Copyright (c) 2007 Health Market Science, Inc.
3   
4   This library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Lesser General Public
6   License as published by the Free Software Foundation; either
7   version 2.1 of the License, or (at your option) any later version.
8   
9   This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  Lesser General Public License for more details.
13  
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
17  USA
18  
19  You can contact Health Market Science at info@healthmarketscience.com
20  or at the following address:
21  
22  Health Market Science
23  2700 Horizon Drive
24  Suite 200
25  King of Prussia, PA 19406
26  */
27  
28  package com.healthmarketscience.jackcess;
29  
30  import java.io.IOException;
31  import java.nio.ByteBuffer;
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.List;
35  
36  import junit.framework.TestCase;
37  
38  /**
39   * @author Tim McCune
40   */
41  public class TableTest extends TestCase {
42  
43    private final PageChannel _pageChannel = new PageChannel(true);
44    private List<Column> _columns = new ArrayList<Column>();
45    private Table _testTable;
46    
47    public TableTest(String name) {
48      super(name);
49    }
50    
51    public void testCreateRow() throws Exception {
52      Column col = newTestColumn();
53      col.setType(DataType.INT);
54      _columns.add(col);
55      col = newTestColumn();
56      col.setType(DataType.TEXT);
57      _columns.add(col);
58      col = newTestColumn();
59      col.setType(DataType.TEXT);
60      _columns.add(col);
61      newTestTable();
62      
63      int colCount = _columns.size();
64      ByteBuffer buffer = createRow(9, "Tim", "McCune");
65  
66      assertEquals((short) colCount, buffer.getShort());
67      assertEquals((short) 9, buffer.getShort());
68      assertEquals((byte) 'T', buffer.get());
69      assertEquals((short) 22, buffer.getShort(22));
70      assertEquals((short) 10, buffer.getShort(24));
71      assertEquals((short) 4, buffer.getShort(26));
72      assertEquals((short) 2, buffer.getShort(28));
73      assertEquals((byte) 7, buffer.get(30));
74    }
75  
76    public void testUnicodeCompression() throws Exception {
77      Column col = newTestColumn();
78      col = newTestColumn();
79      col.setType(DataType.TEXT);
80      _columns.add(col);
81      col = newTestColumn();
82      col.setType(DataType.MEMO);
83      _columns.add(col);
84      newTestTable();
85  
86      String small = "this is a string";
87      String smallNotAscii = "this is a string\0";
88      String large = DatabaseTest.createString(30);
89      String largeNotAscii = large + "\0";
90  
91      ByteBuffer[] buf1 = encodeColumns(small, large);
92      ByteBuffer[] buf2 = encodeColumns(smallNotAscii, largeNotAscii);
93  
94      for(Column tmp : _columns) {
95        tmp.setCompressedUnicode(true);
96      }
97      
98      ByteBuffer[] bufCmp1 = encodeColumns(small, large);
99      ByteBuffer[] bufCmp2 = encodeColumns(smallNotAscii, largeNotAscii);
100     
101     assertEquals(buf1[0].remaining(),
102                  (bufCmp1[0].remaining() + small.length() - 2));
103     assertEquals(buf1[1].remaining(),
104                  (bufCmp1[1].remaining() + large.length() - 2));
105 
106     for(int i = 0; i < buf2.length; ++i) {
107       assertTrue(Arrays.equals(toBytes(buf2[i]), toBytes(bufCmp2[i])));
108     }
109 
110     assertEquals(Arrays.asList(small, large),
111                  Arrays.asList(decodeColumns(bufCmp1)));
112     assertEquals(Arrays.asList(smallNotAscii, largeNotAscii),
113                  Arrays.asList(decodeColumns(bufCmp2)));
114 
115   }
116 
117   private ByteBuffer createRow(Object... row) 
118     throws IOException
119   {
120     return _testTable.createRow(
121         row, _testTable.getFormat().MAX_ROW_SIZE,
122         _testTable.getPageChannel().createPageBuffer());
123   }
124 
125   private ByteBuffer[] encodeColumns(Object... row)
126     throws IOException
127   {
128     ByteBuffer[] result = new ByteBuffer[_columns.size()];
129     for(int i = 0; i < _columns.size(); ++i) {
130       Column col = _columns.get(i);
131       result[i] = col.write(row[i], _testTable.getFormat().MAX_ROW_SIZE);
132     }
133     return result;
134   }
135 
136   private Object[] decodeColumns(ByteBuffer[] buffers)
137     throws IOException
138   {
139     Object[] result = new Object[_columns.size()];
140     for(int i = 0; i < _columns.size(); ++i) {
141       Column col = _columns.get(i);
142       result[i] = col.read(toBytes(buffers[i]));
143     }
144     return result;
145   }
146 
147   private static byte[] toBytes(ByteBuffer buffer) {
148     buffer.rewind();
149     byte[] b = new byte[buffer.remaining()];
150     buffer.get(b);
151     return b;
152   }
153 
154   private Table newTestTable() 
155     throws Exception
156   {
157     _testTable = new Table(true, _columns) {
158         @Override
159         public PageChannel getPageChannel() {
160           return _pageChannel;
161         }
162         @Override
163         public JetFormat getFormat() {
164           return JetFormat.VERSION_4;
165         }
166       };
167     return _testTable;
168   }
169 
170   private Column newTestColumn() {
171     return new Column(true) {
172         @Override
173         public Table getTable() {
174           return _testTable;
175         }
176       };
177   }
178   
179 }