|
<cfparam name="form.query" default=""> |
|
<cfparam name="form.ajax" default=""> |
|
<cfparam name="form.datasource" default=""> |
|
|
|
<cfif cgi.REMOTE_ADDR NEQ '127.0.0.1'> |
|
<cfheader statuscode="401" statustext="Unauthorized"/> |
|
<cfoutput>not authorized</cfoutput> |
|
<cfabort /> |
|
</cfif> |
|
|
|
<cfif form.ajax EQ true> |
|
<cfset result = {}> |
|
<cfset result['body'] = ''> |
|
<cfset result['jsonbody'] = '{}'> |
|
|
|
<cfsetting showdebugoutput="false"> |
|
|
|
<cfset queryFile = '<cfquery datasource="#form.datasource#" name="poop" maxrows="10">#deserializeJSON(form.query).query#</cfquery>'> |
|
|
|
<cftry> |
|
<cffile action="write" file="#GetDirectoryFromPath(getCurrentTemplatePath())#cfquery2013.cfm" output="#queryFile#"> |
|
|
|
<cfinclude template="cfquery2013.cfm"> |
|
|
|
<cffile action="delete" file="#GetDirectoryFromPath(getCurrentTemplatePath())#cfquery2013.cfm"> |
|
|
|
<cfsavecontent variable="bodypoop"> |
|
<cfoutput><cfdump var="#poop#" label="Result"></cfoutput> |
|
</cfsavecontent> |
|
<cfset result['jsonbody'] = []> |
|
<cfloop query="poop"> |
|
<cfset tmp = {}> |
|
<cfloop list="#poop.columnlist#" index="field"> |
|
<cfset tmp[field] = poop[field][poop.currentRow]> |
|
</cfloop> |
|
<cfset arrayAppend(result['jsonbody'], duplicate(tmp))> |
|
</cfloop> |
|
|
|
<cfset result['jsonbody'] = serializeJSON(result['jsonbody'])> |
|
|
|
<cfcatch> |
|
<cffile action="delete" file="#GetDirectoryFromPath(getCurrentTemplatePath())#cfquery2013.cfm"> |
|
<cfsavecontent variable="bodypoop"> |
|
<cfoutput><cfdump var="#cfcatch#" format="html"></cfoutput> |
|
</cfsavecontent> |
|
</cfcatch> |
|
</cftry> |
|
|
|
<cfset result['body'] = bodypoop> |
|
|
|
<cfheader name="Content-Type" value="application/json"> |
|
<cfoutput>#serializeJSON(result)#</cfoutput> |
|
<cfabort /> |
|
</cfif> |
|
|
|
|
|
<cfoutput><!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<title>CF Query</title> |
|
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"> |
|
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css"> |
|
<link rel="stylesheet" href="http://blog.yesmeck.com/jquery-jsonview/stylesheets/jquery.jsonview.css" type="text/css" media="screen" title="no title" charset="utf-8"> |
|
|
|
</head> |
|
<body> |
|
<div class="" style="margin: 0 15px"> |
|
<div class="row"> |
|
<div class="col-md-12 page-header"><h1>Query Oracle</h1></div> |
|
</div> |
|
<div class="row"> |
|
<div class="col-md-10"><textarea class="form-control query" rows="3"></textarea></div> |
|
<div class="col-md-2"> |
|
<div class="btn-group"> |
|
<button type="button" class="btn btn-default" data-toggle="modal" data-target="##prevModal">History</button> |
|
<div class="btn-group"> |
|
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> |
|
<span class="datasource">Dropdown</span> |
|
<span class="caret"></span> |
|
</button> |
|
<ul class="dropdown-menu datasources"> |
|
</ul> |
|
</div> |
|
</div> |
|
<br> |
|
<div class="btn-group"> |
|
<button type="button" class="btn btn-primary do-query">Query</button> |
|
<button type="button" class="btn btn-default add-datasource">Add Datasource</button> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="row"> |
|
<div class="col-md-12"><hr></div> |
|
</div> |
|
<div class="row"> |
|
<div class="col-md-12 query-result"></div> |
|
</div> |
|
<div class="row"> |
|
<div class="col-md-12"><hr></div> |
|
</div> |
|
<div class="row"> |
|
<div class="col-md-12 query-json-result"></div> |
|
</div> |
|
</div> |
|
|
|
<div class="modal fade" id="prevModal" tabindex="-1" role="dialog" aria-hidden="true"> |
|
<div class="modal-dialog"> |
|
<div class="modal-content"> |
|
<div class="modal-body"> |
|
<div class="list-group prev-queries"> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script src="//code.jquery.com/jquery-1.10.1.min.js"></script> |
|
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> |
|
<script src="http://blog.yesmeck.com/jquery-jsonview/javascripts/jquery.jsonview.js" type="text/javascript"></script> |
|
|
|
<script> |
|
(function ($) { |
|
var $modal = $('##prevModal'), |
|
$prevQueries = $('.prev-queries'), |
|
$query = $('textarea.query'), |
|
$queryResult = $('.query-result'), |
|
$queryJSONResult = $('.query-json-result'), |
|
$datasource = $('.datasource'); |
|
|
|
function doQuery(callback) { |
|
var query = $query.val(); |
|
|
|
saveToHistory(query); |
|
|
|
$queryResult.html('<div class="alert alert-info">Loading...</div>'); |
|
$queryJSONResult.html(''); |
|
|
|
$.ajax({ |
|
method: 'post', |
|
data: { |
|
ajax: true, |
|
query: JSON.stringify({query:query}), |
|
datasource: $datasource.text() |
|
} |
|
}).done(function (data, textStatus, jqXHR) { |
|
$queryResult.html(data.body); |
|
$queryJSONResult.JSONView(data.jsonbody || {}); |
|
}).fail(function (jqXHR, textStatus, errorThrown) { |
|
$queryResult.html('<div class="alert alert-danger"><strong>Error</strong> '+ errorThrown +'</div>'); |
|
}); |
|
} |
|
|
|
function saveToHistory(query) { |
|
var rerun = false, |
|
latestQuery = $prevQueries.find('a').first(); |
|
|
|
if (query.length < 1) { |
|
return false; |
|
} |
|
|
|
if (latestQuery.length && latestQuery.find('.query').text() == query) { |
|
if (latestQuery.find('.badge').length) { |
|
latestQuery.find('.badge').text(1 * latestQuery.find('.badge').text() + 1); |
|
} else { |
|
latestQuery.prepend('<span class="badge">2</span>'); |
|
} |
|
} else { |
|
$prevQueries.prepend('<a href="##" class="list-group-item prev-item"><span class="query"></span></a>'); |
|
$prevQueries.find('a').first().find('.query').text(query); |
|
} |
|
|
|
while ($prevQueries.length > 100) { |
|
$prevQueries.last().remove(); |
|
} |
|
|
|
localStorage['query.prevqueries'] = $prevQueries.html(); |
|
} |
|
|
|
function loadHistory() { |
|
if (!localStorage['query.prevqueries']) { |
|
return false; |
|
} |
|
$prevQueries.html(localStorage['query.prevqueries']); |
|
} |
|
|
|
$(function () { |
|
$(document).on('click', '.prev-item', function () { |
|
$modal.modal('hide'); |
|
$query.val($(this).find('.query').text()); |
|
return false; |
|
}) |
|
.on('click', '.btn.do-query', function (e) { |
|
e.preventDefault(); |
|
doQuery(function () { |
|
//something |
|
}); |
|
}) |
|
.on('storage', window, function (e) { |
|
console.log('localstorage changed', e); |
|
}) |
|
.on('click', '.delete-datasource', function (e) { |
|
e.preventDefault(); |
|
e.stopPropagation(); |
|
$(this).parent().parent().remove(); |
|
localStorage['query.datasources'] = $('.datasources').html(); |
|
}) |
|
.on('click', '.datasources a', function (e) { |
|
e.preventDefault(); |
|
$datasource.text($(this).find('.name').text()); |
|
localStorage['query.datasource'] = $datasource.text(); |
|
localStorage['query.datasources'] = $('.datasources').html(); |
|
}) |
|
.on('click', '.add-datasource', function (e) { |
|
e.preventDefault(); |
|
|
|
var dsname = prompt('Datasource name?', ''); |
|
|
|
if (dsname.length > 0) { |
|
$('.datasources').append('<li><a href="##"><button type="button" class="close delete-datasource" aria-hidden="true">×</button><span class="name">' + dsname + '</span></a></li>'); |
|
localStorage['query.datasources'] = $('.datasources').html(); |
|
} |
|
}); |
|
|
|
loadHistory(); |
|
|
|
$datasource.text(localStorage['query.datasource'] || '<none>'); |
|
|
|
if (localStorage['query.datasources']) { |
|
$('.datasources').html(localStorage['query.datasources']); |
|
} |
|
}); |
|
})(jQuery) |
|
</script> |
|
</body> |
|
</html></cfoutput> |