f



[OT] My Second C#

Here is what I've come up with - there are seven or eight classes now, 
two of which are "support classes" (not sure if that's the term - 
they're not helper classes because they're in their own class 
definition).  They are below, with a description of their purpose.  For 
those of you who have the time and inclination, feel free to comment.

-8<-- Class CSCS.DB.DBUtil -->8-

This class has database utility routines.  They're somewhat generic at 
this point...

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;

namespace CSCS.DB
{
     public class DBUtil
     {
         /// <summary>
         /// Returns true if the given SQL statement returns any rows
         /// </summary>
         /// <param name="sql"></param>
         /// <returns>bool</returns>
         public static bool RowExists(String sql)
         {
             bool           itExists = false;
             SqlConnection  cn       = NewConnection();
             DataSet        ds       = new DataSet();
             SqlDataAdapter da       = new SqlDataAdapter(sql, cn);
             da.Fill(ds);

             if (ds.Tables.Count > 0)
             {
                 itExists = true;
             }
             da.Dispose();
             cn.Close();
             cn.Dispose();

             return itExists;
         }

         /// <summary>
         /// Returns true if an element is a CSCI within CSCS
         /// </summary>
         /// <param name="ElementID"></param>
         /// <returns>bool</returns>
         public static bool ElementExists(String ElementID)
         {
             return RowExists("SELECT Actv_Ind "
                 + "FROM Active_Elements "
                 + "WHERE Element_ID = '" + ElementID + "'");
         }

         public static SqlConnection NewConnection()
         {
             String connString = "[our-stuff]";
             return new SqlConnection(connString);
         }

         public static void ExecuteSQL(String sql)
         {
             SqlConnection cn  = NewConnection();
             SqlCommand    cmd = new SqlCommand(sql, cn);
             cmd.ExecuteNonQuery();
             cmd.Dispose();
             cn.Close();
             cn.Dispose();
         }
     }
}

->8--

-8<-- Class CSCS.Util.CSCSFuncs -->8-

This class is quite simple for now - it only has the NormalizeSpace 
method in it.  (This is actually linked into our .NET website as a 
reference...)

using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     public class CSCSFuncs
     {
         /// <summary>
         /// Eliminates all whitespace from a string, similar to the way
         /// HTML does
         /// </summary>
         /// <param name="textIn"></param>
         /// <returns>String</returns>
         public static String NormalizeSpace(String textIn)
         {
             String workText = textIn.Trim();

             while (workText.IndexOf("  ") >= 0)
             {
                 workText = workText.Replace("  "," ");
             }
             return workText;
         }

     }
}

->8--

-8<-- Class CSCS.Util.CodeStatistics -->8-

This is the main class.  I've left out the cull stuff, because I've been 
concentrating on the other.  (And, sadly, the COBOL dictionary is part 
of the cull stuff - but, I'll post my current version of that at the end 
of these...)  I also haven't completed the working-storage-to-property 
transformation completely yet, or implemented the above two classes 
(this still has an executeSQL method, for example).

using CSCS.DB;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;

namespace CSCS.Util
{
     public class CodeStatistics
     {
         // Properties (public instance variables)
         public String elementId
         {
             get
             {
                 return elementId;
             }
             set
             {
                 elementId = value;
             }
         }

         // Private instance variables
         protected SqlConnection     dbConn;
         protected SqlConnection     dbHelp;
         protected String            elementType    = "";
         protected String            elementSubType = "";
         protected String            fileName       = "";
         private   KeywordDictionary cobol          = new 
CobolKeywordDictionary();

         protected DataRow itemInfo;


         // Constuctor for unknown element
         public CodeStatistics(String ServerName)
         {
             openSqlConnection(ServerName);
         }

         // Constructor for known element
         public CodeStatistics(String ServerName, String ElementId)
         {
             openSqlConnection(ServerName);
             retrieveElementInfo(ElementId);
         }

         // Establish the element for this class instance
         protected void retrieveElementInfo(String reiElementId)
         {
             // Retrieve the information about the passed program
             DataSet itemSet = new DataSet();
             String sql = "SELECT * "
                 + "FROM active_elements "
                 + "WHERE element_id = '" + reiElementId.Trim() + "'";
             SqlDataAdapter da = new SqlDataAdapter(sql, dbConn);
             da.Fill(itemSet);

             if (itemSet.Tables.Count > 0)
             {
                 itemInfo       = itemSet.Tables["active_elements"].Rows[0];
                 elementType    = 
itemInfo["element_type"].ToString().Trim();
                 elementSubType = 
itemInfo["element_subtype"].ToString().Trim();
                 fileName       = itemInfo["server_name"].ToString().Trim();
                 elementId      = reiElementId.Trim();
             }
         }

