/// <summary> /// Execute the query sql, which contains zero or one string parameter whose value is /// supplied as param (or null). The result is a single rowset, which may contain zero or /// more rows, each containing cols columns, each an integer value. Read the entire rowset, /// returning a List of int[cols] arrays. /// </summary> /// <param name="cache"></param> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="cols"></param> /// <returns></returns> /// <remarks>The SQL command must NOT modify the database in any way!</remarks> static public List <int[]> ReadIntArray(FdoCache cache, string sql, string param, int cols) { List <int[]> resultList = new List <int[]>(); IOleDbCommand odc = null; try { cache.DatabaseAccessor.CreateCommand(out odc); if (param != null) { odc.SetStringParameter(1, // 1-based parameter index (uint)DBPARAMFLAGSENUM.DBPARAMFLAGS_ISINPUT, null, //flags param, (uint)param.Length); // despite doc, impl makes clear this is char count } odc.ExecCommand(sql, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); bool fMoreRows; odc.NextRow(out fMoreRows); using (ArrayPtr rgHvo = MarshalEx.ArrayToNative(1, typeof(uint))) { while (fMoreRows) { int[] result = new int[cols]; for (int i = 0; i < cols; ++i) { bool fIsNull; uint cbSpaceTaken; odc.GetColValue((uint)(i + 1), rgHvo, rgHvo.Size, out cbSpaceTaken, out fIsNull, 0); if (!fIsNull) { result[i] = IntFromStartOfUintArrayPtr(rgHvo); } } resultList.Add(result); odc.NextRow(out fMoreRows); } } } finally { ShutdownODC(ref odc); } return(resultList); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Internals the read ints from command. /// </summary> /// <param name="cache">The cache.</param> /// <param name="sql">The SQL.</param> /// <param name="param">The param.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ protected virtual List <int> InternalReadIntsFromCommand(FdoCache cache, string sql, string param) { List <int> list = new List <int>(); IOleDbCommand odc = null; try { cache.DatabaseAccessor.CreateCommand(out odc); if (param != null) { odc.SetStringParameter(1, // 1-based parameter index (uint)DBPARAMFLAGSENUM.DBPARAMFLAGS_ISINPUT, null, //flags param, (uint)param.Length); // despite doc, impl makes clear this is char count } odc.ExecCommand(sql, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); bool fMoreRows; odc.NextRow(out fMoreRows); bool fIsNull; uint cbSpaceTaken; using (ArrayPtr rgHvo = MarshalEx.ArrayToNative(1, typeof(uint))) { while (fMoreRows) { odc.GetColValue(1, rgHvo, rgHvo.Size, out cbSpaceTaken, out fIsNull, 0); if (!fIsNull) { list.Add(IntFromStartOfUintArrayPtr(rgHvo)); } odc.NextRow(out fMoreRows); } } } finally { ShutdownODC(ref odc); } return(list); }
/// <summary> /// Execute the query sql, which contains one required integer parameter whose value is /// supplied as param. The result is a single rowset, which may contain zero or /// more rows. Read an integer from each row and return them as a List. /// </summary> /// <param name="cache"></param> /// <param name="sql"></param> /// <param name="param">Required integer parameter.</param> /// <returns>A List containing zero, or more, integers.</returns> /// <remarks>The SQL command must NOT modify the database in any way!</remarks> static public List <int> ReadIntsFromCommand(FdoCache cache, string sql, int param) { List <int> list = new List <int>(); IOleDbCommand odc = null; try { cache.DatabaseAccessor.CreateCommand(out odc); uint uintSize = (uint)Marshal.SizeOf(typeof(uint)); odc.SetParameter(1, // 1-based parameter index (uint)DBPARAMFLAGSENUM.DBPARAMFLAGS_ISINPUT, null, //flags (ushort)DBTYPEENUM.DBTYPE_I4, new uint[] { (uint)param }, uintSize); odc.ExecCommand(sql, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); bool fMoreRows; odc.NextRow(out fMoreRows); bool fIsNull; uint cbSpaceTaken; using (ArrayPtr rgHvo = MarshalEx.ArrayToNative(1, typeof(uint))) { while (fMoreRows) { odc.GetColValue(1, rgHvo, uintSize, out cbSpaceTaken, out fIsNull, 0); if (!fIsNull) { list.Add(IntFromStartOfUintArrayPtr(rgHvo)); } odc.NextRow(out fMoreRows); } } } finally { ShutdownODC(ref odc); } return(list); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Return an array of strings given an SQL query. /// <param name="cache">The cache in use</param> /// <param name="qry">An SQL query to execute</param> /// </summary> /// ------------------------------------------------------------------------------------ public static string[] ReadMultiUnicodeTxtStrings(FdoCache cache, string qry) { StringCollection col = new StringCollection(); IOleDbCommand odc = null; cache.DatabaseAccessor.CreateCommand(out odc); try { uint cbSpaceTaken; bool fMoreRows; bool fIsNull; uint uintSize = (uint)Marshal.SizeOf(typeof(uint)); odc.ExecCommand(qry, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); odc.NextRow(out fMoreRows); while (fMoreRows) { using (ArrayPtr prgchName = MarshalEx.ArrayToNative(4000, typeof(char))) { odc.GetColValue(1, prgchName, prgchName.Size, out cbSpaceTaken, out fIsNull, 0); byte[] rgbTemp = (byte[])MarshalEx.NativeToArray(prgchName, (int)cbSpaceTaken, typeof(byte)); col.Add(Encoding.Unicode.GetString(rgbTemp)); } odc.NextRow(out fMoreRows); } } finally { DbOps.ShutdownODC(ref odc); } string[] strings = new string[col.Count]; for (int i = 0; i < col.Count; ++i) { strings[i] = col[i]; } return(strings); }
/// <summary> /// Execute the query sql, which optionally contains one string parameter whose value is /// supplied as param. The result is a single rowset, which may contain zero or /// more rows, each containing a pair of integers. The row set represents multiple /// sequences. A sequence is defined by consecutive rows with the same value for the first /// item. Each sequence is entered into the values dictionary, with the column 1 value /// as the key, and a list of the column 2 values as the value. /// Rows where either value is null or key is zero will be ignored. /// </summary> /// <param name="cache"></param> /// <param name="sql"></param> /// <param name="param">May be null, if not required.</param> /// <param name="values"></param> /// <returns></returns> /// <remarks>The SQL command must NOT modify the database in any way!</remarks> static public void LoadDictionaryFromCommand(FdoCache cache, string sql, string param, Dictionary <int, List <int> > values) { // As of 11/30/2006, all callers of this method are looking for reference sequence data, // so this List of ints cannot be a set. List <int> list = null; IOleDbCommand odc = null; try { cache.DatabaseAccessor.CreateCommand(out odc); if (param != null) { odc.SetStringParameter(1, // 1-based parameter index (uint)DBPARAMFLAGSENUM.DBPARAMFLAGS_ISINPUT, null, //flags param, (uint)param.Length); // despite doc, impl makes clear this is char count } odc.ExecCommand(sql, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); bool fMoreRows; odc.NextRow(out fMoreRows); bool fIsNull; uint cbSpaceTaken; int currentKey = 0; using (ArrayPtr rgHvo = MarshalEx.ArrayToNative(1, typeof(uint))) { for (; fMoreRows; odc.NextRow(out fMoreRows)) { int key, val; odc.GetColValue(1, rgHvo, rgHvo.Size, out cbSpaceTaken, out fIsNull, 0); if (fIsNull) { continue; } key = IntFromStartOfUintArrayPtr(rgHvo); if (key == 0) { continue; } odc.GetColValue(2, rgHvo, rgHvo.Size, out cbSpaceTaken, out fIsNull, 0); if (fIsNull) { continue; } val = IntFromStartOfUintArrayPtr(rgHvo); if (key != currentKey) { list = new List <int>(); currentKey = key; values[currentKey] = list; } list.Add(val); } } } finally { ShutdownODC(ref odc); } }
/// <summary> /// Update modified row or add a new one, but only if it is a custom field. /// </summary> public void UpdateDatabase() { // We do nothing for builtin fields or rows that have not been modified. if (m_isDirty && IsCustomField) { String sqlCommand; IOleDbCommand odc = null; m_cache.DatabaseAccessor.CreateCommand(out odc); try { // TODO: Maybe check for required columns for custom fields. if (IsInstalled) { // Update (or delete) existing row. if (m_doDelete) { sqlCommand = string.Format("DELETE FROM Field$ WITH (SERIALIZABLE) WHERE Id={0}", m_id); // TODO KenZ(RandyR): What should happen to the data, if any exists? } else { // Only update changeable fields. // Id, Type, Class, Name, Custom, and CustomId are not changeable by // the user, once they have been placed in the DB, so we won't // update them here no matter what. uint index = 1; // Current parameter index sqlCommand = string.Format("UPDATE Field$ WITH (SERIALIZABLE)" + " SET Min={0}, Max={1}, Big={2}, UserLabel={3}," + " HelpString={4}, ListRootId={5}, WsSelector={6}, XmlUI={7}" + " WHERE Id={8}", AsSql(m_min), AsSql(m_max), AsSql(m_big), AsSql(m_userlabel, odc, ref index), AsSql(m_helpString, odc, ref index), AsSql(m_listRootId), AsWSSql(m_wsSelector), AsSql(m_xmlUI, odc, ref index), m_id); } odc.ExecCommand(sqlCommand, (int)SqlStmtType.knSqlStmtNoResults); } else { // ================ Added Start =========================== // First use a stored procedure to determine what the Name field should // be, passing in the UserLabel for possible/future use. string sqlQuery = "declare @res nvarchar(400)" + " exec GenerateCustomName @res OUTPUT" + " select @res"; uint cbSpaceTaken; bool fMoreRows; bool fIsNull; using (ArrayPtr rgchUsername = MarshalEx.ArrayToNative(100, typeof(char))) { odc.ExecCommand(sqlQuery, (int)SqlStmtType.knSqlStmtStoredProcedure); odc.GetRowset(0); odc.NextRow(out fMoreRows); // odc.GetColValue calls are all 1-based... (post error comment) odc.GetColValue(1, rgchUsername, rgchUsername.Size, out cbSpaceTaken, out fIsNull, 0); byte[] rgbTemp = (byte[])MarshalEx.NativeToArray(rgchUsername, (int)cbSpaceTaken, typeof(byte)); m_name = Encoding.Unicode.GetString(rgbTemp); } // ================ Added End =========================== // Note: There is no need to worry about deletion, as this one isn't in // the DB. Make new row in DB. // Use SP to create the new one: . uint uintSize = (uint)Marshal.SizeOf(typeof(uint)); uint index = 1; odc.SetParameter(index++, (uint)DBPARAMFLAGSENUM.DBPARAMFLAGS_ISOUTPUT, null, (ushort)DBTYPEENUM.DBTYPE_I4, new uint[1] { 0 }, uintSize); sqlCommand = string.Format("exec AddCustomField$ ? output, {0}, {1}, {2}, " + "{3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}", AsSql(m_name, odc, ref index), m_type, m_class, AsSql(m_dstCls), AsSql(m_min), AsSql(m_max), AsSql(m_big), AsSql(m_userlabel, odc, ref index), AsSql(m_helpString, odc, ref index), AsSql(m_listRootId), AsWSSql(m_wsSelector), AsSql(m_xmlUI, odc, ref index)); using (ArrayPtr rgHvo = MarshalEx.ArrayToNative(1, typeof(uint))) { odc.ExecCommand(sqlCommand, (int)SqlStmtType.knSqlStmtStoredProcedure); odc.GetParameter(1, rgHvo, uintSize, out fIsNull); m_id = (int)(((uint[])MarshalEx.NativeToArray(rgHvo, 1, typeof(uint)))[0]); } } } finally { DbOps.ShutdownODC(ref odc); } // Before continuing, we have to close any open transactions (essentially the // File/Save operation). Otherwise, lots of things can break or timeout... if (m_cache.DatabaseAccessor.IsTransactionOpen()) { m_cache.DatabaseAccessor.CommitTrans(); } if (m_cache.ActionHandlerAccessor != null) { m_cache.ActionHandlerAccessor.Commit(); } } }
public void LoadBasicData() { CheckDisposed(); int hvoPhm_17_21 = 0; IOleDbCommand odc = null; try { m_fdoCache.DatabaseAccessor.CreateCommand(out odc); string sSql = @"select id from StTxtPara_ " + @"where Owner$ = (select dst from scrsection_content c " + @"join scrSection s on c.src = s.id " + @"where s.VerseRefStart = 57001001) " + @"and substring(contents, 1, 2) = '17'"; odc.ExecCommand(sSql, (int)SqlStmtType.knSqlStmtSelectWithOneRowset); odc.GetRowset(0); bool fMoreRows; odc.NextRow(out fMoreRows); if (fMoreRows) { odc.GetInt(1, out hvoPhm_17_21); } } finally { DbOps.ShutdownODC(ref odc); } // SqlConnection sqlConMaster = new SqlConnection( // string.Format("Server={0}; Database={1};" + // "User ID = sa; Password=inscrutable; Pooling=false;", // m_fdoCache.ServerName, m_fdoCache.DatabaseName)); // sqlConMaster.Open(); // SqlCommand sqlComm = sqlConMaster.CreateCommand(); // // Select the hvo of the paragraph containing Philemon 17-21. // string sSql = @"select id from StTxtPara_ " + // @"where Owner$ = (select dst from scrsection_content c " + // @"join scrSection s on c.src = s.id " + // @"where s.VerseRefStart = 57001001) " + // @"and substring(contents, 1, 2) = '17'"; // sqlComm.CommandText = sSql; // SqlDataReader sqlreader = // sqlComm.ExecuteReader(System.Data.CommandBehavior.SingleResult); // if (sqlreader.Read()) // hvoPhm_17_21 = sqlreader.GetInt32(0); // // sqlreader.Close(); // sqlreader = null; // sqlComm.Dispose(); // sqlComm = null; // sqlConMaster.Close(); // sqlConMaster.Dispose(); // sqlConMaster = null; Assert.IsTrue(hvoPhm_17_21 > 0); NewStPara.s_fPopCalledInNewStPara = false; m_fdoCache.VwCacheDaAccessor.ClearInfoAbout(hvoPhm_17_21, VwClearInfoAction.kciaRemoveObjectInfoOnly); NewStPara para = new NewStPara(m_fdoCache, hvoPhm_17_21); Assert.IsTrue(NewStPara.s_fPopCalledInNewStPara, "PopulateCsBasic wasn't called in NewStPara"); Assert.IsNotNull(para.Contents, "Contents of NewStPara is null"); DerivedStTxtPara2.s_fPopCalledInNewStPara = false; DerivedStTxtPara2.s_fPopCalledInDerived = false; m_fdoCache.VwCacheDaAccessor.ClearInfoAbout(hvoPhm_17_21, VwClearInfoAction.kciaRemoveObjectInfoOnly); DerivedStTxtPara2 para2 = new DerivedStTxtPara2(m_fdoCache, hvoPhm_17_21); Assert.IsFalse(DerivedStTxtPara2.s_fPopCalledInNewStPara, "PopulateCsBasic was called in NewStPara instead of DerivedStTxtPara2"); Assert.IsTrue(DerivedStTxtPara2.s_fPopCalledInDerived, "PoplulateCsBasic wasn't called in DerviedStTxtPara2"); Assert.IsNotNull(para.Contents, "Contents of DerivedStTxtPara2 is null"); DerivedStTxtPara.s_fPopCalledInNewStPara = false; m_fdoCache.VwCacheDaAccessor.ClearInfoAbout(hvoPhm_17_21, VwClearInfoAction.kciaRemoveObjectInfoOnly); DerivedStTxtPara para3 = new DerivedStTxtPara(m_fdoCache, hvoPhm_17_21); Assert.IsTrue(DerivedStTxtPara.s_fPopCalledInNewStPara, "PoplulateCsBasic wasn't called in DerviedStTxtPara"); Assert.IsNotNull(para.Contents, "Contents of DerivedStTxtPara is null"); }