use of com.sun.jna.platform.win32.WinDef.LONGByReference in project jna by java-native-access.
the class SAFEARRAYTest method testADODB.
/**
* Test assumption: The windows search provider is present and holds at least
* five entries. If this assumption is not met, this test fails.
*/
@Test
public void testADODB() {
ObjectFactory fact = new ObjectFactory();
// Open a record set with a sample search (basicly get the first five
// entries from the search index
Connection conn = fact.createObject(Connection.class);
conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1);
Recordset recordset = fact.createObject(Recordset.class);
recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl, System.DateCreated FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
// Save complete list for comparison with subscript list
List<String> urls = new ArrayList<String>(5);
List<String> names = new ArrayList<String>(5);
while (!recordset.getEOF()) {
WinNT.HRESULT hr;
// Fetch (all) five rows and extract SAFEARRAY
SAFEARRAY sa = recordset.GetRows(5);
assertThat(sa.getDimensionCount(), is(2));
// Test getting bounds via automation functions SafeArrayGetLBound
// and SafeArrayGetUBound
// 5 rows (dimension 1) and 4 (dimension 2) columns should be
// returned, the indices are zero-based, the lower bounds are
// always zero
//
// Dimensions are inverted between SafeArray and java, so
// in this case row dimension 2 retrieves row count,
// dimension 1 retrieves column count
WinDef.LONGByReference res = new WinDef.LONGByReference();
hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), res);
assert COMUtils.SUCCEEDED(hr);
assertThat(res.getValue().intValue(), is(0));
hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), res);
assert COMUtils.SUCCEEDED(hr);
assertThat(res.getValue().intValue(), is(4));
hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(1), res);
assert COMUtils.SUCCEEDED(hr);
assertThat(res.getValue().intValue(), is(0));
hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(1), res);
assert COMUtils.SUCCEEDED(hr);
assertThat(res.getValue().intValue(), is(3));
// Get dimensions directly from structure
// lLbound contains lowerBound (first index)
// cElements contains count of elements
int row_lower = sa.rgsabound[0].lLbound.intValue();
int row_count = sa.rgsabound[0].cElements.intValue();
int column_lower = sa.rgsabound[1].lLbound.intValue();
int column_count = sa.rgsabound[1].cElements.intValue();
assertThat(row_lower, is(0));
assertThat(row_count, is(5));
assertThat(column_lower, is(0));
assertThat(column_count, is(4));
// Use Wrapper methods
assertThat(sa.getLBound(0), is(0));
assertThat(sa.getUBound(0), is(4));
assertThat(sa.getLBound(1), is(0));
assertThat(sa.getUBound(1), is(3));
// Columns 1 - 3 return Strings, Column 4 returns a date
for (int rowIdx = row_lower; rowIdx < row_lower + row_count; rowIdx++) {
for (int colIdx = column_lower; colIdx < column_lower + column_count; colIdx++) {
VARIANT result = (VARIANT) sa.getElement(rowIdx, colIdx);
Pointer pv = sa.ptrOfIndex(rowIdx, colIdx);
VARIANT result2 = new VARIANT(pv);
COMUtils.checkRC(hr);
if (colIdx == 3) {
assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
assert (result2.getVarType().intValue() & Variant.VT_DATE) > 0;
} else {
assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
assert (result2.getVarType().intValue() & Variant.VT_BSTR) > 0;
}
// Only clear result, as SafeArrayGetElement creates a copy
// result2 is a view into the SafeArray
OleAuto.INSTANCE.VariantClear(result);
}
}
// Access SafeArray directly
sa.lock();
try {
// Map the returned array to java
VARIANT[] variantArray = (VARIANT[]) (new VARIANT(sa.pvData.getPointer()).toArray(row_count * column_count));
for (int rowIdx = 0; rowIdx < row_count; rowIdx++) {
for (int colIdx = 0; colIdx < column_count; colIdx++) {
int index = rowIdx * column_count + colIdx;
VARIANT result = variantArray[index];
if (colIdx == 3) {
assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
} else {
assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
}
// see comment for urls
if (colIdx == 2) {
urls.add(result.stringValue());
} else if (colIdx == 1) {
names.add(result.stringValue());
}
}
}
} finally {
sa.unlock();
}
// Access SafeArray directly - Variant 2
Pointer data = sa.accessData();
try {
// Map the returned array to java
VARIANT[] variantArray = (VARIANT[]) (new VARIANT(data).toArray(row_count * column_count));
for (int rowIdx = 0; rowIdx < row_count; rowIdx++) {
for (int colIdx = 0; colIdx < column_count; colIdx++) {
int index = rowIdx * column_count + colIdx;
VARIANT result = variantArray[index];
if (colIdx == 3) {
assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
} else {
assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
}
// see comment for urls
if (colIdx == 2) {
urls.add(result.stringValue());
} else if (colIdx == 1) {
names.add(result.stringValue());
}
}
}
} finally {
sa.unaccessData();
}
sa.destroy();
}
recordset.Close();
// Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl"
recordset = fact.createObject(Recordset.class);
recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
// Create SAFEARRAY and wrap it into a VARIANT
// Array is initialized to one element and then redimmed. This is done
// to test SafeArrayRedim, in normal usage it is more efficient to
// intitialize directly to the correct size
SAFEARRAY arr = SAFEARRAY.createSafeArray(1);
arr.putElement(new VARIANT("System.ItemUrl"), 0);
boolean exceptionCaught = false;
try {
arr.putElement(new VARIANT("System.ItemName"), 1);
} catch (COMException ex) {
exceptionCaught = true;
}
assertTrue("Array is initialized to a size of one - it can't hold a second item.", exceptionCaught);
arr.redim(2, 0);
arr.putElement(new VARIANT("System.ItemName"), 1);
assertThat(arr.getDimensionCount(), is(1));
VARIANT columnList = new VARIANT();
columnList.setValue(Variant.VT_ARRAY | Variant.VT_VARIANT, arr);
assert !(recordset.getEOF());
while (!recordset.getEOF()) {
SAFEARRAY sa = recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList);
assertThat(sa.getDimensionCount(), is(2));
assertThat(sa.getVarType().intValue(), is(Variant.VT_VARIANT));
LONGByReference longRef = new LONGByReference();
OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), longRef);
int lowerBound = longRef.getValue().intValue();
assertThat(sa.getLBound(0), equalTo(lowerBound));
OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), longRef);
int upperBound = longRef.getValue().intValue();
assertThat(sa.getUBound(0), equalTo(upperBound));
// 5 rows are expected
assertThat(upperBound - lowerBound + 1, is(5));
for (int rowIdx = lowerBound; rowIdx <= upperBound; rowIdx++) {
VARIANT variantItemUrl = (VARIANT) sa.getElement(rowIdx, 0);
VARIANT variantItemName = (VARIANT) sa.getElement(rowIdx, 1);
assertThat(variantItemUrl.stringValue(), is(urls.get(rowIdx)));
assertThat(variantItemName.stringValue(), is(names.get(rowIdx)));
OleAuto.INSTANCE.VariantClear(variantItemUrl);
OleAuto.INSTANCE.VariantClear(variantItemName);
}
sa.destroy();
}
recordset.Close();
// Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl"
recordset = fact.createObject(Recordset.class);
recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
assert !(recordset.getEOF());
while (!recordset.getEOF()) {
Object[][] data = (Object[][]) OaIdlUtil.toPrimitiveArray(recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList), true);
assertThat(data.length, is(5));
assertThat(data[0].length, is(2));
for (int rowIdx = 0; rowIdx < data.length; rowIdx++) {
assertThat((String) data[rowIdx][0], is(urls.get(rowIdx)));
assertThat((String) data[rowIdx][1], is(names.get(rowIdx)));
}
}
recordset.Close();
conn.Close();
fact.disposeAll();
}
Aggregations