Merge "Remove support for auto-paging of cursors." into oc-dev
am: 7f0d8c8076
Change-Id: Ice100c419ce6d53721d6bbec1147bb1cc1bb7b4d
diff --git a/api/test-current.txt b/api/test-current.txt
index 192ce75..3acc9ff 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -11775,15 +11775,6 @@
field protected final java.util.ArrayList<T> mObservers;
}
- public final class PageViewCursor extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
- ctor public PageViewCursor(android.database.Cursor, android.os.Bundle);
- method public void fillWindow(int, android.database.CursorWindow);
- method public android.database.CursorWindow getWindow();
- method public boolean onMove(int, int);
- method public static android.database.Cursor wrap(android.database.Cursor, android.os.Bundle);
- field public static final java.lang.String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
- }
-
public class SQLException extends java.lang.RuntimeException {
ctor public SQLException();
ctor public SQLException(java.lang.String);
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 2f87633..d428a3a 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -24,7 +24,6 @@
import android.database.CursorToBulkCursorAdaptor;
import android.database.DatabaseUtils;
import android.database.IContentObserver;
-import android.database.PageViewCursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -104,7 +103,6 @@
if (cursor != null) {
CursorToBulkCursorAdaptor adaptor = null;
- cursor = PageViewCursor.wrap(cursor, queryArgs);
try {
adaptor = new CursorToBulkCursorAdaptor(cursor, observer,
getProviderName());
diff --git a/core/java/android/database/PageViewCursor.java b/core/java/android/database/PageViewCursor.java
deleted file mode 100644
index 4569a27..0000000
--- a/core/java/android/database/PageViewCursor.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.database;
-
-import static com.android.internal.util.ArrayUtils.contains;
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.content.ContentResolver;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.Log;
-import android.util.MathUtils;
-
-import java.util.Arrays;
-
-/**
- * Cursor wrapper that provides visibility into a subset of a wrapped cursor.
- *
- * The window is specified by offset and limit.
- *
- * @hide
- */
-@TestApi
-public final class PageViewCursor extends CursorWrapper implements CrossProcessCursor {
-
- /** An extra added to results that are auto-paged using the wrapper. */
- public static final String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
-
- private static final String[] EMPTY_ARGS = new String[0];
- private static final String TAG = "PageViewCursor";
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
- private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
-
- private final int mOffset; // aka first index
- private final int mCount;
- private final Bundle mExtras;
-
- private @Nullable CursorWindow mWindow;
- private int mPos = -1;
- private int mWindowFillCount = 0;
-
- /**
- * @see PageViewCursor#wrap(Cursor, Bundle)
- */
- public PageViewCursor(Cursor cursor, Bundle queryArgs) {
- super(cursor);
-
- int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
- int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE);
-
- checkArgument(offset > -1);
- checkArgument(limit > -1);
-
- int count = mCursor.getCount();
-
- mOffset = offset;
-
- mExtras = new Bundle();
- Bundle extras = cursor.getExtras();
- if (extras != null) {
- mExtras.putAll(extras);
- }
-
- // When we're wrapping another cursor, it should not already be "paged".
- checkArgument(!hasPagedResponseDetails(mExtras));
-
- mExtras.putBoolean(EXTRA_AUTO_PAGED, true);
- mExtras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, count);
-
- // Ensure we retain any extra args supplied in cursor extras, and add
- // offset and/or limit.
- String[] existingArgs = mExtras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- existingArgs = existingArgs != null ? existingArgs : EMPTY_ARGS;
-
- int size = existingArgs.length;
-
- // copy the array with space for the extra query args we'll be adding.
- String[] newArgs = Arrays.copyOf(existingArgs, size + 2);
-
- if (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)) {
- newArgs[size++] = ContentResolver.QUERY_ARG_OFFSET;
- }
- if (queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)) {
- newArgs[size++] = ContentResolver.QUERY_ARG_LIMIT;
- }
-
- assert(size > existingArgs.length); // must add at least one arg.
-
- // At this point there may be a null element at the end of
- // the array because our pre-sizing didn't match the actualy
- // number of args we added. So we trim.
- if (size == newArgs.length - 1) {
- newArgs = Arrays.copyOf(newArgs, size);
- }
- mExtras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, newArgs);
-
- mCount = MathUtils.constrain(count - offset, 0, limit);
-
- if (DEBUG) Log.d(TAG, "Wrapped cursor"
- + " offset: " + mOffset
- + ", limit: " + limit
- + ", delegate_size: " + count
- + ", paged_count: " + mCount);
- }
-
- @Override
- public Bundle getExtras() {
- return mExtras;
- }
-
- @Override
- public int getPosition() {
- return mPos;
- }
-
- @Override
- public boolean isBeforeFirst() {
- if (mCount == 0) {
- return true;
- }
- return mPos == -1;
- }
-
- @Override
- public boolean isAfterLast() {
- if (mCount == 0) {
- return true;
- }
- return mPos == mCount;
- }
-
- @Override
- public boolean isFirst() {
- return mPos == 0;
- }
-
- @Override
- public boolean isLast() {
- return mPos == mCount - 1;
- }
-
- @Override
- public boolean moveToFirst() {
- return moveToPosition(0);
- }
-
- @Override
- public boolean moveToLast() {
- return moveToPosition(mCount - 1);
- }
-
- @Override
- public boolean moveToNext() {
- return move(1);
- }
-
- @Override
- public boolean moveToPrevious() {
- return move(-1);
- }
-
- @Override
- public boolean move(int offset) {
- return moveToPosition(mPos + offset);
- }
-
- @Override
- public boolean moveToPosition(int position) {
- if (position >= mCount) {
- if (VERBOSE) Log.v(TAG, "Invalid Positon: " + position + " >= count: " + mCount
- + ". Moving to last record.");
- mPos = mCount;
- super.moveToPosition(mOffset + mPos); // move into "after last" state.
- return false;
- }
-
- // Make sure position isn't before the beginning of the cursor
- if (position < 0) {
- if (VERBOSE) Log.v(TAG, "Ignoring invalid move to position: " + position);
- mPos = -1;
- super.moveToPosition(mPos);
- return false;
- }
-
- if (position == mPos) {
- if (VERBOSE) Log.v(TAG, "Ignoring no-op move to position: " + position);
- return true;
- }
-
- int delegatePosition = position + mOffset;
- if (VERBOSE) Log.v(TAG, "Moving delegate cursor to position: " + delegatePosition);
- if (super.moveToPosition(delegatePosition)) {
- mPos = position;
- return true;
- } else {
- mPos = -1;
- super.moveToPosition(-1);
- return false;
- }
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition) {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public int getCount() {
- return mCount;
- }
-
- @Override
- public boolean getWantsAllOnMoveCalls() {
- return false; // we want bulk cursor adapter to lift data into a CursorWindow.
- }
-
- @Override
- public CursorWindow getWindow() {
- assert(mPos == -1 || mPos == 0);
- if (mWindow == null) {
- mWindow = new CursorWindow("PageViewCursorWindow");
- fillWindow(0, mWindow);
- }
-
- return mWindow;
- }
-
- @Override
- public void fillWindow(int position, CursorWindow window) {
- assert(window == mWindow);
-
- if (mWindowFillCount++ > 0) {
- Log.w(TAG, "Re-filling window on paged cursor! Reduce ContentResolver.QUERY_ARG_LIMIT");
- }
-
- DatabaseUtils.cursorFillWindow(this, position, window);
- }
-
- /**
- * Wraps the cursor such that it will honor paging args (if present), AND if the cursor does
- * not report paging size.
- * <p>
- * No-op if cursor already contains paging or is less than specified page size.
- */
- public static Cursor wrap(Cursor cursor, @Nullable Bundle queryArgs) {
-
- boolean hasPagingArgs = queryArgs != null
- && (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)
- || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT));
-
- if (!hasPagingArgs) {
- if (VERBOSE) Log.v(TAG, "No-wrap: No paging args in request.");
- return cursor;
- }
-
- if (hasPagedResponseDetails(cursor.getExtras())) {
- if (VERBOSE) Log.v(TAG, "No-wrap. Cursor has paging details.");
- return cursor;
- }
-
- // Cursors that want all calls aren't compatible with our way
- // of doing business. TODO: Cover this case in CTS.
- if (cursor.getWantsAllOnMoveCalls()) {
- Log.w(TAG, "Unable to wrap cursor that wants to hear about move calls.");
- return cursor;
- }
-
- return new PageViewCursor(cursor, queryArgs);
- }
-
- /**
- * @return true if the extras contains information indicating the associated cursor is
- * paged.
- */
- private static boolean hasPagedResponseDetails(@Nullable Bundle extras) {
- if (extras == null) {
- return false;
- }
-
- if (extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) {
- return true;
- }
-
- String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- if (honoredArgs != null
- && (contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)
- || contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) {
- return true;
- }
-
- return false;
- }
-}
diff --git a/core/tests/coretests/src/android/database/PageViewCursorTest.java b/core/tests/coretests/src/android/database/PageViewCursorTest.java
deleted file mode 100644
index fba6aaf..0000000
--- a/core/tests/coretests/src/android/database/PageViewCursorTest.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database;
-
-import static com.android.internal.util.ArrayUtils.contains;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
-import android.util.MathUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.Random;
-
-@RunWith(AndroidJUnit4.class)
-public class PageViewCursorTest {
-
- private static final int ITEM_COUNT = 20;
-
- private static final String NAME_COLUMN = "name";
- private static final String NUM_COLUMN = "num";
-
- private static final String[] COLUMNS = new String[] {
- NAME_COLUMN,
- NUM_COLUMN
- };
-
- private static final String[] NAMES = new String[] {
- "000",
- "111",
- "222",
- "333",
- "444",
- "555",
- "666",
- "777",
- "888",
- "999",
- "aaa",
- "bbb",
- "ccc",
- "ddd",
- "eee",
- "fff",
- "ggg",
- "hhh",
- "iii",
- "jjj"
- };
-
- private MatrixCursor mDelegate;
- private PageViewCursor mCursor;
-
- @Before
- public void setUp() {
- Random rand = new Random();
-
- mDelegate = new MatrixCursor(COLUMNS);
- for (int i = 0; i < ITEM_COUNT; i++) {
- MatrixCursor.RowBuilder row = mDelegate.newRow();
- row.add(NAME_COLUMN, NAMES[i]);
- row.add(NUM_COLUMN, rand.nextInt());
- }
-
- mCursor = new PageViewCursor(mDelegate, createArgs(10, 5));
- }
-
- @Test
- public void testPage_Size() {
- assertEquals(5, mCursor.getCount());
- }
-
- @Test
- public void testPage_TotalSize() {
- assertEquals(ITEM_COUNT, mCursor.getExtras().getInt(ContentResolver.EXTRA_TOTAL_SIZE));
- }
-
- @Test
- public void testPage_OffsetExceedsCursorCount_EffectivelyEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(ITEM_COUNT * 2, 5));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testMoveToPosition() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(4));
- assertEquals(NAMES[14], mCursor.getString(0));
-
- // and then back down again for good measure.
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPosition_MoveToSamePosition_NoOp() {
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPosition_PositionOutOfBounds_MovesToBeforeFirst() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
-
- // move before
- assertFalse(mCursor.moveToPosition(-12));
- assertTrue(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testMoveToPosition_PositionOutOfBounds_MovesToAfterLast() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
-
- assertFalse(mCursor.moveToPosition(222));
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testPosition() {
- assertEquals(-1, mCursor.getPosition());
- }
-
- @Test
- public void testIsBeforeFirst() {
- assertTrue(mCursor.isBeforeFirst());
- mCursor.moveToFirst();
- assertFalse(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testCount_ZeroForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testIsBeforeFirst_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertTrue(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testIsAfterLast() {
- assertFalse(mCursor.isAfterLast());
- mCursor.moveToLast();
- mCursor.moveToNext();
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testIsAfterLast_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testIsFirst() {
- assertFalse(mCursor.isFirst());
- mCursor.moveToFirst();
- assertTrue(mCursor.isFirst());
- }
-
- @Test
- public void testIsLast() {
- assertFalse(mCursor.isLast());
- mCursor.moveToLast();
- assertTrue(mCursor.isLast());
- }
-
- @Test
- public void testMove() {
- // note that initial position is -1, so moving
- // 2 will only put as at 1.
- mCursor.move(2);
- assertEquals(NAMES[11], mCursor.getString(0));
- mCursor.move(-1);
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToFist() {
- mCursor.moveToPosition(3);
- mCursor.moveToFirst();
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToLast() {
- mCursor.moveToLast();
- assertEquals(NAMES[14], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToNext() {
- // default position is -1, so next is 0.
- mCursor.moveToNext();
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToNext_AfterLastReturnsFalse() {
- mCursor.moveToLast();
- assertFalse(mCursor.moveToNext());
- }
-
- @Test
- public void testMoveToPrevious() {
- mCursor.moveToPosition(3);
- mCursor.moveToPrevious();
- assertEquals(NAMES[12], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPrevious_BeforeFirstReturnsFalse() {
- assertFalse(mCursor.moveToPrevious());
- }
-
- @Test
- public void testWindow_ReadPastEnd() {
- assertFalse(mCursor.moveToPosition(10));
- }
-
- @Test
- public void testLimitOutOfBounds() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
- assertEquals(15, mCursor.getCount());
- }
-
- @Test
- public void testOffsetOutOfBounds_EmptyResult() {
- mCursor = new PageViewCursor(mDelegate, createArgs(100000, 100));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testAddsExtras() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
- assertTrue(mCursor.getExtras().getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testAddsExtras_OnlyOffset() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- mCursor = new PageViewCursor(mDelegate, args);
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testAddsExtras_OnlyLimit() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- mCursor = new PageViewCursor(mDelegate, args);
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testGetWindow() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 5));
- CursorWindow window = mCursor.getWindow();
- assertEquals(5, window.getNumRows());
- }
-
- @Test
- public void testWraps() {
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testWraps_NullExtras() {
- Bundle args = createArgs(5, 5);
- mDelegate.setExtras(null);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testWraps_WithJustOffset() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(15, wrapped.getCount());
- }
-
- @Test
- public void testWraps_WithJustLimit() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testNoWrap_WithoutPagingArgs() {
- Cursor wrapped = PageViewCursor.wrap(mDelegate, Bundle.EMPTY);
- assertTrue(mDelegate == wrapped);
- }
-
- @Test
- public void testNoWrap_CursorsHasExistingPaging_ByTotalSize() {
- Bundle extras = new Bundle();
- extras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, 5);
- mDelegate.setExtras(extras);
-
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(mDelegate == wrapped);
- }
-
- @Test
- public void testNoWrap_CursorsHasExistingPaging_ByHonoredArgs() {
- Bundle extras = new Bundle();
- extras.putStringArray(
- ContentResolver.EXTRA_HONORED_ARGS,
- new String[] {
- ContentResolver.QUERY_ARG_OFFSET,
- ContentResolver.QUERY_ARG_LIMIT
- });
- mDelegate.setExtras(extras);
-
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(mDelegate == wrapped);
- }
-
- private static Bundle createArgs(int offset, int limit) {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, offset);
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
- return args;
- }
-
- private void assertStringAt(int row, int column, String expected) {
- mCursor.moveToPosition(row);
- assertEquals(expected, mCursor.getString(column));
- }
-}