Friday, December 13, 2024

Execute store procedure with out param dynamicly

 CREATE PROCEDURE Myproc

@parm varchar(10),

@parm1OUT varchar(30) OUTPUT,
@parm2OUT varchar(30) OUTPUT
AS
SELECT @parm1OUT='parm 1' + @parm
SELECT @parm2OUT='parm 2' + @parm
GO

DECLARE @SQLString NVARCHAR(500)
DECLARE @ParmDefinition NVARCHAR(500)
DECLARE @parmIN VARCHAR(10)
DECLARE @parmRET1 VARCHAR(30)
DECLARE @parmRET2 VARCHAR(30)
SET @parmIN=' returned'
SET @SQLString=N'EXEC Myproc @parm,
@parm1OUT OUTPUT, @parm2OUT OUTPUT'
SET @ParmDefinition=N'@parm varchar(10),
@parm1OUT varchar(30) OUTPUT,
@parm2OUT varchar(30) OUTPUT'

EXECUTE sp_executesql
@SQLString,
@ParmDefinition,
@parm=@parmIN,
@parm1OUT=@parmRET1 OUTPUT,@parm2OUT=@parmRET2 OUTPUT

SELECT @parmRET1 AS "parameter 1", @parmRET2 AS "parameter 2"
go
drop procedure Myproc

A simple recorder based on selenium

 As known, selenium automating web applications for testing purposes. Below code will present an idea to record operations performed on the browser using selenium and javascript. The key is using javascript to listen the onlick and onchange event of document element. And then according to the return information to identify what action the tester did and what element the action performed. 


/** JavaScript to register listeners for click & change events. */

private static final String SCRIPT = "var callback = arguments[arguments.length - 1];"

+ "function record(category)"

+ "{"

+"var result = new Array();"

+"result[0] = category;"

+"result[1] = event.srcElement.tagName;"

+"result[2] = event.srcElement.id;"

+"result[3] = event.srcElement.name;"

+"result[4] = event.srcElement.className;"

+"result[5] = event.srcElement.type;"

+"result[6] = event.srcElement.value;"

+"result[7] = event.srcElement.getAttribute('gwt_id');"

+"result[8] = event.srcElement.getAttribute('control_id');"

+"result[9] = event.srcElement.innerText;"

+ "callback(result);"

+ "}"

+ "function click()"

+ "{" 

+ "record('click');"

+ "}"

+ "function enter()"

+ "{" 

+ "record('enter');"

+ "}"

+ "document.onclick = click;"

+ "document.onchange = enter;";


/** Constant definition for tab name index. */

protected static final int TAG_NAME_INDEX = 1;

/** Constant definition for ID index. */

protected static final int ID_INDEX = 2;

/** Constant definition for name index. */

protected static final int NAME_INDEX = 3;

/** Constants definition for class property index. */

protected static final int CLASS_INDEX = 4;

/** Constant definition for value index. */

protected static final int VALUE_INDEX = 6;

/** Constant definition for GWT ID index. */

protected static final int GWT_ID_INDEX = 7;

/** Constant definition for control id index. */

protected static final int CONTROL_ID_INDEX = 8;

/** Constant definition for inner text index. */

protected static final int INNER_TEXT_INDEX = 9;


driver.manage().timeouts().setScriptTimeout(5000, TimeUnit.SECONDS);

Object result = ((JavascriptExecutor) webDriver).executeAsyncScript(SCRIPT);

if (result instanceof List<?>) {

    @SuppressWarnings("unchecked")

    List<String> list = (List<String>) result;

    

    String classAttribute = list.get(CLASS_INDEX);

    ParseResult result = ParseResult.FAILURE;

    if (list[0] == "click" && !StringUtils.isEmpty(classAttribute) && classAttribute.contains("Label")) {

        String tabCaption = list.get(INNER_TEXT_INDEX);

        String xpath = String.format("//div[@class='%s'][text()='%s']/parent::div", list.get(CLASS_INDEX),     tabCaption);

        WebElement element = driver.waitForXPath(xpath);

        String parentClass = element.getAttribute("class");

        if (StringUtils.isNotBlank(parentClass) && parentClass.contains("TabLayoutPanelTabInner")) {

            ICommand command = new Command(COMMAND_NAME, tabCaption);

            result = new ParseResult(command);

        }

    }

}




