[{"data":1,"prerenderedAt":1280},["ShallowReactive",2],{"post:access-lucee-extension":3},{"id":4,"title":5,"body":6,"date":1267,"description":12,"draft":1268,"extension":1269,"meta":1270,"navigation":352,"path":1271,"seo":1272,"stem":1273,"tags":1274,"__hash__":1279},"posts\u002Fposts\u002Faccess-lucee-extension.md","Creating an MS Access Lucee Extension",{"type":7,"value":8,"toc":1256},"minimark",[9,13,18,76,79,82,98,101,114,117,120,136,139,150,179,185,239,251,261,271,281,298,316,319,331,805,819,871,890,916,954,960,963,966,980,986,1047,1050,1082,1085,1088,1095,1176,1183,1189,1235,1238,1249,1252],[10,11,12],"p",{},"I turned a simple task (migrate data from an MS Access database) into a Lucee extension which wraps the UCanAccess JDBC driver.",[14,15,17],"h2",{"id":16},"table-of-contents","Table Of Contents",[19,20,21,28,34,40,46,52,58,64,70],"ul",{},[22,23,24],"li",{},[25,26,17],"a",{"href":27},"#table-of-contents",[22,29,30],{},[25,31,33],{"href":32},"#querying-an-access-file-from-cfml","Querying an Access File from CFML",[22,35,36],{},[25,37,39],{"href":38},"#jdbc-is-awesome","JDBC Is Awesome!",[22,41,42],{},[25,43,45],{"href":44},"#why-a-lucee-extension","Why A Lucee Extension?",[22,47,48],{},[25,49,51],{"href":50},"#creating-the-lucee-extension","Creating the Lucee Extension",[22,53,54],{},[25,55,57],{"href":56},"#packaging-a-lucee-extension-with-commandbox-and-forgebox","Packaging a Lucee Extension with CommandBox and ForgeBox",[22,59,60],{},[25,61,63],{"href":62},"#using-the-ucanaccess-lucee-extension","Using the UCanAccess Lucee Extension",[22,65,66],{},[25,67,69],{"href":68},"#connecting-to-ms-access-the-hard-way","Connecting To MS Access the Hard Way",[22,71,72],{},[25,73,75],{"href":74},"#conclusion","Conclusion",[14,77,33],{"id":78},"querying-an-access-file-from-cfml",[10,80,81],{},"At work last week, I had need to migrate data from a Microsoft Access database file (ugh!) to a more \"desireable\" platform. I haven't used Microsoft Access since I was in high school, and since I don't even have Microsoft Office installed on my development machine I needed a way to connect to this database from CFML.",[10,83,84,85,91,92,97],{},"A few Google searches led me to ",[25,86,90],{"href":87,"rel":88},"http:\u002F\u002Fucanaccess.sourceforge.net\u002Fsite.html",[89],"nofollow","UCanAccess",", a JDBC driver for Microsoft Access built on ",[25,93,96],{"href":94,"rel":95},"https:\u002F\u002Fjackcess.sourceforge.io\u002F",[89],"Jackcess",". The documentation was easy enough to follow, though I confused myself with the wrong jar's class path, and soon I had a working connection to the database file.",[14,99,39],{"id":100},"jdbc-is-awesome",[10,102,103,104,108,109,113],{},"Turns out JDBC is pretty awesome! I think it's cool that I can run standard ANSI SQL (some of which Access doesn't natively support) on a proprietary database file for a Microsoft program which ",[105,106,107],"em",{},"isn't even installed on my system",". And all of it is the ",[110,111,112],"strong",{},"exact same developer experience"," as if I was using MySQL or MSSQL. (Minus perhaps a performance hit.)",[10,115,116],{},"But I digress. After I was done with the data import, I decided to wrap up the UCanAccess jars into a Lucee extension. Why?",[14,118,45],{"id":119},"why-a-lucee-extension",[10,121,122,123,127,128,131,132,135],{},"It's pretty simple: Lucee extensions allow you to add new CFML features, administrator UI, or java libraries in an easy plug-and-play process. No more downloading ",[124,125,126],"code",{},".zip"," files or copying ",[124,129,130],{},".jar"," files into your codebase. A Lucee extension is an ",[110,133,134],{},"especially"," easy setup in the case of a JDBC driver, because all we need to do is deliver a handful of jars to the Lucee engine and instruct Lucee to recognize them collectively as a JDBC driver.",[14,137,51],{"id":138},"creating-the-lucee-extension",[10,140,141,142,149],{},"I started by downloading Julian Halliwell's ",[25,143,146],{"href":144,"rel":145},"https:\u002F\u002Fgithub.com\u002Fcfsimplicity\u002Flucee-mariadb",[89],[124,147,148],{},"lucee-mariadb"," extension as a base. (Thanks, Julian!) After some adjustments, my repository looked like this:",[19,151,152,158,164,173],{},[22,153,154,157],{},[124,155,156],{},"extension\u002F"," - Houses the Lucee extension source code.",[22,159,160,163],{},[124,161,162],{},"box.json"," - Places the extension on Forgebox.io and defines scripts for building and releasing the extension to Forgebox.",[22,165,166,169,170,172],{},[124,167,168],{},"buildExtension.cfc"," - Generates a new .zip and .lex file whenever the extension version changes in ",[124,171,162],{},".",[22,174,175,178],{},[124,176,177],{},"README.md"," - Proper documentation is essential!",[10,180,181,182,184],{},"The contents of the ",[124,183,156],{}," folder look like this:",[19,186,187,214,220],{},[22,188,189,192],{},[124,190,191],{},"context\u002F",[19,193,194],{},[22,195,196,199],{},[124,197,198],{},"admin\u002F",[19,200,201],{},[22,202,203,206],{},[124,204,205],{},"dbdriver\u002F",[19,207,208],{},[22,209,210,213],{},[124,211,212],{},"UCanAccess.cfc"," - Adds ability for admin users to create a UCanAccess datasource in the Lucee Admin.",[22,215,216,219],{},[124,217,218],{},"jars\u002F"," - house any jar files which need to be loaded into Lucee.",[22,221,222,225],{},[124,223,224],{},"META-INF\u002F",[19,226,227,233],{},[22,228,229,232],{},[124,230,231],{},"logo.png"," - The logo is shown when browsing extensions in the Lucee Admin.",[22,234,235,238],{},[124,236,237],{},"MANIFEST.MF"," - Manifest file defines Lucee extension configuration.",[10,240,241,242,244,245,250],{},"I modified the ",[124,243,237],{}," file to specify the extension name and a few JDBC settings. I followed the ",[25,246,249],{"href":247,"rel":248},"https:\u002F\u002Fdocs.lucee.org\u002Fguides\u002Flucee-5\u002Fextensions.html",[89],"\"Extensions in Lucee 5\""," documentation on this, which was a huge help all throughout this process.",[252,253,258],"pre",{"className":254,"code":256,"language":257},[255],"language-text","Manifest-Version: 1.0\nBuilt-Date: 2019-07-11 09:00:00\nversion: \"0.0.1\"\nid: \"007CA05C-E789-4769-A8B8C266E5675F7A\"\nname: \"UCanAccess\"\ndescription: \"JDBC Driver for the MS Access database.\"\ncategory: \"Datasource\"\nlucee-core-version: \"5.0.0.019\"\nstart-bundles: false\njdbc: \"[{'label':'UCanAccess','id':'ucanaccess','connectionString':'jdbc:ucanaccess:\u002F\u002F\u002F{file}','class':'net.ucanaccess.jdbc.UcanaccessDriver'}]\"\n","text",[124,259,256],{"__ignoreMap":260},"",[10,262,263,264,266,267,270],{},"Next I placed the UCanAccess ",[124,265,130],{}," file and its four dependency jars in the ",[124,268,269],{},"jar\u002F"," folder.",[10,272,273,274,277,278,280],{},"Next I renamed the ",[124,275,276],{},"context\u002Fadmin\u002Fdbdriver\u002FMariaDB.cfc"," file to ",[124,279,212],{}," and modified it to replace any mention of MariaDB with UCanAccess. I'm not even certain what this file is for, but I think it's probably configuring the extension as a \"proper\" JDBC driver and adding the ability to create a UCanAccess datasource from the Lucee admin UI.",[10,282,283],{},[105,284,285,288,289,291,292,297],{},[110,286,287],{},"Note:"," I haven't tested this datasource UI yet. I've got a feeling I'll need to update my ",[124,290,212],{}," dbdriver file to replace the MariaDB connection properties with ",[25,293,296],{"href":294,"rel":295},"http:\u002F\u002Fucanaccess.sourceforge.net\u002Fsite.html#examples",[89],"UCanAccess connection properties",". Makes sense, I just haven't gotten there yet.",[10,299,300,301,304,305,307,308,311,312,315],{},"At this point, the extension was \"done\". Simply creating a zip file of the ",[124,302,303],{},"extension"," folder and uploading it into the Lucee Admin is all that is needed to install the extension. We could also create a ",[124,306,126],{}," file, change the file extension to ",[124,309,310],{},".lex",", and drop it in the Lucee context's ",[124,313,314],{},"deploy\u002F"," folder",[14,317,57],{"id":318},"packaging-a-lucee-extension-with-commandbox-and-forgebox",[10,320,321,322,324,325,327,328,330],{},"The tricky part of creating this extension was packaging it. I created a CommandBox task named ",[124,323,168],{}," which creates the ",[124,326,126],{}," and ",[124,329,310],{}," files for Lucee consumption and commits the files to the repository.",[252,332,336],{"className":333,"code":334,"language":335,"meta":260,"style":260},"language-js shiki shiki-themes github-light github-dark","component {\n\n    function run() {\n        generateZips();\n        commitUpdates()\n    }\n\n    function generateZips() {\n        cfzip( action=\"zip\", source=\"extension\", file=\"lucee-ucanaccess.zip\", overwrite=\"true\" ) {}\n        cfzip( action=\"zip\", source=\"extension\", file=\"lucee-ucanaccess.lex\", overwrite=\"true\" ) {}\n\n        print.line( \"Generated lucee-ucanaccess.zip and lucee-ucanaccess.lex\" );\n    }\n\n    function commitUpdates(){\n        var gitStatus = command( '!git' )\n            .params( 'status' )\n            .run( returnOutput=true );\n        \n        \u002F\u002F git add will error (thus halting the release) if these files are unchanged.\n        \u002F\u002F So only proceed if `git status` says there are changed files. :)\n        if ( gitStatus DOES NOT CONTAIN \"lucee-ucanaccess\" ) {\n            print.redLine( \"Nothing new to release\" );\n            return;\n        }\n\n        command( '!git' )\n            .params( 'add lucee-ucanaccess.*' )\n            .run();\n\n        command( '!git' )\n            .params( 'add lucee-ucanaccess.zip' )\n            .run();\n        \n        command( '!git' )\n            .params( 'commit -m \"Add new release .lex and .zip\"' )\n            .run();\n        \n        print.greenLine( \"New release with .lex and .zip\" );\n    }\n}\n","js",[124,337,338,347,354,368,377,386,392,397,407,450,482,487,504,509,514,525,547,563,582,588,595,601,625,641,650,656,661,673,687,696,701,712,726,735,740,751,765,774,779,794,799],{"__ignoreMap":260},[339,340,343],"span",{"class":341,"line":342},"line",1,[339,344,346],{"class":345},"sVt8B","component {\n",[339,348,350],{"class":341,"line":349},2,[339,351,353],{"emptyLinePlaceholder":352},true,"\n",[339,355,357,361,365],{"class":341,"line":356},3,[339,358,360],{"class":359},"szBVR","    function",[339,362,364],{"class":363},"sScJk"," run",[339,366,367],{"class":345},"() {\n",[339,369,371,374],{"class":341,"line":370},4,[339,372,373],{"class":363},"        generateZips",[339,375,376],{"class":345},"();\n",[339,378,380,383],{"class":341,"line":379},5,[339,381,382],{"class":363},"        commitUpdates",[339,384,385],{"class":345},"()\n",[339,387,389],{"class":341,"line":388},6,[339,390,391],{"class":345},"    }\n",[339,393,395],{"class":341,"line":394},7,[339,396,353],{"emptyLinePlaceholder":352},[339,398,400,402,405],{"class":341,"line":399},8,[339,401,360],{"class":359},[339,403,404],{"class":363}," generateZips",[339,406,367],{"class":345},[339,408,410,413,416,419,423,426,428,431,434,436,439,442,444,447],{"class":341,"line":409},9,[339,411,412],{"class":363},"        cfzip",[339,414,415],{"class":345},"( action",[339,417,418],{"class":359},"=",[339,420,422],{"class":421},"sZZnC","\"zip\"",[339,424,425],{"class":345},", source",[339,427,418],{"class":359},[339,429,430],{"class":421},"\"extension\"",[339,432,433],{"class":345},", file",[339,435,418],{"class":359},[339,437,438],{"class":421},"\"lucee-ucanaccess.zip\"",[339,440,441],{"class":345},", overwrite",[339,443,418],{"class":359},[339,445,446],{"class":421},"\"true\"",[339,448,449],{"class":345}," ) {}\n",[339,451,453,455,457,459,461,463,465,467,469,471,474,476,478,480],{"class":341,"line":452},10,[339,454,412],{"class":363},[339,456,415],{"class":345},[339,458,418],{"class":359},[339,460,422],{"class":421},[339,462,425],{"class":345},[339,464,418],{"class":359},[339,466,430],{"class":421},[339,468,433],{"class":345},[339,470,418],{"class":359},[339,472,473],{"class":421},"\"lucee-ucanaccess.lex\"",[339,475,441],{"class":345},[339,477,418],{"class":359},[339,479,446],{"class":421},[339,481,449],{"class":345},[339,483,485],{"class":341,"line":484},11,[339,486,353],{"emptyLinePlaceholder":352},[339,488,490,493,495,498,501],{"class":341,"line":489},12,[339,491,492],{"class":345},"        print.",[339,494,341],{"class":363},[339,496,497],{"class":345},"( ",[339,499,500],{"class":421},"\"Generated lucee-ucanaccess.zip and lucee-ucanaccess.lex\"",[339,502,503],{"class":345}," );\n",[339,505,507],{"class":341,"line":506},13,[339,508,391],{"class":345},[339,510,512],{"class":341,"line":511},14,[339,513,353],{"emptyLinePlaceholder":352},[339,515,517,519,522],{"class":341,"line":516},15,[339,518,360],{"class":359},[339,520,521],{"class":363}," commitUpdates",[339,523,524],{"class":345},"(){\n",[339,526,528,531,534,536,539,541,544],{"class":341,"line":527},16,[339,529,530],{"class":359},"        var",[339,532,533],{"class":345}," gitStatus ",[339,535,418],{"class":359},[339,537,538],{"class":363}," command",[339,540,497],{"class":345},[339,542,543],{"class":421},"'!git'",[339,545,546],{"class":345}," )\n",[339,548,550,553,556,558,561],{"class":341,"line":549},17,[339,551,552],{"class":345},"            .",[339,554,555],{"class":363},"params",[339,557,497],{"class":345},[339,559,560],{"class":421},"'status'",[339,562,546],{"class":345},[339,564,566,568,571,574,576,580],{"class":341,"line":565},18,[339,567,552],{"class":345},[339,569,570],{"class":363},"run",[339,572,573],{"class":345},"( returnOutput",[339,575,418],{"class":359},[339,577,579],{"class":578},"sj4cs","true",[339,581,503],{"class":345},[339,583,585],{"class":341,"line":584},19,[339,586,587],{"class":345},"        \n",[339,589,591],{"class":341,"line":590},20,[339,592,594],{"class":593},"sJ8bj","        \u002F\u002F git add will error (thus halting the release) if these files are unchanged.\n",[339,596,598],{"class":341,"line":597},21,[339,599,600],{"class":593},"        \u002F\u002F So only proceed if `git status` says there are changed files. :)\n",[339,602,604,607,610,613,616,619,622],{"class":341,"line":603},22,[339,605,606],{"class":359},"        if",[339,608,609],{"class":345}," ( gitStatus ",[339,611,612],{"class":578},"DOES",[339,614,615],{"class":578}," NOT",[339,617,618],{"class":578}," CONTAIN",[339,620,621],{"class":421}," \"lucee-ucanaccess\"",[339,623,624],{"class":345}," ) {\n",[339,626,628,631,634,636,639],{"class":341,"line":627},23,[339,629,630],{"class":345},"            print.",[339,632,633],{"class":363},"redLine",[339,635,497],{"class":345},[339,637,638],{"class":421},"\"Nothing new to release\"",[339,640,503],{"class":345},[339,642,644,647],{"class":341,"line":643},24,[339,645,646],{"class":359},"            return",[339,648,649],{"class":345},";\n",[339,651,653],{"class":341,"line":652},25,[339,654,655],{"class":345},"        }\n",[339,657,659],{"class":341,"line":658},26,[339,660,353],{"emptyLinePlaceholder":352},[339,662,664,667,669,671],{"class":341,"line":663},27,[339,665,666],{"class":363},"        command",[339,668,497],{"class":345},[339,670,543],{"class":421},[339,672,546],{"class":345},[339,674,676,678,680,682,685],{"class":341,"line":675},28,[339,677,552],{"class":345},[339,679,555],{"class":363},[339,681,497],{"class":345},[339,683,684],{"class":421},"'add lucee-ucanaccess.*'",[339,686,546],{"class":345},[339,688,690,692,694],{"class":341,"line":689},29,[339,691,552],{"class":345},[339,693,570],{"class":363},[339,695,376],{"class":345},[339,697,699],{"class":341,"line":698},30,[339,700,353],{"emptyLinePlaceholder":352},[339,702,704,706,708,710],{"class":341,"line":703},31,[339,705,666],{"class":363},[339,707,497],{"class":345},[339,709,543],{"class":421},[339,711,546],{"class":345},[339,713,715,717,719,721,724],{"class":341,"line":714},32,[339,716,552],{"class":345},[339,718,555],{"class":363},[339,720,497],{"class":345},[339,722,723],{"class":421},"'add lucee-ucanaccess.zip'",[339,725,546],{"class":345},[339,727,729,731,733],{"class":341,"line":728},33,[339,730,552],{"class":345},[339,732,570],{"class":363},[339,734,376],{"class":345},[339,736,738],{"class":341,"line":737},34,[339,739,587],{"class":345},[339,741,743,745,747,749],{"class":341,"line":742},35,[339,744,666],{"class":363},[339,746,497],{"class":345},[339,748,543],{"class":421},[339,750,546],{"class":345},[339,752,754,756,758,760,763],{"class":341,"line":753},36,[339,755,552],{"class":345},[339,757,555],{"class":363},[339,759,497],{"class":345},[339,761,762],{"class":421},"'commit -m \"Add new release .lex and .zip\"'",[339,764,546],{"class":345},[339,766,768,770,772],{"class":341,"line":767},37,[339,769,552],{"class":345},[339,771,570],{"class":363},[339,773,376],{"class":345},[339,775,777],{"class":341,"line":776},38,[339,778,587],{"class":345},[339,780,782,784,787,789,792],{"class":341,"line":781},39,[339,783,492],{"class":345},[339,785,786],{"class":363},"greenLine",[339,788,497],{"class":345},[339,790,791],{"class":421},"\"New release with .lex and .zip\"",[339,793,503],{"class":345},[339,795,797],{"class":341,"line":796},40,[339,798,391],{"class":345},[339,800,802],{"class":341,"line":801},41,[339,803,804],{"class":345},"}\n",[10,806,807,808,811,812,815,816,818],{},"I tested that the task works by running ",[124,809,810],{},"task run buildExtension"," from CommandBox. Once I had that working, I added the following ",[124,813,814],{},"scripts"," to my ",[124,817,162],{},":",[252,820,822],{"className":333,"code":821,"language":335,"meta":260,"style":260},"\"scripts\":{\n    \"postVersion\":\"package set location='https:\u002F\u002Fbitbucket.org\u002Fmichaelborn_me\u002Fucanaccess\u002Fsrc\u002Fv`package version`\u002Flucee-ucanaccess.zip'\",\n    \"onRelease\":\"task run buildExtension && publish\",\n    \"postPublish\":\"!git push --follow-tags\"\n}\n",[124,823,824,832,845,857,867],{"__ignoreMap":260},[339,825,826,829],{"class":341,"line":342},[339,827,828],{"class":421},"\"scripts\"",[339,830,831],{"class":345},":{\n",[339,833,834,837,839,842],{"class":341,"line":349},[339,835,836],{"class":421},"    \"postVersion\"",[339,838,818],{"class":345},[339,840,841],{"class":421},"\"package set location='https:\u002F\u002Fbitbucket.org\u002Fmichaelborn_me\u002Fucanaccess\u002Fsrc\u002Fv`package version`\u002Flucee-ucanaccess.zip'\"",[339,843,844],{"class":345},",\n",[339,846,847,850,852,855],{"class":341,"line":356},[339,848,849],{"class":421},"    \"onRelease\"",[339,851,818],{"class":345},[339,853,854],{"class":421},"\"task run buildExtension && publish\"",[339,856,844],{"class":345},[339,858,859,862,864],{"class":341,"line":370},[339,860,861],{"class":421},"    \"postPublish\"",[339,863,818],{"class":345},[339,865,866],{"class":421},"\"!git push --follow-tags\"\n",[339,868,869],{"class":341,"line":379},[339,870,804],{"class":345},[10,872,873,874,879,880,883,884,889],{},"Aside: I acquired these package scripts from Brad Wood after he mentioned them in the ",[25,875,878],{"href":876,"rel":877},"http:\u002F\u002Fcfml-slack.herokuapp.com\u002F",[89],"CFML slack",". (",[105,881,882],{},"Reason #999 for following Brad Wood very closely in Slack...",") They're also documented in the ",[25,885,888],{"href":886,"rel":887},"https:\u002F\u002Fcommandbox.ortusbooks.com\u002Fpackage-management\u002Fpackage-scripts",[89],"CommandBox Package Scripts",". I include some variant of these scripts in every package I write, because they make publishing new Forgebox releases super easy and consistent.",[10,891,892,893,896,897,900,901,904,905,904,908,911,912,915],{},"These scripts automate the Forgebox release process by using the ",[124,894,895],{},"package version"," or ",[124,898,899],{},"bump"," commands in CommandBox. I can run ",[124,902,903],{},"bump --major",", ",[124,906,907],{},"bump --minor",[124,909,910],{},"bump --patch",", or even ",[124,913,914],{},"package version 0.7.2"," in CommandBox and CommandBox will:",[917,918,919,922,929,951],"ol",{},[22,920,921],{},"create and commit a git tag referencing the new version number",[22,923,924,925,928],{},"run my ",[124,926,927],{},"postVersion"," script to set the download URL",[22,930,924,931,934,935],{},[124,932,933],{},"onRelease"," script to\n",[917,936,937,948],{},[22,938,939,940,942,943,327,945,947],{},"compress the ",[124,941,156],{}," folder into installable ",[124,944,126],{},[124,946,310],{}," files, and",[22,949,950],{},"publish the new release",[22,952,953],{},"push up any code changes, including my new git tag version number.",[10,955,956,957,959],{},"Just like that, I ran ",[124,958,907],{}," and my new Lucee Extension zoomed off to ForgeBox!",[14,961,63],{"id":962},"using-the-ucanaccess-lucee-extension",[10,964,965],{},"Three easy steps to installing the extension:",[917,967,968,974,977],{},[22,969,970,971],{},"Add a new Extension Provider in your Lucee Server admin pointing to ",[124,972,973],{},"https:\u002F\u002Fforgebox.io",[22,975,976],{},"Find the \"UCanAccess\" extension in the \"Not installed\" section",[22,978,979],{},"Click the extension and click \"Install\"",[10,981,982,983,818],{},"I've admitted earlier in this blog post that I haven't tested datasource creation from the Lucee Admin yet. Until I get that working, the easiest way to create a UCanAccess datasource is manually in your ",[124,984,985],{},"Application.cfc",[252,987,989],{"className":333,"code":988,"language":335,"meta":260,"style":260},"msAccessDB = {\n   class: \"net.ucanaccess.jdbc.UcanaccessDriver\",\n   connectionString: \"jdbc:ucanaccess:\u002F\u002FC:\\Users\\me\\my\\FILENAME.accdb\"\n};\n",[124,990,991,1001,1011,1042],{"__ignoreMap":260},[339,992,993,996,998],{"class":341,"line":342},[339,994,995],{"class":345},"msAccessDB ",[339,997,418],{"class":359},[339,999,1000],{"class":345}," {\n",[339,1002,1003,1006,1009],{"class":341,"line":349},[339,1004,1005],{"class":345},"   class: ",[339,1007,1008],{"class":421},"\"net.ucanaccess.jdbc.UcanaccessDriver\"",[339,1010,844],{"class":345},[339,1012,1013,1016,1019,1022,1025,1028,1031,1033,1036,1039],{"class":341,"line":356},[339,1014,1015],{"class":345},"   connectionString: ",[339,1017,1018],{"class":421},"\"jdbc:ucanaccess:\u002F\u002FC:",[339,1020,1021],{"class":578},"\\U",[339,1023,1024],{"class":421},"sers",[339,1026,1027],{"class":578},"\\m",[339,1029,1030],{"class":421},"e",[339,1032,1027],{"class":578},[339,1034,1035],{"class":421},"y",[339,1037,1038],{"class":578},"\\F",[339,1040,1041],{"class":421},"ILENAME.accdb\"\n",[339,1043,1044],{"class":341,"line":370},[339,1045,1046],{"class":345},"};\n",[10,1048,1049],{},"Once you do that, you should be able to use the datasource to connect to an MS Access database file and run queries:",[252,1051,1053],{"className":333,"code":1052,"language":335,"meta":260,"style":260},"var query = queryExecute( \"SELECT COUNT(*) FROM pages\", {}, { datasource: \"msAccessDB\" } );\n",[124,1054,1055],{"__ignoreMap":260},[339,1056,1057,1060,1063,1065,1068,1070,1073,1076,1079],{"class":341,"line":342},[339,1058,1059],{"class":359},"var",[339,1061,1062],{"class":345}," query ",[339,1064,418],{"class":359},[339,1066,1067],{"class":363}," queryExecute",[339,1069,497],{"class":345},[339,1071,1072],{"class":421},"\"SELECT COUNT(*) FROM pages\"",[339,1074,1075],{"class":345},", {}, { datasource: ",[339,1077,1078],{"class":421},"\"msAccessDB\"",[339,1080,1081],{"class":345}," } );\n",[10,1083,1084],{},"And just like that, you are benefiting from the power of JDBC and Lucee Extensions. (And UCanAccess. And Jackcess. And myself, of course!)",[14,1086,69],{"id":1087},"connecting-to-ms-access-the-hard-way",[10,1089,1090,1091,1094],{},"If you want to ignore all my hard work and do this the ",[110,1092,1093],{},"hard way"," (perhaps you are on Adobe ColdFusion?), you can follow this process to connect to an MS Access database:",[917,1096,1097,1105,1146,1156],{},[22,1098,1099,1100],{},"Download and extract ",[25,1101,1104],{"href":1102,"rel":1103},"https:\u002F\u002Fsourceforge.net\u002Fprojects\u002Fucanaccess\u002Ffiles\u002Flatest\u002Fdownload",[89],"the UCanAccess .zip file",[22,1106,1107,1108,1111,1112,1114,1115,1118,1119],{},"Navigate to ",[124,1109,1110],{},"UCanAccess-{version}.bin\u002F",", and copy these five ",[124,1113,130],{}," files to your project ",[124,1116,1117],{},"lib\u002F"," folder:\n",[917,1120,1121,1126,1131,1136,1141],{},[22,1122,1123],{},[124,1124,1125],{},"ucanaccess-{version}.jar",[22,1127,1128],{},[124,1129,1130],{},"lib\u002Fcommons-lang-{version}.jar",[22,1132,1133],{},[124,1134,1135],{},"lib\u002Fcommons-logging-{version}.jar",[22,1137,1138],{},[124,1139,1140],{},"lib\u002Fhsqldb.jar",[22,1142,1143],{},[124,1144,1145],{},"lib\u002Fjackcess-2.1.11.jar",[22,1147,1148,1149,1151,1152,1155],{},"In ",[124,1150,985],{},", set ",[124,1153,1154],{},"this.javaSettings.loadPaths = [ \".\u002Flib\u002F\" ];"," to instruct Lucee or ACF to load up the jar files",[22,1157,1148,1158,1160,1161],{},[124,1159,985],{}," (Lucee) or the Adobe CF Administrator, add a datasource with the following two properties:\n",[917,1162,1163,1169],{},[22,1164,1165,1166],{},"References the class path as ",[124,1167,1168],{},"net.ucanaccess.jdbc.UcanaccessDriver",[22,1170,1171,1172,1175],{},"Set a connection string starting with ",[124,1173,1174],{},"jdbc:ucanaccess:\u002F\u002F"," and ending with the full path to your MS Access database file.",[10,1177,1178,1179,1182],{},"Now be warned, I'm not certain this works at all in Adobe CF. It has been a few years since I've use the ACF Admin to create a datasource, and it ",[105,1180,1181],{},"may not"," support custom JDBC connection strings and class paths - I don't know! Feel free to educate me on this - I'll happily update this blog article.",[10,1184,1185,1186,1188],{},"In Lucee you can drop a datasource struct into your ",[124,1187,985],{}," which looks like this:",[252,1190,1191],{"className":333,"code":988,"language":335,"meta":260,"style":260},[124,1192,1193,1201,1209,1231],{"__ignoreMap":260},[339,1194,1195,1197,1199],{"class":341,"line":342},[339,1196,995],{"class":345},[339,1198,418],{"class":359},[339,1200,1000],{"class":345},[339,1202,1203,1205,1207],{"class":341,"line":349},[339,1204,1005],{"class":345},[339,1206,1008],{"class":421},[339,1208,844],{"class":345},[339,1210,1211,1213,1215,1217,1219,1221,1223,1225,1227,1229],{"class":341,"line":356},[339,1212,1015],{"class":345},[339,1214,1018],{"class":421},[339,1216,1021],{"class":578},[339,1218,1024],{"class":421},[339,1220,1027],{"class":578},[339,1222,1030],{"class":421},[339,1224,1027],{"class":578},[339,1226,1035],{"class":421},[339,1228,1038],{"class":578},[339,1230,1041],{"class":421},[339,1232,1233],{"class":341,"line":370},[339,1234,1046],{"class":345},[14,1236,75],{"id":1237},"conclusion",[19,1239,1240,1243,1246],{},[22,1241,1242],{},"Java libraries are awesome, and being able to use them from CFML is awesome.",[22,1244,1245],{},"Big shoutout to UCanAccess and Jackcess.",[22,1247,1248],{},"Lucee Extensions are actually pretty easy, at least for packaging jars.",[10,1250,1251],{},"Thanks for reading!",[1253,1254,1255],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":260,"searchDepth":349,"depth":349,"links":1257},[1258,1259,1260,1261,1262,1263,1264,1265,1266],{"id":16,"depth":349,"text":17},{"id":78,"depth":349,"text":33},{"id":100,"depth":349,"text":39},{"id":119,"depth":349,"text":45},{"id":138,"depth":349,"text":51},{"id":318,"depth":349,"text":57},{"id":962,"depth":349,"text":63},{"id":1087,"depth":349,"text":69},{"id":1237,"depth":349,"text":75},"2019-07-15T16:13:57-04:00",false,"md",{},"\u002Fposts\u002Faccess-lucee-extension",{"title":5,"description":12},"posts\u002Faccess-lucee-extension",[1275,1276,1277,1278],"coldfusion","lucee","cfml","jdbc","cDrxRxTPXP5NgANmXTO4lr35BkuqD0DKBarqj5_qkQA",1790471527790]