Kaydet (Commit) 1ae17f5b authored tarafından Ocke.Janssen's avatar Ocke.Janssen

dba34c: #i102625# only fetch rows when the view moves outside the scope of the rowset window

üst 10df05f6
...@@ -691,6 +691,20 @@ sal_Bool SAL_CALL OCacheSet::previous( ) throw(SQLException, RuntimeException) ...@@ -691,6 +691,20 @@ sal_Bool SAL_CALL OCacheSet::previous( ) throw(SQLException, RuntimeException)
m_bInserted = m_bUpdated = m_bDeleted = sal_False; m_bInserted = m_bUpdated = m_bDeleted = sal_False;
return m_xDriverSet->previous(); return m_xDriverSet->previous();
} }
sal_Bool OCacheSet::last_checked( sal_Bool /*i_bFetchRow*/)
{
return last();
}
// -------------------------------------------------------------------------
sal_Bool OCacheSet::previous_checked( sal_Bool /*i_bFetchRow*/ )
{
return previous();
}
// -------------------------------------------------------------------------
sal_Bool OCacheSet::absolute_checked( sal_Int32 row,sal_Bool /*i_bFetchRow*/ )
{
return absolute(row);
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void SAL_CALL OCacheSet::refreshRow( ) throw(SQLException, RuntimeException) void SAL_CALL OCacheSet::refreshRow( ) throw(SQLException, RuntimeException)
{ {
......
...@@ -174,6 +174,9 @@ namespace dbaccess ...@@ -174,6 +174,9 @@ namespace dbaccess
virtual bool columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow); virtual bool columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow);
virtual bool updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns); virtual bool updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns);
virtual void fillMissingValues(ORowSetValueVector::Vector& io_aRow) const; virtual void fillMissingValues(ORowSetValueVector::Vector& io_aRow) const;
virtual sal_Bool previous_checked( sal_Bool i_bFetchRow );
virtual sal_Bool absolute_checked( sal_Int32 row,sal_Bool i_bFetchRow );
virtual sal_Bool last_checked( sal_Bool i_bFetchRow);
}; };
} }
#endif //DBACCESS_CORE_API_CACHESET_HXX #endif //DBACCESS_CORE_API_CACHESET_HXX
......
...@@ -1167,6 +1167,12 @@ sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException) ...@@ -1167,6 +1167,12 @@ sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException)
++m_aKeyIter; // this is possible because we stand on begin() and this is the "beforefirst" row ++m_aKeyIter; // this is possible because we stand on begin() and this is the "beforefirst" row
if(m_aKeyIter == m_aKeyMap.end() && !fetchRow()) if(m_aKeyIter == m_aKeyMap.end() && !fetchRow())
m_aKeyIter = m_aKeyMap.end(); m_aKeyIter = m_aKeyMap.end();
else
{
//m_aKeyIter->second.second.second = new OPrivateRow(_rInsertRow->get());
m_xRow.set(m_xDriverRow,UNO_QUERY_THROW);
return !isAfterLast();
}
} }
else if(!isAfterLast()) else if(!isAfterLast())
++m_aKeyIter; ++m_aKeyIter;
...@@ -1240,13 +1246,19 @@ sal_Bool SAL_CALL OKeySet::first( ) throw(SQLException, RuntimeException) ...@@ -1240,13 +1246,19 @@ sal_Bool SAL_CALL OKeySet::first( ) throw(SQLException, RuntimeException)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
sal_Bool SAL_CALL OKeySet::last( ) throw(SQLException, RuntimeException) sal_Bool SAL_CALL OKeySet::last( ) throw(SQLException, RuntimeException)
{ {
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::last" ); return last_checked(sal_True);
}
sal_Bool OKeySet::last_checked( sal_Bool i_bFetchRow)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::last_checked" );
m_bInserted = m_bUpdated = m_bDeleted = sal_False; m_bInserted = m_bUpdated = m_bDeleted = sal_False;
fillAllRows(); fillAllRows();
m_aKeyIter = m_aKeyMap.end(); m_aKeyIter = m_aKeyMap.end();
--m_aKeyIter; --m_aKeyIter;
refreshRow(); if ( i_bFetchRow )
refreshRow();
return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(); return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -1260,6 +1272,10 @@ sal_Int32 SAL_CALL OKeySet::getRow( ) throw(SQLException, RuntimeException) ...@@ -1260,6 +1272,10 @@ sal_Int32 SAL_CALL OKeySet::getRow( ) throw(SQLException, RuntimeException)
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException) sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
{
return absolute_checked(row,sal_True);
}
sal_Bool OKeySet::absolute_checked( sal_Int32 row,sal_Bool i_bFetchRow )
{ {
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::absolute" ); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::absolute" );
m_bInserted = m_bUpdated = m_bDeleted = sal_False; m_bInserted = m_bUpdated = m_bDeleted = sal_False;
...@@ -1281,6 +1297,11 @@ sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, Runtime ...@@ -1281,6 +1297,11 @@ sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, Runtime
sal_Bool bNext = sal_True; sal_Bool bNext = sal_True;
for(sal_Int32 i=m_aKeyMap.size()-1;i < row && bNext;++i) for(sal_Int32 i=m_aKeyMap.size()-1;i < row && bNext;++i)
bNext = fetchRow(); bNext = fetchRow();
if ( bNext )
{
m_xRow.set(m_xDriverRow,UNO_QUERY_THROW);
return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
}
} }
else else
m_aKeyIter = m_aKeyMap.end(); m_aKeyIter = m_aKeyMap.end();
...@@ -1292,7 +1313,8 @@ sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, Runtime ...@@ -1292,7 +1313,8 @@ sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, Runtime
++m_aKeyIter; ++m_aKeyIter;
} }
} }
refreshRow(); if ( i_bFetchRow )
refreshRow();
return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(); return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
} }
...@@ -1308,17 +1330,24 @@ sal_Bool SAL_CALL OKeySet::relative( sal_Int32 rows ) throw(SQLException, Runtim ...@@ -1308,17 +1330,24 @@ sal_Bool SAL_CALL OKeySet::relative( sal_Int32 rows ) throw(SQLException, Runtim
return absolute(getRow()+rows); return absolute(getRow()+rows);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
sal_Bool SAL_CALL OKeySet::previous( ) throw(SQLException, RuntimeException) sal_Bool OKeySet::previous_checked( sal_Bool i_bFetchRow )
{ {
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::previous" ); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::previous" );
m_bInserted = m_bUpdated = m_bDeleted = sal_False; m_bInserted = m_bUpdated = m_bDeleted = sal_False;
if(m_aKeyIter != m_aKeyMap.begin()) if(m_aKeyIter != m_aKeyMap.begin())
{ {
--m_aKeyIter; --m_aKeyIter;
refreshRow(); if ( i_bFetchRow )
refreshRow();
} }
return m_aKeyIter != m_aKeyMap.begin(); return m_aKeyIter != m_aKeyMap.begin();
} }
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OKeySet::previous( ) throw(SQLException, RuntimeException)
{
return previous_checked(sal_True);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException) void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException)
{ {
......
...@@ -228,6 +228,11 @@ namespace dbaccess ...@@ -228,6 +228,11 @@ namespace dbaccess
virtual void SAL_CALL cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
virtual sal_Bool previous_checked( sal_Bool i_bFetchRow );
virtual sal_Bool absolute_checked( sal_Int32 row,sal_Bool i_bFetchRow );
virtual sal_Bool last_checked( sal_Bool i_bFetchRow);
}; };
} }
#endif // DBACCESS_CORE_API_KEYSET_HXX #endif // DBACCESS_CORE_API_KEYSET_HXX
......
...@@ -441,6 +441,13 @@ void ORowSetCache::setFetchSize(sal_Int32 _nSize) ...@@ -441,6 +441,13 @@ void ORowSetCache::setFetchSize(sal_Int32 _nSize)
m_nStartPos = 0; m_nStartPos = 0;
m_nEndPos = _nSize; m_nEndPos = _nSize;
} }
else if (m_nStartPos < m_nPosition && m_nPosition < m_nEndPos)
{
sal_Int32 nNewSt = -1;
fillMatrix(nNewSt,_nSize+1);
m_nStartPos = 0;
m_nEndPos = _nSize;
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -654,34 +661,26 @@ sal_Bool ORowSetCache::next( ) ...@@ -654,34 +661,26 @@ sal_Bool ORowSetCache::next( )
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::isBeforeFirst( ) sal_Bool ORowSetCache::isBeforeFirst( )
{ {
// return !m_nPosition;
return m_bBeforeFirst; return m_bBeforeFirst;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::isAfterLast( ) sal_Bool ORowSetCache::isAfterLast( )
{ {
return m_bAfterLast; return m_bAfterLast;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::isFirst( ) sal_Bool ORowSetCache::isFirst( )
{ {
return m_nPosition == 1; // ask resultset for return m_nPosition == 1; // ask resultset for
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::isLast( ) sal_Bool ORowSetCache::isLast( )
{ {
// return m_bRowCountFinal ? (m_nPosition==m_nRowCount) : m_pCacheSet->isLast();
return m_nPosition == m_nRowCount; return m_nPosition == m_nRowCount;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::beforeFirst( ) sal_Bool ORowSetCache::beforeFirst( )
{ {
if(!m_bBeforeFirst) if(!m_bBeforeFirst)
{ {
m_bAfterLast = sal_False; m_bAfterLast = sal_False;
...@@ -696,8 +695,6 @@ sal_Bool ORowSetCache::beforeFirst( ) ...@@ -696,8 +695,6 @@ sal_Bool ORowSetCache::beforeFirst( )
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
sal_Bool ORowSetCache::afterLast( ) sal_Bool ORowSetCache::afterLast( )
{ {
if(!m_bAfterLast) if(!m_bAfterLast)
{ {
m_bBeforeFirst = sal_False; m_bBeforeFirst = sal_False;
...@@ -705,7 +702,7 @@ sal_Bool ORowSetCache::afterLast( ) ...@@ -705,7 +702,7 @@ sal_Bool ORowSetCache::afterLast( )
if(!m_bRowCountFinal) if(!m_bRowCountFinal)
{ {
m_pCacheSet->last(); m_pCacheSet->last_checked(sal_False);
m_bRowCountFinal = sal_True; m_bRowCountFinal = sal_True;
m_nRowCount = m_pCacheSet->getRow();// + 1 removed m_nRowCount = m_pCacheSet->getRow();// + 1 removed
} }
...@@ -721,10 +718,22 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos ...@@ -721,10 +718,22 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos
{ {
OSL_ENSURE(_nNewStartPos != _nNewEndPos,"ORowSetCache::fillMatrix: StartPos and EndPos can not be equal!"); OSL_ENSURE(_nNewStartPos != _nNewEndPos,"ORowSetCache::fillMatrix: StartPos and EndPos can not be equal!");
// fill the whole window with new data // fill the whole window with new data
ORowSetMatrix::iterator aIter = m_pMatrix->begin(); ORowSetMatrix::iterator aIter;
sal_Bool bCheck = m_pCacheSet->absolute(_nNewStartPos); // -1 no need to sal_Int32 i;
sal_Bool bCheck;
if ( _nNewStartPos == -1 )
{
aIter = m_pMatrix->begin() + m_nEndPos;
i = m_nEndPos+1;
}
else
{
aIter = m_pMatrix->begin();
i = _nNewStartPos;
}
bCheck = m_pCacheSet->absolute(i); // -1 no need to
sal_Int32 i=_nNewStartPos;
for(;i<_nNewEndPos;++i,++aIter) for(;i<_nNewEndPos;++i,++aIter)
{ {
if(bCheck) if(bCheck)
...@@ -738,7 +747,7 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos ...@@ -738,7 +747,7 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos
if(!m_bRowCountFinal) if(!m_bRowCountFinal)
{ {
if(m_pCacheSet->previous()) // because we stand after the last row if(m_pCacheSet->previous_checked(sal_False)) // because we stand after the last row
m_nRowCount = m_pCacheSet->getRow(); // here we have the row count m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
if(!m_nRowCount) if(!m_nRowCount)
m_nRowCount = i-1; // it can be that getRow return zero m_nRowCount = i-1; // it can be that getRow return zero
...@@ -767,16 +776,18 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos ...@@ -767,16 +776,18 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos
} }
break; break;
} }
bCheck = m_pCacheSet->next(); if ( i < (_nNewEndPos-1) )
bCheck = m_pCacheSet->next();
} }
// m_nStartPos = _nNewStartPos; // m_nStartPos = _nNewStartPos;
// we have to read one row forward to enshure that we know when we are on last row // we have to read one row forward to ensure that we know when we are on last row
// but only when we don't know it already // but only when we don't know it already
/*
if(!m_bRowCountFinal) if(!m_bRowCountFinal)
{ {
if(!m_pCacheSet->next()) if(!m_pCacheSet->next())
{ {
if(m_pCacheSet->previous()) // because we stand after the last row if(m_pCacheSet->previous_checked(sal_False)) // because we stand after the last row
m_nRowCount = m_pCacheSet->getRow(); // here we have the row count m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
m_bRowCountFinal = sal_True; m_bRowCountFinal = sal_True;
} }
...@@ -784,6 +795,7 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos ...@@ -784,6 +795,7 @@ sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos
m_nRowCount = std::max(i,m_nRowCount); m_nRowCount = std::max(i,m_nRowCount);
} }
*/
return bCheck; return bCheck;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -921,19 +933,16 @@ sal_Bool ORowSetCache::moveWindow() ...@@ -921,19 +933,16 @@ sal_Bool ORowSetCache::moveWindow()
// but only when we don't know it already // but only when we don't know it already
if ( !m_bRowCountFinal ) if ( !m_bRowCountFinal )
{ {
bOk = m_pCacheSet->absolute( m_nPosition + 1 ); bOk = m_pCacheSet->absolute_checked( m_nPosition + 1,sal_False );
if ( bOk ) if ( bOk )
m_nRowCount = std::max(sal_Int32(m_nPosition+1),m_nRowCount); m_nRowCount = std::max(sal_Int32(m_nPosition+1),m_nRowCount);
} }
} }
if(!bOk) if(!bOk && !m_bRowCountFinal)
{ {
if(!m_bRowCountFinal) // because we stand after the last row
{ m_nRowCount = m_pCacheSet->previous_checked(sal_False) ? m_pCacheSet->getRow() : 0;// + 1 removed
// because we stand after the last row m_bRowCountFinal = sal_True;
m_nRowCount = m_pCacheSet->previous() ? m_pCacheSet->getRow() : 0;// + 1 removed
m_bRowCountFinal = sal_True;
}
} }
} }
} }
...@@ -967,7 +976,7 @@ sal_Bool ORowSetCache::moveWindow() ...@@ -967,7 +976,7 @@ sal_Bool ORowSetCache::moveWindow()
// now I can say how many rows we have // now I can say how many rows we have
if(!bOk) if(!bOk)
{ {
m_pCacheSet->previous(); // because we stand after the last row m_pCacheSet->previous_checked(sal_False); // because we stand after the last row
m_nRowCount = nPos; // here we have the row count m_nRowCount = nPos; // here we have the row count
m_bRowCountFinal = sal_True; m_bRowCountFinal = sal_True;
} }
...@@ -985,7 +994,7 @@ sal_Bool ORowSetCache::moveWindow() ...@@ -985,7 +994,7 @@ sal_Bool ORowSetCache::moveWindow()
if ( !m_bRowCountFinal ) if ( !m_bRowCountFinal )
{ {
m_pCacheSet->previous(); // because we stand after the last row m_pCacheSet->previous_checked(sal_False); // because we stand after the last row
m_nRowCount = std::max(m_nRowCount,--nPos); // here we have the row count m_nRowCount = std::max(m_nRowCount,--nPos); // here we have the row count
OSL_ENSURE(nPos == m_pCacheSet->getRow(),"nPos isn't valid!"); OSL_ENSURE(nPos == m_pCacheSet->getRow(),"nPos isn't valid!");
m_bRowCountFinal = sal_True; m_bRowCountFinal = sal_True;
...@@ -1001,7 +1010,7 @@ sal_Bool ORowSetCache::moveWindow() ...@@ -1001,7 +1010,7 @@ sal_Bool ORowSetCache::moveWindow()
aIter = m_pMatrix->begin(); aIter = m_pMatrix->begin();
nPos = m_nStartPos; nPos = m_nStartPos;
bCheck = m_pCacheSet->absolute(m_nStartPos); bCheck = m_pCacheSet->absolute_checked(m_nStartPos,sal_False);
for(; !aIter->isValid() && bCheck;++aIter) for(; !aIter->isValid() && bCheck;++aIter)
{ {
OSL_ENSURE(aIter != m_pMatrix->end(),"Invalid iterator"); OSL_ENSURE(aIter != m_pMatrix->end(),"Invalid iterator");
......
...@@ -56,8 +56,8 @@ ...@@ -56,8 +56,8 @@
#define STR_QUERY_NOTABLE RID_STR_QRY_START + 21 #define STR_QUERY_NOTABLE RID_STR_QRY_START + 21
#define STR_QRY_ORDERBY_UNRELATED RID_STR_QRY_START + 22 #define STR_QRY_ORDERBY_UNRELATED RID_STR_QRY_START + 22
#define STR_QUERY_HANDLETEXT RID_STR_QRY_START + 23 #define STR_QUERY_HANDLETEXT RID_STR_QRY_START + 23
#define STR_QUERY_FALSE RID_STR_QRY_START + 24 // free
#define STR_QUERY_TRUE RID_STR_QRY_START + 25 // free
#define STR_QRY_TOO_MANY_COLUMNS RID_STR_QRY_START + 26 #define STR_QRY_TOO_MANY_COLUMNS RID_STR_QRY_START + 26
#define STR_SVT_SQL_SYNTAX_ERROR RID_STR_QRY_START + 27 #define STR_SVT_SQL_SYNTAX_ERROR RID_STR_QRY_START + 27
#define STR_QUERYDESIGN_NO_VIEW_SUPPORT RID_STR_QRY_START + 28 #define STR_QUERYDESIGN_NO_VIEW_SUPPORT RID_STR_QRY_START + 28
......
...@@ -281,14 +281,6 @@ ErrorBox ERR_QRY_ORDERBY_ON_ASTERISK ...@@ -281,14 +281,6 @@ ErrorBox ERR_QRY_ORDERBY_ON_ASTERISK
{ {
Message [ en-US ] = "[*] cannot be used as a sort criterion."; Message [ en-US ] = "[*] cannot be used as a sort criterion.";
}; };
String STR_QUERY_TRUE
{
Text [ en-US ] = "TRUE" ;
};
String STR_QUERY_FALSE
{
Text [ en-US ] = "FALSE" ;
};
String STR_QRY_TOO_MANY_TABLES String STR_QRY_TOO_MANY_TABLES
{ {
Text [ en-US ] = "There are too many tables."; Text [ en-US ] = "There are too many tables.";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment