/// ------------------------------------------------------------------------------------ /// <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> /// 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(); } } }
/// <summary> /// Restore DbOps to using its own interfaces. /// </summary> static public void DisableDummyOps() { s_DbOps = new DbOps(); }