UNPKG

waterline-postgresql

Version:
291 lines (252 loc) 8.31 kB
'use strict'; /* globals describe, it */ var chai = require('chai'), expect = chai.expect; var knex = require('knex')({ dialect: 'postgres' }); // install postgis extension and save a reference in st var st = require('../lib/index.js')(knex); function queryBuilder() { return knex.queryBuilder ? knex.queryBuilder() : knex(); } function verifySqlResult(expectedObj, sqlObj) { Object.keys(expectedObj).forEach(function(key) { expect(sqlObj[key]).to.deep.equal(expectedObj[key]); }); } function testsql(func, res) { var sqlRes = func.toSQL(); if (typeof res === 'string') { verifySqlResult({ sql: res }, sqlRes); } else { verifySqlResult(res, sqlRes); } } describe('Postgis functions', function() { it('alias', function() { testsql(st.asText('geom'), { sql: 'ST_asText("geom") as "geom"', bindings: [] }); testsql(st.asText('geom').as('foo'), { sql: 'ST_asText("geom") as "foo"', bindings: [] }); }); it('select with asText', function() { testsql(queryBuilder().select('id', st.asText('geom')).from('points'), { sql: 'select "id", ST_asText("geom") as "geom" from "points"', bindings: [] }); }); it('select with asEWKT', function() { testsql(queryBuilder().select('id', st.asEWKT('geom')).from('points'), { sql: 'select "id", ST_asEWKT("geom") as "geom" from "points"', bindings: [] }); }); it('select with centroid', function() { testsql(queryBuilder().select('id', st.centroid('geom')).from('points'), { sql: 'select "id", ST_centroid("geom") from "points"', bindings: [] }); }); it('select with centroid and asText', function() { testsql(queryBuilder().select('id', st.asText(st.centroid('geom')).as('centroid')).from('points'), { sql: 'select "id", ST_asText(ST_centroid("geom")) as "centroid" from "points"', bindings: [] }); }); it('select with intersects, argument in ewkt format', function() { testsql( queryBuilder() .select('id', st.asText('geom')) .from('points') .where(st.intersects('geom', 'SRID=4326;Polygon((0 0, 0 1, 1 1, 1 0, 0 0))')), { sql: 'select "id", ST_asText("geom") as "geom" from "points" where ST_intersects("geom", ?)', bindings: ['SRID=4326;Polygon((0 0, 0 1, 1 1, 1 0, 0 0))'] }); }); it('select with intersects, argument using geomFromText function', function() { testsql( queryBuilder() .select('id', st.asText('geom')) .from('points') .where(st.intersects('geom', st.geomFromText('Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326))), { sql: 'select "id", ST_asText("geom") as "geom" from "points" where ST_intersects("geom", ST_geomFromText(?, ?))', bindings: ['Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326] }); }); it('select with intersects, field name is equals to a type defined in WKT', function() { testsql( queryBuilder() .select('id', st.asText('point')) .from('points') .where(st.intersects('point', st.geomFromText('Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326))), { sql: 'select "id", ST_asText("point") as "point" from "points" where ST_intersects("point", ST_geomFromText(?, ?))', bindings: ['Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326] }); }); it('insert with geomFromText', function() { testsql( queryBuilder() .insert({ 'id': 1, 'geom': st.geomFromText('Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326) }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromText(?, ?), ?)', bindings: ['Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326, 1] }); }); it('insert with geomFromText Formato EWKT', function() { testsql( queryBuilder() .insert({ 'id': 1, 'geom': st.geomFromText('SRID=4326;Polygon((0 0, 0 1, 1 1, 1 0, 0 0))') }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromText(?, ?), ?)', bindings: ['Polygon((0 0, 0 1, 1 1, 1 0, 0 0))', 4326, 1] }); }); it('insert with geomFromGeoJSON text', function() { testsql( queryBuilder() .insert({ 'id': 1, 'geom': st.geomFromGeoJSON('{"type":"Point","coordinates":[-48.23456,20.12345]}') }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromGeoJSON(?), ?)', bindings: [{type:'Point', coordinates:[-48.23456, 20.12345]}, 1] }); }); it('insert with geomFromGeoJSON object', function() { testsql( queryBuilder() .insert({ 'id': 1, 'geom': st.geomFromGeoJSON({type:'Point', coordinates:[-48.23456, 20.12345]}) }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromGeoJSON(?), ?)', bindings: [{type:'Point', coordinates:[-48.23456, 20.12345]}, 1] }); }); it('update a geometry column using geomFromGeoJSON text from another column', function() { testsql( queryBuilder() .update({ 'geom': st.geomFromGeoJSON('geoJsonColumn') }) .table('points'), { sql: 'update "points" set "geom" = ST_geomFromGeoJSON("geoJsonColumn")', bindings: [] }); }); it('select with asGeoJSON', function() { testsql(queryBuilder().select('id', st.asGeoJSON('geom')).from('points'), { sql: 'select "id", ST_asGeoJSON("geom") as "geom" from "points"', bindings: [] }); }); it('allow spaces between WKT type and the first parenthesis', function() { testsql( queryBuilder() .insert({ 'id': 1, 'geom': st.geomFromText('Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))', 4326) }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromText(?, ?), ?)', bindings: ['Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))', 4326, 1] }); }); it('prevent sql injection', function() { testsql( queryBuilder() .insert({ id: 1, geom: st.geomFromText("Point(')); DROP TABLE points; SELECT concat(concat(')", 4326) }) .into('points'), { sql: 'insert into "points" ("geom", "id") values (ST_geomFromText("Point(\')); DROP TABLE points; SELECT concat(concat(\')", ?), ?)', bindings: [4326, 1] }); expect( function() { return queryBuilder() .insert({ id: 1, geom: st.geomFromGeoJSON({type: 'Point', coordinates: 'DROP TABLE points;'}) }) .into('points'); } ).to.throw('Invalid GeoJSON'); }); it('prevent sql injection', function() { testsql(queryBuilder() .insert({ id: 1, geom: st.geomFromText("Point(')); DROP TABLE points; SELECT concat(concat(')", 4326) }) .into('points'), 'insert into "points" ("geom", "id") values (ST_geomFromText("Point(\')); DROP TABLE points; SELECT concat(concat(\')", ?), ?)'); expect( function() { return queryBuilder() .insert({ id: 1, geom: st.geomFromGeoJSON({type: 'Point', coordinates: 'DROP TABLE points;'}) }) .into('points'); } ).to.throw('Invalid GeoJSON'); }); }); describe('Postgis extras', function() { it('define extra functions', function() { knex.postgisDefineExtras(function(knex, formatter) { return { utmzone: function(geom) { return knex.raw('utmzone(?)', [formatter.wrapWKT(geom)]); } }; }); testsql( queryBuilder() .select('id', st.utmzone('point') .as('utm')) .from('points'), { sql: 'select "id", utmzone("point") as "utm" from "points"', bindings: [] } ); testsql( queryBuilder() .select('id', st.utmzone(st.geomFromText('Point(0 0, 0 1)', 4326)) .as('utm')) .from('points'), { sql: 'select "id", utmzone(ST_geomFromText(?, ?)) as "utm" from "points"', bindings: ['Point(0 0, 0 1)', 4326] } ); }); });