         // Update the statistics for the element ID
         public void updateStatistics(String usPath, String usProcessName)
         {
             if (File.Exists(usPath + fileName))
             {
                 clearXrefTables();
                 walkThruFile(usPath + fileName, usProcessName);
             }
         }

         protected void walkThruFile(String wtfPath, String wtfProcessName)
         {
             String            textLine    = "";
             StreamReader      file        = File.OpenText(wtfPath);
             CodeCounter       counter     = new 
CodeCounter(elementType, elementSubType);
             ProcXrefUpdater   procUpdater = new 
ProcXrefUpdater(elementId, elementType, elementSubType);
             RejectXrefUpdater rejUpdater  = new 
RejectXrefUpdater(elementId, wtfProcessName);
             CallXrefUpdater   callUpdater = new CallXrefUpdater(elementId);

             while (!file.EndOfStream)
             {
                 textLine = file.ReadLine().ToUpper();

                 if ((elementType != "P") && (elementType != "L"))
                 {
                     textLine = textLine.Trim();
                 }

                 counter.CountLine(textLine); // Count this line as a 
"line of code"

                 switch(elementType)
                 {
                     case "P":
                     case "L":
                         textLine = textLine.Replace(",", " 
").Replace(".", " ").Trim();
                         procUpdater.UpdateXref(textLine);
                         rejUpdater.UpdateXref(textLine);
                         callUpdater.UpdateXref(textLine);
                         //updateCull(textLine);
                         break;
                 }

             }

             file.Close();
             file.Dispose();

             deleteNestedCalls(callUpdater);
             updateLOC(counter);
         }

         // Deletes calls to nested subprograms, if they exist
         protected void deleteNestedCalls(CallXrefUpdater callUpdater)
         {
             if (callUpdater.ProgramIDs.Count > 0)
             {   // Delete any references to calls if the target is 
defined in the program (i.e., nested subprograms)
                 DBUtil.ExecuteSQL("DELETE FROM sdp_CSCI_CALL_Xref "
                     + "WHERE Element_ID = '" + elementId + "' "
                         + "AND Call_Name IN ('"
                             + String.Join("','", 
callUpdater.ProgramIDs.ToArray()) + "')");
             }
         }

         // Updates the lines of code for this item
         protected void updateLOC(CodeCounter counter)
         {
             itemInfo["total_lines"]      = counter.LOCtotal;
             itemInfo["executable_lines"] = counter.LOCexecutable;
             itemInfo["commented_lines"]  = counter.LOCcommented;
             itemInfo.AcceptChanges();
         }


         protected void updateCull(String ucLine)
         {
             // Redacted
         }

         // Establish connections with the database
         protected void openSqlConnection(String oscServerName)
         {
             String connString = "";

             if (oscServerName == "") {
                 oscServerName = "[default name]";
             }

             connString = "server=" + oscServerName + "[other settings]";
             dbConn = new SqlConnection(connString);
             dbConn.Open();

             connString = connString.Replace("[db1]","[db2]");
             dbHelp = new SqlConnection(connString);
             dbHelp.Open();
         }

         public String cscsRegValue(String crvKey)
         {
             SqlCommand crvCmd = new SqlCommand("SELECT reg_value "
                 + "FROM sdp_registry "
                 + "WHERE reg_key = '" + crvKey + "'", dbConn);
             SqlDataReader crvDR = crvCmd.ExecuteReader();
             if (crvDR.Read())
             {
                 return(crvDR["reg_value"].ToString().Trim());
             }
             else
             {
                 return("");
             }
         }

         protected void clearXrefTables()
         {
             // Depending on the type, clear out the cross-reference tables
             switch (elementType)
             {
                 case "P":
                 case "L":
                     // Delete xrefs
                     executeSQL("DELETE FROM Proc_Prog_Xref     WHERE 
ProgName   = '" + elementId + "'");
                     executeSQL("DELETE FROM RejectsXref        WHERE 
program    = '" + elementId + "'");
                     executeSQL("DELETE FROM sdp_CSCI_Call_Xref WHERE 
Element_ID = '" + elementId + "'");
                     // Delete cull info
                     executeSQL("DELETE FROM sdp_Dbe_Csci_Xref WHERE 
CSCI = '" + elementId + "'");
                     executeSQL("DELETE FROM sdp_Dbr_Csci_Xref WHERE 
CSCI = '" + elementId + "'");
                     break;
                 }

         }

         protected void executeSQL(String esText)
         {
             SqlConnection esConn = new 
SqlConnection(dbConn.ConnectionString + "[password]");
             SqlCommand    esCmd  = new SqlCommand(esText, esConn);
             esConn.Open();
             esCmd.ExecuteNonQuery();
             esCmd.Dispose();
             esConn.Close();
             esConn.Dispose();
         }

     }
}

->8--

-8<-- Class CSCS.Util.CodeCounter -->8-

This class has the responsibility for counting lines of code.  It 
exposes the counts that it has obtained.

using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     public class CodeCounter
     {
         // Public Properties
         // Lines of Code totals
         public int LOCtotal {
             get { return locTotal; }
         }
         public int LOCexecutable {
             get { return locExecutable; }
         }
         public int LOCcommented {
             get { return locCommented; }
         }

         // Private properties
         private int locTotal {
             get { return locTotal;  }
             set { locTotal = value; }
         }
         private int locExecutable {
             get { return locExecutable;  }
             set { locExecutable = value; }
         }
         private int locCommented {
             get { return locCommented;  }
             set { locCommented = value; }
         }
         private String ElementType {
             get { return ElementType;  }
             set { ElementType = value; }
         }
         private String ElementSubType {
             get { return ElementSubType;  }
             set { ElementSubType = value; }
         }
         private String commentStart {
             get { return commentStart; }
             set { commentStart = value; }
         }
         private String commentEnd {
             get { return commentEnd; }
             set { commentEnd = value; }
         }
         private String commentSingle {
             get { return commentSingle; }
             set { commentSingle = value; }
         }
         private bool inComment {
             get { return inComment; }
             set { inComment = value; }
         }


         /// <summary>
         /// Constructor for code counter class - sets up environment
         /// </summary>
         /// <param name="ElementTypeIn"></param>
         /// <param name="ElementSubTypeIn"></param>
         public CodeCounter(String ElementTypeIn, String ElementSubTypeIn)
         {
             locTotal       = locExecutable = locCommented = 0;
             ElementType    = ElementTypeIn;
             ElementSubType = ElementSubTypeIn;
             inComment      = false;
             DetermineCommentDelimiters();
         }

         /// <summary>
         /// Determines the comment delimiters for various element types
         /// </summary>
         private void DetermineCommentDelimiters()
         {
             if (ElementType == "G")
             {
                 switch (ElementSubType)
                 {
                     case "HTML":
                     case "CSS":
                     case "XML":
                         commentStart = "<!--";
                         commentEnd = "-->";
                         break;

                     case "XSLT":
                         commentStart = "<xsl:comment>";
                         commentEnd = "</xsl:comment>";
                         break;

                     case "JS":
                         commentStart = "/*";
                         commentEnd = "*/";
                         commentSingle = "//";
                         break;
                 }
             }
         }

         /// <summary>
         /// Counts a line of code, based on the element type and subtype
         /// </summary>
         /// <param name="textLine"></param>
         public void CountLine(String textLine)
         {   // A line is a line...
             locTotal++;

             if (textLine != "")
             {
                 switch(ElementType)
                 {
                     case "P":
                     case "L":
                         countCobolLine(textLine);
                         break;

                     case "G":
                         countGuiLine(textLine);
                         break;

                     case "R":
                         countRunstreamLine(textLine);
                         break;

                     case "Q":
                         countIquLine(textLine);
                         break;

                     default:
                         // Anything else, a non-blank line is executable
                         locExecutable++;
                         break;
                 }
             }
         }

         /// <summary>
         /// This method determines whether a line of COBOL code is 
commented
         /// or executable
         /// </summary>
         /// <param name="line"></param>
         protected void countCobolLine(String line)
         {
             if ((line.Length > 6) && (line.Substring(6, 1) == "*"))
             {
                 locCommented++;
             }
             else
             {
                 locExecutable++;
             }

         }

         /// <summary>
         /// This method determines whether a GUI line of code is 
commented or
         /// executable
         /// </summary>
         /// <param name="line"></param>
         protected void countGuiLine(String line)
         {

             if ((commentStart == "") && (commentEnd == "") && 
(commentSingle == ""))
             {   // We don't look for comments - if it's not blank, it's 
executable
                 locExecutable++;
             }
             else
             {
                 if (inComment)
                 {   // We're in a multi-line comment
                     locCommented++;
                     if (line.IndexOf(commentEnd) >= 0)
                     {   // This is the last line of the multi-line comment
                         inComment = false;
                     }
                 }
                 else
                 {
                     if (line.IndexOf(commentStart) >= 0)
                     {
                         if (line.IndexOf(commentEnd) == -1)
                         {   // Start of a multi-line comment
                             inComment = true;
                         }
                         if ((line.IndexOf(commentStart) == 0))
                         {   // Nothing before the comment - the entire 
line is commented
                             locCommented++;
                         }
                         else
                         {   // Something before the comment - count the 
line as executable
                             locExecutable++;
                         }
                     }
                     else
                     {
                         if ((commentSingle != "") && 
(line.IndexOf(commentSingle) >= 0))
                         {
                             if (line.IndexOf(commentSingle) == 0)
                             {   // The entire line is a comment
                                 locCommented++;
                             }
                             else
                             {   // Only the end of the line is commented
                                 locExecutable++;
                             }
                         }
                         else
                         {
                             locExecutable++;
                         }
                     }
                 }
             }

         }

         /// <summary>
         /// This method determines whether a runstream line is commented or
         /// executable
         /// </summary>
         /// <param name="line"></param>
         protected void countRunstreamLine(String line)
         {
             bool counted = false;

             switch (ElementSubType)
             {
                 case "IPF":
                     if (line.Substring(0, 1) == "@")
                     {   // IPF comment character
                         locCommented++;
                         counted = true;
                     }
                     break;

                 case "QLP":
                     if (line.Substring(0, 1) == "*")
                     {   // QLP comment character
                         locCommented++;
                         counted = true;
                     }
                     break;
                 default:
                     // Apply ECL comment rules
                     if   ((line.Length > 2)
                       && ((line.Substring(0, 3) == "@ .")
                       ||  (line.Substring(0, 3) == "@. ")))
                     {   // ECL comment character
                         locCommented++;
                         counted = true;
                     }
                     break;
             }
             if (!counted)
             {
                 locExecutable++;
             }
         }

         /// <summary>
         /// This method determines whether an IQ/U line is commented or
         /// executable
         /// </summary>
         /// <param name="line"></param>
         protected void countIquLine(String line)
         {
             if (line.Substring(0, 1) == ".")
             {
                 locCommented++;
             }
             else
             {
                 locExecutable++;
             }

         }
     }
}

->8--

-8<-- Class CSCS.Util.ProcXrefUpdater -->8-

This class is responsible for updating the item/proc cross-reference.

using CSCS.DB;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     public class ProcXrefUpdater
     {
         private String ElementID {
             get { return ElementID; }
             set { ElementID = value; }
         }
         private String ElementType {
             get { return ElementType; }
             set { ElementType = value; }
         }
         private String ElementSubType {
             get { return ElementSubType; }
             set { ElementSubType = value; }
         }

         public ProcXrefUpdater(String ElementIDIn, String 
ElementTypeIn, String ElementSubTypeIn)
         {
             ElementID      = ElementIDIn;
             ElementType    = ElementTypeIn;
             ElementSubType = ElementSubTypeIn;
         }

         public void UpdateXref(String textLine)
         {
             // For this to work right, we need all items separated by 
only one space
             textLine = CSCSFuncs.NormalizeSpace(textLine);

             switch (ElementType) {
                 case "P":
                     UpdateXrefForProgram(textLine);
                     break;

                 case "L":
                     UpdateXrefForProc(textLine);
                     break;
             }

         }

         /// <summary>
         /// Establishes the proc xref based on the "COPY" statement,
         /// at the entry point level
         /// </summary>
         /// <param name="line"></param>
         protected void UpdateXrefForProgram(String line)
         {
             if ((line.Length > 6) && (line.Substring(0, 5) == "COPY ")) {
                 String[] words = line.Split(' ');
                 String[] pieces = words[1].Split('-');

                 if (DBUtil.ElementExists(pieces[0]))
                 {   // See if this is already in the cross-reference
                     if (!DBUtil.RowExists("SELECT ProgName "
                             + "FROM Proc_Prog_Xref "
                             + "WHERE   ProgName   = '" + ElementID + "' "
                                 + "AND ProcName   = '" + pieces[0] + "' "
                                 + "AND EntryPoint = '" + words[1] + "'"))
                     {   // Add this program/proc to the table
                         DBUtil.ExecuteSQL("INSERT INTO Proc_Prog_Xref "
                             + "(ProgName, ProcName, Passive, EntryPoint) "
                             + "VALUES ('" + ElementID + "','" + 
pieces[0] + "',0,'" + words[1] + "')");
                     }
                 }
             }
         }

         /// <summary>
         /// Establishes the proc xref based on the "PERFORM" statement,
         /// at the proc level
         /// </summary>
         /// <param name="line"></param>
         protected void UpdateXrefForProc(String line)
         {
             if ((line.Length > 9) && (line.Substring(0, 8) == "PERFORM "))
             {
                 String[] words  = line.Split(' ');
                 String[] pieces = words[1].Split('-');

                 // Don't count performs of the proc itself
                 if ((pieces[0] != ElementID) && 
(DBUtil.ElementExists(pieces[0])))
                 {   // See if this is already in the xref
                     if (!DBUtil.RowExists("SELECT ProgName "
                             + "FROM Proc_Prog_Xref "
                             + "WHERE   ProgName = '" + ElementID + "' "
                                 + "AND ProcName = '" + pieces[0] + "'"))
                     {
                         DBUtil.ExecuteSQL("INSERT INTO Proc_Prog_Xref "
                             + "(ProgName, ProcName, Passive, EntryPoint) "
                             + "VALUES ('" + ElementID + "','" + 
pieces[0] + "',1,NULL)");
                     }
                 }
             }
         }
     }
}

->8--

-8<-- Class CSCS.Util.RejectXrefUpdater -->8-

This class is responsible for updating the item/reject cross-reference.

using CSCS.DB;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     public class RejectXrefUpdater
     {
         private String ElementID {
             get { return ElementID;  }
             set { ElementID = value; }
         }
         private String ProcessName {
             get { return ProcessName;  }
             set { ProcessName = value; }
         }

         public RejectXrefUpdater(String ElementIDIn, String ProcessNameIn)
         {
             ElementID   = ElementIDIn;
             ProcessName = ProcessNameIn;
         }

         public void UpdateXref(String textLine)
         {
             Int32 rejectCode;

             // Get rid of extra spaces
             textLine = CSCSFuncs.NormalizeSpace(textLine);
             rejectCode = FindRejectCode(textLine);

             if (rejectCode > 0)
             {
                 StoreRejectXref(rejectCode);
             }
         }

         /// <summary>
         /// Finds the reject code in a line of text, returning 0
         /// if one was not found
         /// </summary>
         /// <param name="line"></param>
         /// <returns>Int32</returns>
         protected Int32 FindRejectCode(String line)
         {
             Int32 rejectCode = 0;

             if ((line.IndexOf("REJCDE") >= 0) && (line.IndexOf("MOVE ") 
 >= 0))
             {   // Line is "MOVE [something] TO REJCDE"
                 String[] words = line.Split(' ');
                 if (Int32.TryParse(words[1], out rejectCode))
                 {   // Mask off narratives to get the lowest 4 digits
                     rejectCode = rejectCode % 10000;
                 }
             }

             return rejectCode;
         }

         /// <summary>
         /// Store the program/reject xref row
         /// </summary>
         /// <param name="RejectCode"></param>
         protected void StoreRejectXref(Int32 RejectCode)
         {   // Is this reject already in the xref?
             if (!DBUtil.RowExists("SELECT program "
                     + "FROM RejectsXref "
                     + "WHERE   program    = '" + ElementID + "' "
                         + "AND reject_num = "  + RejectCode.ToString()))
             {   // Insert it
                 DBUtil.ExecuteSQL("INSERT INTO RejectsXref "
                     + "(program, reject_num, last_updated, 
last_updated_by) "
                     + "VALUES ('" + ElementID + "'," + 
RejectCode.ToString()
                     + ",current_timestamp,'" + ProcessName + "')");
             }
         }

     }
}

->8--

-8<-- Class CSCS.Util.CallXrefUpdater -->8-

This class is responsible for updating the item/call cross-reference. 
It exposes a list of PROGRAM-IDs that are found throughout the code.

using CSCS.DB;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     public class CallXrefUpdater
     {
         // ProgramIDs found in the source code
         public List<String> ProgramIDs {
             get { return programIDlist; }
         }
         private String ElementID {
             get { return ElementID;  }
             set { ElementID = value; }
         }
         private List<String> programIDlist = new List<String>();

         public CallXrefUpdater(String ElementIDIn)
         {
             ElementID = ElementIDIn;
         }

         public void UpdateXref(String textLine)
         {
             String[] words = CSCSFuncs.NormalizeSpace(textLine).Split(' ');

             // Check for "PROGRAM-ID"
             if (words[0] == "PROGRAM-ID") {   // Save these off - we'll 
delete them at the end
                 programIDlist.Add(words[1]);
             }

             if ((words.Length > 1) && (words[0] == "CALL")) {
                 if ((words[1].Substring(0, 1) == "\"") || 
(words[1].Substring(0, 1) == "'"))
                 {   // Calling a literal - this is one we'll store
                     String callName = words[1].Substring(1, 
words[1].Length - 2);

                     if (!DBUtil.RowExists("SELECT Element_ID "
                             + "FROM sdp_CSCI_CALL_Xref "
                             + "WHERE   Element_ID = '" + ElementID + "' "
                                 + "AND Call_Name  = '" + callName + "'"))
                     {   // It's not there - insert it
                         DBUtil.ExecuteSQL("INSERT INTO sdp_CSCI_CALL_Xref "
                             + "(Element_ID, Call_Name) "
                             + "VALUES ('" + ElementID + "','" + 
callName + "')");
                     }
                 }
             }
         }
     }
}

->8--

-8<-- CSCS.Util.CobolKeywordDictionary -->8-

This class is responsible for identifying COBOL keywords.

using System;
using System.Collections.Generic;
using System.Text;

namespace CSCS.Util
{
     class CobolKeywordDictionary : KeywordDictionary
     {
         // This is loaded with the keywords from the below table
         static private Dictionary<String,String> cobolKeywords = new 
Dictionary<String, String>();