Parsing a command based script file with Regex

 In script file, the command format is:


command  param1  "param 2" "param3 has double quotes \" and single quote '" ...

All all those 3 parameters are valid. 

The white space is the separator among command and parameters.

when there are spaces in parameter, it should be included in double quotes, e.g. "param 2".

when there are double quotes in parameter, should use backslash ('\') to escape. e.g. "param \" 3"

when line start with sharp mark ('#'), it is comment and should be ignored.

source:

import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ScriptFileParser handles loading from simple .text based scripts.
 *
 * @author: barret
 */
public class ScriptFileParser  {
    // CHECKSTYLE:OFF
    private static final String ERROR_MESSAGE = "The format is invalid for script line: %s";
    private static final String REGX_FOR_GROUP = "\"((?:\\\\\"|[^\"])*)\"";
    private static final String REGX_FOR_PARAMETER = REGX_FOR_GROUP + "|([^\"\\s]+)";
    // CHECKSTYLE:ON

    /** The logging instance for this class. */
    private static final Log LOG = LogFactory.getLog(ScriptFileParser.class);  

    /**
     * Read the string lines from given script steam.
     * Filter the byte order mark when necessary.
     *
     * @param scriptStream of script file.
     * @return the read lines.
     * @throws IOException thrown if the stream cannot be read.
     */
     public List<String> readLines(final InputStream scriptStream) throws IOException {
List<String> lineList;
BOMInputStream bomIn = new BOMInputStream(scriptStream, ByteOrderMark.UTF_8,
                                                                ByteOrderMark.UTF_16LE,
                                                                ByteOrderMark.UTF_16BE);

        if (bomIn.hasBOM()) {
String encoding = bomIn.getBOMCharsetName();
lineList = IOUtils.readLines(bomIn, encoding);
} else {
lineList = IOUtils.readLines(bomIn);
}
return lineList;
}
    
    /**
     * Parse the given script row.
     *
     * @param row of script file.
     * @param lineNumber the line number where this line was found.
     * @return Builded script category.
     * @throws ScriptLoaderException if parse action failed.
     */
    private IScriptPrototypeLine parseScriptRow(final String row, final int lineNumber)  {
        if (row.trim().length() == 0 || row.trim().startsWith("#")) {
            return new ScriptComment(row, lineNumber);
        }
        
        checkFormat(row);
        
        List<String> params = parseParameters(row);
        
        if (params.size() < 1) {
     String message = String.format(ERROR_MESSAGE, row);
     throw new ScriptParseException(message);
        } 

        String command = params.get(0);
        params.remove(command);

        return new ScriptCommandPrototype(command, params, lineNumber);
    }

    /**
     * Parse the parameters from given script row.
     * 
     * @param row of script file.
     * @return Parsed parameters.
     */
     private List<String> parseParameters(final String row) {
        List<String> params = new ArrayList<String>();
        Pattern pattern = Pattern.compile(REGX_FOR_PARAMETER);
        Matcher matcher = pattern.matcher(row);
        while (matcher.find()) {
         String parsed = matcher.group(1) != null ? matcher.group(1) : matcher.group();
         String param = parsed.replace("\\\"", "\"");
         params.add(param);
        }
return params;
     }

    /**
     * Check the format of given script row.
     * 
     * @param row of script file.
     * @throws ScriptLoaderException if format is invalid.
     */
     private void checkFormat(final String row) {
String replaced = row.replaceAll(REGX_FOR_GROUP, "\"");
        String invalidFormatReg = "\"\\S|\\S\"";
        
        Pattern pattern = Pattern.compile(invalidFormatReg);
        Matcher matcher = pattern.matcher(replaced);

        while (matcher.find()) {
     String message = String.format(ERROR_MESSAGE, row);
     throw new ScriptParseException(message);
        }
    }
}

Transfer XML to HTML by JS based on XSL

 XSL stands for Extended Stylesheet Language. The reason why the World Wide Web Consortium began developing XSLs was due to the demand for XML based style sheet languages. XSLT stands for XSLT transformation, which is a W3C standard. Just as CSS is a style sheet for HTML, XSL is a style sheet for XML.

1 Prepare XML file cdcatalog.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>

</catalog>

2 Prepare xsl file cdcatalog.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th align="left">Title</th>
        <th align="left">Artist</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
        <td><xsl:value-of select="title" /></td>
        <td><xsl:value-of select="artist" /></td>
      </tr>
      </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>


</xsl:stylesheet>

3 Prepare javascript:

<html>
<body>

<script type="text/javascript">

// Load XML
var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load("cdcatalog.xml")

// Load XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load("cdcatalog.xsl")

// Transform
document.write(xml.transformNode(xsl))

</script>

</body>
</html>

Parse XML by XPath

 XPath is a language used to search for information in XML documents. XPath can be used to traverse elements and attributes in XML documents.

XPath is a major element of the W3C XSLT standard, and both XQuery and XPointer are built on top of the XPath expression.

Therefore, understanding XPath is the foundation of many advanced XML applications.

1 Prepare xml file books.xml

    

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book category="COOKING">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>

2 Prepare HTML file XPathTest.html using XPath

<html>
<body>
<script type="text/javascript">

var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load("books.xml")

path="/bookstore/book/title"

// code for IE
if (window.ActiveXObject)
{
var nodes=xml.selectNodes(path);

for (i=0;i<nodes.length;i++)
  {
  document.write(nodes[i].childNodes[0].nodeValue);
  document.write("<br />");
  }
}
</script>

</body>
</html>

C# calls the C++ code

 

  •     Prepare the C++ code:

    1 create the solution 'TestConsole' by VS.

    2 In this solution, add a new project CppDeno with mode 'Win32 Console Application' and application type 'DLL'

    3 In file CppDemo.cpp add the code as below:

    extern "C" __declspec(dllexport) int Add(int a,int b) {

return a + b; 

    }

    4 compile this simple project.

  •     Static call the C++ dll:

    1 Under solution 'TestConsole', add new project 'TestDemo'

    2 In program.cs file, add below code to Main method:

     Console.WriteLine(Add(1, 2)); 

Console.Read();

    3 Copy the CppDemo.lib & CppDemo.dll to debug folder of this project

    4 Press key 'F5' to run

  •     Dynamic call C++ code:

    1 Create new class NativeMethod.cs, the code as below:

    using System;

    using System.Runtime.InteropServices;

    namespace TestDemo

   {

    internal class NativeMethod

    {

        [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]

        public static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

        [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]

        public static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]

        public static extern bool FreeLibrary(int hModule);

    }

}

    2 add delegate definition to Program.cs:

     delegate int Add(int a, int b);

    3 update method Main as below:

     static void Main(string[] args) {

            //1. 动态加载C++ Dll             

            int hModule = NativeMethod.LoadLibrary(@"c:CppDemo.dll");             

            if (hModule == 0) return;              

            //2. 读取函数指针             

            IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");              

            //3. 将函数指针封装成委托             

            Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));              

            //4. 测试             

            Console.WriteLine(addFunction(1, 2));             

            Console.Read();

}

   4 Press key 'F5' to run

Summery for synchronization in .NET

 The following tables summarize the .NET tools available for coordinating or synchronizing the actions of threads:

 

1 Simple Blocking Methods

    

ConstructPurpose
SleepBlocks for a given time period
JoinWaits for another thread to finish

 

2 Locking Constructs

ConstructPurposeCross Process?Speed
LockEnsures just one thread can access a resource, or section of code.NoFast
MutexEnsures just one thread can access a resource, or section of code. Can be used to prevent multiple instances of an application from starting.YesModerate
SemaphoreEnsures not more than a pecified number of therads can access a resource, or section of code.YesModerate

 

(Synchronization Context are also provided, for automatic locking)

3 Signaling Constructs

ConstructPurposeCross Process?Speed
EventWaitHandleAllows a thread to wait until it receives a signal from another therad.YesModerate
Wait & PulseAllows a thread to wait until a custom blocking condition is met.NoModerate

4 Non-Blocking Synchronization Constructs

ConstructPurposeCross Process?Speed
InterlockedTo perform simple non-blocking atomic operations.Yes (Assuming shared memory)Very fast
volatileTo allow safe non-blocking access to individual fields outside of a lock.Yes (Assuming shared memory)Very fast