Ejemplo n.º 1
0
        /// <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();
                }
            }
        }