         static CobolKeywordDictionary()
         {
             // A list of COBOL keywords
             String[] keywords = { [the keywords] };

             for (int i = 0; i < keywords.Length; i++)
             {
                 cobolKeywords.Add(keywords[i], null);
             }

         }
         public bool isKeyword(String keyword)
         {
             return cobolKeywords.ContainsKey(keyword.ToUpper());
         }
     }
}

->8--

Have a wonderful day!

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~   /   \  /         ~        Live from Montgomery, AL!       ~
~  /     \/       o  ~                                        ~
~ /      /\   -   |  ~          daniel@thebelowdomain         ~
~ _____ /  \      |  ~      http://www.djs-consulting.com     ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e    ~
~ h---- r+++ z++++                                            ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"Who is more irrational?  A man who believes in a God he doesn't see, or 
a man who's offended by a God he doesn't believe in?" - Brad Stine
0
lxi0007 (1830)
2/6/2007 5:00:26 AM
comp.lang.cobol 4278 articles. 1 followers. Post Follow

3 Replies
9037 Views

Similar Articles

[PageSpeed] 5

"LX-i" <lxi0007@netscape.net> wrote in message 
news:e8586$45c80b6b$454920f8$1704@KNOLOGY.NET...
> Here is what I've come up with - there are seven or eight classes now, two 
> of which are "support classes" (not sure if that's the term - they're not 
> helper classes because they're in their own class definition).  They are 
> below, with a description of their purpose.  For those of you who have the 
> time and inclination, feel free to comment.
>
[most of the code snipped]
>
>         /// <summary>
>         /// Returns true if an element is a CSCI within CSCS
>         /// </summary>
>         /// <param name="ElementID"></param>
>         /// <returns>bool</returns>
>         public static bool ElementExists(String ElementID)
>         {
>             return RowExists("SELECT Actv_Ind "
>                 + "FROM Active_Elements "
>                 + "WHERE Element_ID = '" + ElementID + "'");
>         }

    This leaves you open to SQL injection attacks: a malicious user could 
set the value of ElementID to be equal to "'; DELETE * FROM Active_Elements; 
SELECT '' = '" for example, so that the concatenated string ends up looking 
like:

SELECT Actv_Ind
FROM Active_Elements
WHERE Element_ID = ''; DELETE * FROM Active_Elements; SELECT '' = ''

Even if the code is only used internally, it's best to get into the habit of 
using parameterized SQL commands.

http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson06.aspx

    - Oliver 


0
owong (6177)
2/8/2007 7:26:33 PM
Oliver Wong<owong@castortech.com> 02/08/07 12:26 PM >>>
>"LX-i" <lxi0007@netscape.net> wrote in message 
>news:e8586$45c80b6b$454920f8$1704@KNOLOGY.NET...
>> Here is what I've come up with - there are seven or eight classes now,
two 
>> of which are "support classes" (not sure if that's the term - they're not

>> helper classes because they're in their own class definition).  They are

>> below, with a description of their purpose.  For those of you who have
the 
>> time and inclination, feel free to comment.
>>
>[most of the code snipped]
>>
>>         /// <summary>
>>         /// Returns true if an element is a CSCI within CSCS
>>         /// </summary>
>>         /// <param name="ElementID"></param>
>>         /// <returns>bool</returns>
>>         public static bool ElementExists(String ElementID)
>>         {
>>             return RowExists("SELECT Actv_Ind "
>>                 + "FROM Active_Elements "
>>                 + "WHERE Element_ID = '" + ElementID + "'");
>>         }
>
>    This leaves you open to SQL injection attacks: a malicious user could 
>set the value of ElementID to be equal to "'; DELETE * FROM
Active_Elements; 
>SELECT '' = '" for example, so that the concatenated string ends up looking

>like:
>
>SELECT Actv_Ind
>FROM Active_Elements
>WHERE Element_ID = ''; DELETE * FROM Active_Elements; SELECT '' = ''
>
>Even if the code is only used internally, it's best to get into the habit
of 
>using parameterized SQL commands.
>
>http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson06.aspx 

I always wondered what "SQL Injection" was.  Interesting!

Frank


--- 
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO  USA
0
2/9/2007 12:46:19 AM
Oliver Wong wrote:
> "LX-i" <lxi0007@netscape.net> wrote in message 
> news:e8586$45c80b6b$454920f8$1704@KNOLOGY.NET...
>> Here is what I've come up with - there are seven or eight classes now, two 
>> of which are "support classes" (not sure if that's the term - they're not 
>> helper classes because they're in their own class definition).  They are 
>> below, with a description of their purpose.  For those of you who have the 
>> time and inclination, feel free to comment.
>>
> [most of the code snipped]
>>         /// <summary>
>>         /// Returns true if an element is a CSCI within CSCS
>>         /// </summary>
>>         /// <param name="ElementID"></param>
>>         /// <returns>bool</returns>
>>         public static bool ElementExists(String ElementID)
>>         {
>>             return RowExists("SELECT Actv_Ind "
>>                 + "FROM Active_Elements "
>>                 + "WHERE Element_ID = '" + ElementID + "'");
>>         }
> 
>     This leaves you open to SQL injection attacks: a malicious user could 
> set the value of ElementID to be equal to "'; DELETE * FROM Active_Elements; 
> SELECT '' = '" for example, so that the concatenated string ends up looking 
> like:
> 
> SELECT Actv_Ind
> FROM Active_Elements
> WHERE Element_ID = ''; DELETE * FROM Active_Elements; SELECT '' = ''

Wow - I never knew what a SQL injection attack was.  Thanks for bringing 
that up - we'll be implementing safer queries soon!  :)

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~   /   \  /         ~        Live from Montgomery, AL!       ~
~  /     \/       o  ~                                        ~
~ /      /\   -   |  ~          daniel@thebelowdomain         ~
~ _____ /  \      |  ~      http://www.djs-consulting.com     ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e    ~
~ h---- r+++ z++++                                            ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"Who is more irrational?  A man who believes in a God he doesn't see, or 
a man who's offended by a God he doesn't believe in?" - Brad Stine
0
lxi0007 (1830)
2/9/2007 2:20:46 AM
Reply: