Search in sources :

Example 1 with LONGByReference

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();
}
Also used : COMException(com.sun.jna.platform.win32.COM.COMException) SAFEARRAY(com.sun.jna.platform.win32.OaIdl.SAFEARRAY) LONGByReference(com.sun.jna.platform.win32.WinDef.LONGByReference) ArrayList(java.util.ArrayList) Pointer(com.sun.jna.Pointer) VARIANT(com.sun.jna.platform.win32.Variant.VARIANT) IConnectionPoint(com.sun.jna.platform.win32.COM.util.IConnectionPoint) ObjectFactory(com.sun.jna.platform.win32.COM.util.ObjectFactory) ComObject(com.sun.jna.platform.win32.COM.util.annotation.ComObject) UINT(com.sun.jna.platform.win32.WinDef.UINT) VT_UINT(com.sun.jna.platform.win32.Variant.VT_UINT) LONGByReference(com.sun.jna.platform.win32.WinDef.LONGByReference) Test(org.junit.Test)

Aggregations

Pointer (com.sun.jna.Pointer)1 COMException (com.sun.jna.platform.win32.COM.COMException)1 IConnectionPoint (com.sun.jna.platform.win32.COM.util.IConnectionPoint)1 ObjectFactory (com.sun.jna.platform.win32.COM.util.ObjectFactory)1 ComObject (com.sun.jna.platform.win32.COM.util.annotation.ComObject)1 SAFEARRAY (com.sun.jna.platform.win32.OaIdl.SAFEARRAY)1 VARIANT (com.sun.jna.platform.win32.Variant.VARIANT)1 VT_UINT (com.sun.jna.platform.win32.Variant.VT_UINT)1 LONGByReference (com.sun.jna.platform.win32.WinDef.LONGByReference)1 UINT (com.sun.jna.platform.win32.WinDef.UINT)1 ArrayList (java.util.ArrayList)1 Test (org.junit.Test)1