예제 #1
0
 private void WriteDirectValue(CommenceValue v)
 {
     _xw.WriteStartElement(XmlConvert.EncodeLocalName(base.ExportHeaders[v.ColumnDefinition.ColumnIndex]));
     // only write if we have something
     if (!string.IsNullOrEmpty(v.DirectFieldValue))
     {
         // can we get away with writing the value or do we need to use CData?
         if (v.ColumnDefinition.CommenceFieldDefinition.MaxChars == CommenceLimits.MaxTextFieldCapacity)
         {
             _xw.WriteCData(v.DirectFieldValue);
         }
         else
         {
             _xw.WriteString(v.DirectFieldValue);
         }
     }
     _xw.WriteEndElement();
 }
예제 #2
0
        /// <summary>
        /// Takes raw cursor data and returns a list of CommenceValue lists
        /// </summary>
        /// <param name="rawdata">Data</param>
        /// <returns>A list of CommenceValue lists</returns>
        private List <List <CommenceValue> > ProcessDataBatch(string[][] rawdata)
        {
            List <List <CommenceValue> > retval = new List <List <CommenceValue> >();
            CommenceValue    cv;
            ColumnDefinition cd;

            // rawdata represents the actual database row values
            for (int i = 0; i < rawdata.GetLength(0); i++) // rows
            {
                List <CommenceValue> rowdata = new List <CommenceValue>();
                // for thids we can assume the first row of rawdata contains the thid
                if (this.useThids)
                {
                    cv = new CommenceValue(rawdata[i][0], this.columnDefinitions.First()); // assumes thid column is first. This is an accident waiting to happen.
                    rowdata.Add(cv);
                }

                // process row
                for (int j = 1; j < rawdata[i].Length; j++) // columns
                {
                    // a column for the thid is only returned when a thid is requested
                    // therefore getting the right column is a little tricky
                    int colindex;
                    if (this.useThids)
                    {
                        colindex = j;
                    }
                    else
                    {
                        colindex = j - 1;
                    }
                    cd = this.columnDefinitions[colindex];

                    string[] buffer;
                    if (cd.IsConnection)
                    {
                        if (string.IsNullOrEmpty(rawdata[i][j].Trim())) // should we trim?
                        {
                            cv = new CommenceValue(cd);                 // always create a CommenceValue for consistency
                        }
                        else
                        {
                            if (!settings.SplitConnectedItems)
                            {
                                buffer = new string[] { rawdata[i][j] }; // just return as-is
                                cv     = new CommenceValue(buffer, cd);
                            }
                            else
                            {
                                if (cd.Delimiter == "\n")
                                {
                                    switch (cd.CommenceFieldDefinition.Type)
                                    {
                                    case CommenceFieldType.Text:
                                    case CommenceFieldType.URL:
                                        // any non-Name text field in Commence will accept a \n
                                        // we use a regex to split values at "\n" *but not* "\r\n"
                                        // this is not 100% fail-safe as a fieldvalue *can* contain just \n if it is a large text field.
                                        // in that case, your only option is to suppress the splitting in ExportSettings
                                        buffer = regex.Split(rawdata[i][j]);     // this may result in Commence fieldvalues being split incorrectly if they contain embedded delimiters.
                                        break;

                                    default:
                                        buffer = rawdata[i][j].Split(new string[] { cd.Delimiter }, StringSplitOptions.None);
                                        break;
                                    } // switch
                                }
                                else
                                {
                                    buffer = rawdata[i][j].Split(new string[] { cd.Delimiter }, StringSplitOptions.None);
                                }
                                // buffer now contains the connected values as array, do any formatting transformation
                                buffer = FormatValues(buffer, cd);
                                cv     = new CommenceValue(buffer, cd);
                            }
                        }
                    }    // if IsConnection
                    else //a direct value
                    {
                        buffer = new string[] { rawdata[i][j] };
                        buffer = FormatValues(buffer, cd);
                        cv     = new CommenceValue(buffer[0], cd);
                    }
                    rowdata.Add(cv);
                } // for j
                retval.Add(rowdata);
            }     // for i
            return(retval);
        }
