Professional Web Applications Themes

My first CFC - a little help. - Coldfusion - Advanced Techniques

Hey guys, I'm trying to create a CFC which allows me to input two table names and two datasources and return to me the differences of the two tables. I want to return any differences in the columnList, and also the records. I'll be able to handle the logic to do that, but am a little confused about how to approach the CFC. So I have a form page with 4 fields, Table1, Table2, DSN1, DSN2 - The user will give the dsn and tablenames they want to compare. How would you approach this. Should my CFC have 1 function ...

  1. #1

    Default My first CFC - a little help.

    Hey guys, I'm trying to create a CFC which allows me to input two table names
    and two datasources and return to me the differences of the two tables. I want
    to return any differences in the columnList, and also the records.

    I'll be able to handle the logic to do that, but am a little confused about
    how to approach the CFC. So I have a form page with 4 fields, Table1, Table2,
    DSN1, DSN2 - The user will give the dsn and tablenames they want to compare.

    How would you approach this. Should my CFC have 1 function which does all the
    logic and return 4 parameters back? Not clear on the syntax with this, can I
    use multiple CFRETURNS in one function?

    The examples I found online only cosisted of 1 function returning 1 variable.
    I understand this, but I need to return more then 1.

    Thanks!

    blastbeat Guest

  2. #2

    Default Re: My first CFC - a little help.

    "can I use multiple CFRETURNS in one function?"

    No.

    Either break each return out into a separate function, or have the result be
    stored in CFC member variables and access the results using get___ calls, or
    store all 4 results in a structure, indexed by the name of the result.

    Kronin555 Guest

  3. #3

    Default Re: My first CFC - a little help.

    Kronin, thanks for the quick reply.

    Let me give you the real world scenario I'm facing, as I think if you explain
    it it's going to benefit me a lot.

    Let's just say I wanted to, upon a form post, get the columnList of table1 and
    the list of table2, just 2 variables.

    So my first page has 2 form fields, table1 and table2, the user enters those
    in and the form is posted to a page which invokes my CFC. - This is the part I
    am confused on. Do I call multiple functions to return 2 vars? If so, how? or
    would I just return 1 variable with 2 seperate lists.

    Appreciate it

    blastbeat Guest

  4. #4

    Default Re: My first CFC - a little help.

    OK, the easiest method is as follows:

    In the CFC's function, create a struct that contains all return variables.
    Index those off whatever you deem appropriate:

    <cfset returnStruct = StructNew()>
    <cfset returnStruct.table1columnlist = whereverIStoredTable1ColumnList>
    <cfset returnStruct.table2list = whereverIStoredTable2List>
    <cfreturn returnStruct>

    Kronin555 Guest

  5. #5

    Default Re: My first CFC - a little help.

    Gotcha, thanks Kronin.
    blastbeat Guest

  6. #6

    Default Re: My first CFC - a little help.

    no prob. good luck.
    Kronin555 Guest

  7. #7

    Default Re: My first CFC - a little help.

    Kron, one more, perhaps I'm getting confused my first time because I'm trying
    to return a struct, the examples in the DOCS show a string being returned with
    CFINVOKE and looks straight forward.

    I believe my CFC is ok, but my INVOKE tag is off, let me know what you think.



    Here is my CFC

    <cfcomponent>
    <cffunction name="compareColumns" access="public" returntype="struct"
    hint="Returns the differences between columns in tables.">
    <cfargument name="tableOne" type="string" />
    <cfargument name="tableTwo" type="string" />
    <cfargument name="dsnOne" type="string" />
    <cfargument name="dsnTwo" type="string" />

    <cfquery name="tableOne" datasource="#dsnOne#">
    select *
    from #tableOne#
    </cfquery>
    <cfquery name="tableTwo" datasource="#dsnTwo#">
    select *
    from #tableTwo#
    </cfquery>

    <cfset tableCols = StructNew()>
    <cfset tableCols.tableOne = tableOne.ColumnList>
    <cfset tableCols.tableTwo = tableTwo.ColumnList>

    <cfreturn tableCols>

    </cffunction>
    </cfcomponent>

    And here is the page where I'm trying to invoke it and output tableCols.

    <cfinvoke component="tableDifferences" method="compareColumns"
    returnvariable="test" argumentcollection="tableCols"></cfinvoke>

    <cfoutput>#test#</cfoutput>

    I used argumentcollection as recommended by the docs if you are trying to
    return a struct

    blastbeat Guest

  8. #8

    Default Re: My first CFC - a little help.

    Well, one possible problem is that you're naming your queries the same as some
    arguments coming in. It's never good style to use the same name for different
    things. Either it's an argument, or a query.

    As far as <cfinvoke>, I've never used it with argumentcollection before. What
    is the contents of tableCols before you call <cfinvoke>?

    Kronin555 Guest

  9. #9

    Default Re: My first CFC - a little help.

    Hi Kron,

    Ok, so I ripped out all the component stuff to debug and figured out the
    structure is having difficulties storing the values. I validated this by
    outputing the var's on their own to validate that they work.

    Here is what my test page looks like.

    <cfset tableOne = "employees">
    <cfset tableTwo = "employees">
    <cfset dsnOne = "iportaluser">
    <cfset dsnTwo = "iportaluser">

    <cfquery name="tableOne" datasource="#dsnOne#">
    select *
    from #tableOne#
    </cfquery>
    <cfquery name="tableTwo" datasource="#dsnTwo#">
    select *
    from #tableTwo#
    </cfquery>

    <cfset tableCols = StructNew() />
    <cfset tableCols.tableOne = "tableOne.ColumnList" />
    <cfset tableCols.tableTwo = "tableTwo.ColumnList" />

    <cfoutput>#tableOne.ColumnList# #tableTwo.ColumnList#</cfoutput>


    As you can see, I'm outputting the columnlist of the queries and it's working
    fine. When I try and output the structure using
    <Cfoutput>#tableCols#</cfoutput> it breaks and give me the following error.

    Complex object types cannot be converted to simple values.

    blastbeat Guest

  10. #10

    Default Re: My first CFC - a little help.

    You can't just cfoutput a structure. It's a complex type (as the error says).

    <cfdump var="#tableCols#">
    Kronin555 Guest

  11. #11

    Default Re: My first CFC - a little help.

    Gotcha, but then I'm confused as to how to pass the structure out of the
    component to reference it on my next page. Here's my code, let me know how to
    output the structure on the next page. Basically, I want to compare the
    columnlists and display to the user any columns in table 2 not in table 1.

    <cfcomponent>
    <cffunction name="compareColumns" access="public" returntype="struct"
    hint="Returns the differences between columns in tables.">
    <cfargument name="tableOne" type="string" />
    <cfargument name="tableTwo" type="string" />
    <cfargument name="dsnOne" type="string" />
    <cfargument name="dsnTwo" type="string" />

    <cfquery name="tableOne" datasource="#dsnOne#">
    select *
    from #tableOne#
    </cfquery>
    <cfquery name="tableTwo" datasource="#dsnTwo#">
    select *
    from #tableTwo#
    </cfquery>

    <cfset tableCols = StructNew() />
    <cfset tableCols.tableOne = tableOne.ColumnList />
    <cfset tableCols.tableTwo = tableTwo.ColumnList />

    <cfreturn tableCols>

    </cffunction>
    </cfcomponent>


    blastbeat Guest

  12. #12

    Default Re: My first CFC - a little help.

    I got this working Kron, someone here helped me. Makes sense now.
    blastbeat Guest

  13. #13

    Default Re: My first CFC - a little help.

    Blastbeat, when you are writing your own functions, whether inside a component
    or elsewhere, it is to your advantage to use the var keyword when setting
    variables. In your case, this:
    <cfset tableCols = StructNew() />
    shoud be this:
    <cfset var tableCols = StructNew() />

    The reason is that if tableCols is declared as a variable before your method
    is invoked, your method will overwrite the variable. The var keyword keeps the
    variable local to the function.


    Dan Guest

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139