예제 #3
0
        /// <summary>
        /// Reads data using DDE. This is extremely show and should only ever be used as a last resort.
        /// </summary>
        /// <param name="mocktables"></param>
        internal void GetDataByDDE(List <TableDef> mocktables) // needs fixing
        {
            /* DDE requests are limited to a maximum length of 255 characters,
             * which is easily exceeded. A workaround is splitting the requests.
             * Not pretty but the only way to get to many-many relationships that contain >93750 worth of connected characters
             * without setting the maxfieldsize higher.
             */

            List <List <CommenceValue> > rows;
            List <CommenceValue>         rowvalues;
            ICommenceDatabase            db = new CommenceDatabase();

            // always define a category
            db.ViewCategory(this.cursor.Category);
            // are we dealing with a view?
            if (!string.IsNullOrEmpty(cursor.View))
            {
                db.ViewView(this.cursor.View);
            }
            int itemCount = db.ViewItemCount();

            for (int i = 1; i <= itemCount; i++) // note that we use a 1-based iterator
            {
                rows      = new List <List <CommenceValue> >();
                rowvalues = new List <CommenceValue>();
                foreach (TableDef td in mocktables)
                {
                    string[]      DDEResult  = null;
                    List <string> fieldNames = td.ColumnDefinitions.Select(o => o.FieldName).ToList();
                    if (td.Primary)
                    {
                        // ViewFields and ViewConnectedFields have a limited capacity
                        // the total length of a DDE command cannot exceed 255 characters
                        // What we are going to do is limit the number of characters to a value of up to 150 chars,
                        // to be on the safe side (ViewConnectedFilter and two delimiters already make up 35 characters!)
                        ListChopper lcu = new ListChopper(fieldNames, 150);
                        foreach (List <string> l in lcu.Portions)
                        {
                            DDEResult = db.ViewFields(i, l);

                            // we have our results, we now have to create CommenceValue objects from it
                            // and we also have to match them up with their respective column
                            // this is a little tricky...
                            for (int j = 0; j < DDEResult.Length; j++)
                            {
                                ColumnDefinition cd     = td.ColumnDefinitions.Find(o => o.FieldName.Equals(l[j]));
                                string[]         buffer = new string[] { DDEResult[j] };
                                //buffer = FormatValues(buffer,this.Formatting, cd);
                                buffer = FormatValues(buffer, cd);
                                CommenceValue v = new CommenceValue(buffer[0], cd);
                                rowvalues.Add(v);
                            } // for
                        }     // list l
                    }
                    else      // we are dealing with a connection
                    {
                        int conItemCount = db.ViewConnectedCount(i, td.ColumnDefinitions[0].Connection, td.ColumnDefinitions[0].Category); // doesn't matter which one we use
                        // here's a nice challenge:
                        // upon every iteration we get a row of fieldvalues from the connection
                        // to make things worse, we chop them up so it aren't even complete rows.
                        // we must aggregate the values for each field.
                        // We'll construct a datatable to hack around that;
                        // we could have also used a dictionary I suppose.

                        //  using a datatable may be easiest
                        DataTable dt = new DataTable();
                        for (int c = 0; c < fieldNames.Count; c++)
                        {
                            dt.Columns.Add(fieldNames[c]); // add fields as columns, keeping everything default
                        }

                        // loop all connected items
                        for (int citemcount = 1; citemcount <= conItemCount; citemcount++)
                        {
                            DataRow     dr  = dt.NewRow(); // create a row containing all columns
                            ListChopper lcu = new ListChopper(fieldNames, 150);
                            foreach (List <string> list in lcu.Portions)
                            {
                                DDEResult = db.ViewConnectedFields(i, td.ColumnDefinitions[0].Connection, td.ColumnDefinitions[0].Category, citemcount, list);
                                // populate colums for the fields we requested
                                for (int j = 0; j < DDEResult.Length; j++)
                                {
                                    dr[list[j]] = DDEResult[j];
                                }
                            } // list l
                            dt.Rows.Add(dr);
                        }     // citemcount

                        // create a CommenceValue from every column in the datatable
                        foreach (DataColumn dc in dt.Columns)
                        {
                            // this will also return columns that have no data, which is what we want.
                            string[] query =
                                (from r in dt.AsEnumerable()
                                 select r.Field <String>(dc.ColumnName)).ToArray();
                            ColumnDefinition cd = td.ColumnDefinitions.Find(o => o.FieldName.Equals(dc.ColumnName));
                            CommenceValue    cv = null;
                            if (query.Length > 0) // only create value if there is one
                            {
                                //query = FormatValues(query, this.Formatting, cd);
                                query = FormatValues(query, cd);
                                cv    = new CommenceValue(query, cd);
                            }
                            else
                            {
                                // create empty CommenceValue
                                cv = new CommenceValue(cd);
                            }
                            rowvalues.Add(cv);
                        }
                    } // if
                }     // foreach tabledef
                rows.Add(rowvalues);
                CursorDataReadProgressChangedArgs args = new CursorDataReadProgressChangedArgs(rows, i, totalRows); // progress within the cursor
                OnDataProgressChanged(args);
            } // i
            db = null;
            ExportCompleteArgs a = new ExportCompleteArgs(itemCount);

            OnDataReadCompleted(a);
        }