Compare commits

...

10 Commits

Author SHA1 Message Date
Heiko Mueller 9c7a1b135c SIGMOD Demo Version 2017-05-17 22:33:31 -04:00
Oliver Kennedy cc6be2fbfb MimirAdaptor now converts notebooks 2016-06-25 22:00:50 -07:00
Heiko Mueller 336fe2c554 First version of SQL export 2016-06-25 21:33:56 -07:00
Heiko Mueller b477728974 Merge branch 'master' of gitlab.odin.cse.buffalo.edu:Vizier/demo 2016-06-25 07:49:53 -04:00
Heiko Mueller e48e14db1c Started to add filters 2016-06-25 07:49:40 -04:00
Oliver Kennedy 9a1116c376 Support for SQL generation. 2016-06-25 02:02:04 -07:00
Oliver Kennedy afdf9f7042 Adding Mimir to Vizier Deps 2016-06-24 11:05:16 -07:00
Heiko Mueller d04b767df4 Merge branch 'master' of gitlab.odin.cse.buffalo.edu:Vizier/demo 2016-06-22 17:41:13 -04:00
Heiko Mueller bcacfcc245 First version of cell formulas added 2016-06-22 17:41:01 -04:00
Jacob 3cf01e15b7 Added sort translation. 2016-06-17 22:48:23 -04:00
79 changed files with 3782 additions and 2624 deletions

6
bin/runTest Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
BASE=`dirname $0`/..
CLASSPATH=`echo $BASE/target/vizier-db/WEB-INF/lib/* | tr ' ' ':'`
java -cp $CLASSPATH:$BASE/target/classes:$BASE/target/test-classes org.vizier.test.$1

24
pom.xml
View File

@ -71,9 +71,33 @@
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.parboiled</groupId>
<artifactId>parboiled-java</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>info.mimirdb</groupId>
<artifactId>mimirdb-mimir</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.2</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>Mimir</id>
<name>Mimir Snapshot</name>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<url>http://maven.vizierdb.info/</url>
<layout>default</layout>
</repository>
</repositories>
</project>

View File

@ -13,68 +13,31 @@
*/
package org.vizierdb.database;
import org.vizierdb.util.SpreadsheetHelper;
import org.vizierdb.database.value.Value;
/**
* A cell in a notebook data snapshot. Each cell is identified by the unique
* identifiers of the column and row that contain the cell. For a particular
* snapshot the cell is mapped to a position defined by a mapping that is part
* of the snapshot. Thus, column and row DO NOT identify the position of a cell
* in a snapshot!
* A cell in a notebook data snapshot. Extends a {@link CellCoordinates} with
* a cell value.
*
* @author Heiko Mueller
*/
public class Cell {
public class Cell extends CellCoordinates {
private final int _col;
private final int _row;
private final String _value;
private final Value _value;
public Cell(int col, int row, String value) {
public Cell(int columnId, int rowId, Value value) {
super(columnId, rowId);
_col = col;
_row = row;
_value = value;
}
/**
* Identifier of the column that contains the cell.
*
* @return
*/
public int getColumnId() {
return _col;
}
/**
* The column identifier is a concatenation of the column identifier
* (transformed into spreadsheet column name notation) and row the
* identifier.
*
* @return
*/
public String getIdentifier() {
return SpreadsheetHelper.getColumnName(_col) + _row;
}
/**
* Identifier of the row that contains the cell.
*
* @return
*/
public int getRowId() {
return _row;
}
/**
* The cell value.
*
* @return
*/
public String getValue() {
public Value getValue() {
return _value;
}

View File

@ -0,0 +1,65 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database;
/**
* Coordinates of a cell in a notebook data snapshot. Each cell is assigned to a
* column and row, referenced by their respective unique identifiers.
*
* @author Heiko Mueller
*/
public class CellCoordinates {
public static final int UNKNOWN_COLUMN = -1;
public static final int UNKNOWN_ROW = -1;
private final int _col;
private final int _row;
public CellCoordinates(int col, int row) {
_col = col;
_row = row;
}
/**
* Identifier of the column that contains the cell.
*
* @return
*/
public int getColumnId() {
return _col;
}
/**
* The cell key is a concatenation of column and row identifier.
*
* @return
*/
public String getKey() {
return _col + "#" + _row;
}
/**
* Identifier of the row that contains the cell.
*
* @return
*/
public int getRowId() {
return _row;
}
}

View File

@ -0,0 +1,90 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database;
import java.util.HashMap;
import java.util.Iterator;
import org.vizierdb.database.value.Value;
/**
* Set of spreadsheet cells. Cells are indexed by the identifier of their value.
*
* @author Heiko Mueller
*/
public class CellSet implements Iterable<Cell> {
private final HashMap<String, Cell> _cellIndex = new HashMap<>();
private final HashMap<Integer, Cell> _valueIndex = new HashMap<>();
public void add(Cell cell) {
_cellIndex.put(cell.getKey(), cell);
_valueIndex.put(cell.getValue().getIdentifier(), cell);
}
/**
* Cell with the given key.
*
* @param key
* @return
*/
public Cell getCell(String key) {
return _cellIndex.get(key);
}
/**
* Cell at given coordinate position.
*
* @param coordinates
* @return
*/
public Cell getCell(CellCoordinates coordinates) {
return this.getCell(coordinates.getKey());
}
/**
* Cell that contains value with given identifier.
*
* @param valueId
* @return
*/
public Cell getCellForValue(int valueId) {
return _valueIndex.get(valueId);
}
/**
* Value with given identifier or null if no such value exists.
*
* @param valueId
* @return
*/
public Value getValue(int valueId) {
Cell cell = _valueIndex.get(valueId);
if (cell != null) {
return cell.getValue();
} else {
return null;
}
}
@Override
public Iterator<Cell> iterator() {
return _valueIndex.values().iterator();
}
}

View File

@ -0,0 +1,137 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.vizierdb.database.value.DependencyGraph;
import org.vizierdb.database.value.ErrorValue;
import org.vizierdb.database.value.Value;
import org.vizierdb.database.value.formula.Formula;
/**
* Class to build a cell set. Keeps a mapping from cell keys to cells and the
* dependency graph. The latter two objects are not part of the materialized
* snapshot. This is a helper to group various objects that are needed when
* executing script operations.
*
* @author Heiko Mueller
*/
public class CellSetFactory {
private final CellSet _cells = new CellSet();
private final DependencyGraph _graph = new DependencyGraph();
/**
* Add a cell to the set and indexes. Also updates the dependency graph.
*
* @param cell
*/
public void add(Cell cell) {
_cells.add(cell);
if (cell.getValue().isDerived()) {
int valueId = cell.getValue().getIdentifier();
for (int sourceValueId : cell.getValue().getDependencies()) {
_graph.addEdge(valueId, sourceValueId);
}
}
}
/**
* Re-evaluate all values that depend on an updated value.
*
* @param valueId
*/
public void evalForUpdatedValue(int valueId) {
for (int dependentValueId : _graph.getDependentValues(valueId)) {
Cell cell = _cells.getCellForValue(dependentValueId);
_cells.add(new Cell(cell.getColumnId(), cell.getRowId(), cell.getValue().eval(_cells)));
}
}
/**
* Re-evaluate all values that depend on deleted values. The new values will
* all be error values due to their dependency on a deleted value.
*
* @param snapshot
* @param valueIds
*/
public void evalForDeletedValues(Snapshot snapshot, List<Integer> valueIds) {
HashSet<Integer> processedValues = new HashSet<>();
for (int valueId : valueIds) {
for (int dependentValueId : _graph.getDirectDependentValues(valueId)) {
Cell cell = _cells.getCellForValue(dependentValueId);
if (cell != null) {
Value value = cell.getValue();
_cells.add(new Cell(cell.getColumnId(), cell.getRowId(), new ErrorValue(value.getIdentifier(), Formula.ERROR_UNKNOWN_NAME, value.getFormula(snapshot))));
}
processedValues.add(dependentValueId);
}
}
LinkedList<Integer> indirectDependents = new LinkedList<>(processedValues);
while (!indirectDependents.isEmpty()) {
int valueId = indirectDependents.pop();
for (int dependentValueId : _graph.getDirectDependentValues(valueId)) {
if (!processedValues.contains(dependentValueId)) {
Cell cell = _cells.getCellForValue(dependentValueId);
if (cell != null) {
Value value = cell.getValue();
_cells.add(new Cell(cell.getColumnId(), cell.getRowId(), value.eval(_cells)));
for (int cand : value.getDependencies()) {
indirectDependents.push(cand);
}
}
processedValues.add(dependentValueId);
}
}
}
}
/**
* Retrieve cell using cell key.
*
* @param key
* @return
*/
public Cell get(String key) {
return _cells.getCell(key);
}
/**
* Dependency graph that has been constructed.
*
* @return
*/
public DependencyGraph getDependencyGraph() {
return _graph;
}
/**
* Generated cell set.
*
* @return
*/
public CellSet getSet() {
return _cells;
}
}

View File

@ -13,20 +13,24 @@
*/
package org.vizierdb.database;
import java.util.regex.Pattern;
import org.vizierdb.util.SpreadsheetHelper;
/**
* Column in a spreadsheet. Has a name and a unique identifier. The name can be
* empty. The identifier is immutable.
* Column in a spreadsheet. Has a unique identifier, unique label, and a user
* provided name. The name may not be unique among all column names in a
* spreadsheet.
*
* @author Heiko Mueller
*/
public class Column {
/**
* Special string prefix to all references to columns by their identifier.
*/
public static final String COLUMN_ID_INDICATOR = "#";
public static final String COLUMN_ID_INDICATOR = "$";
public static final Pattern VALID_NAME_REGEX = Pattern.compile("[\\d\\w-_]+");
private final ColumnList _columns;
private final int _identifier;
private final String _label;
private final String _name;
/**
@ -34,24 +38,40 @@ public class Column {
*
* @param identifier
* @param name
* @param columnIndex
* @param columns
*/
public Column(int identifier, String name) {
public Column(int identifier, String name, int columnIndex, ColumnList columns) {
if (name.startsWith(COLUMN_ID_INDICATOR)) {
if (name == null) {
throw new java.lang.IllegalArgumentException("Invalid column name: null");
} else if (!VALID_NAME_REGEX.matcher(name).matches()) {
throw new java.lang.IllegalArgumentException("Invalid column name: " + name);
} else if (columnIndex < 0) {
throw new java.lang.IllegalArgumentException("Invalid column index: " + columnIndex);
}
_identifier = identifier;
_name = name;
_label = SpreadsheetHelper.getColumnName(columnIndex);
_columns = columns;
}
/**
* A column without a name.
* Returns the most descriptive name. This is the user provided name if
* unique or the label otherwise.
*
* @param identifier
* @return
*/
private Column(int identifier) {
public String getDescriptiveName() {
this(identifier, null);
if (_columns.isUniqueName(_name)) {
return _name;
} else if (_columns.isUniqueName(_label)) {
return _label;
} else {
return COLUMN_ID_INDICATOR + _identifier;
}
}
/**
@ -65,7 +85,18 @@ public class Column {
}
/**
* Column name. The name may be null.
* Unique column label based on columns position in the spreadsheet (i.e.,
* A, B, C, ...).
*
* @return
*/
public String getLabel() {
return _label;
}
/**
* User provided column name.
*
* @return
*/
@ -73,4 +104,15 @@ public class Column {
return _name;
}
/**
* Indicates whether the column name is unique among all columns in a
* spreadsheet.
*
* @return
*/
public boolean hasUniqueName() {
return _columns.isUniqueName(_name);
}
}

View File

@ -16,7 +16,6 @@ package org.vizierdb.database;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.vizierdb.util.SpreadsheetHelper;
/**
* Listing of columns in a spreadsheet. Columns appear in the spreadsheet in the
@ -27,28 +26,26 @@ import org.vizierdb.util.SpreadsheetHelper;
*/
public class ColumnList implements Iterable<Column> {
/**
* Default name for unknown columns. Unknown columns may arise during
* reenactment of operations that reference columns which have not been
* created or no longer exist.
*/
public static final String UNKNOWN_COLUMN = "???";
private final HashMap<Integer, Integer> _columnIndex = new HashMap<>();
private final ArrayList<Column> _columnList = new ArrayList<>();
private final HashMap<String, Integer> _nameCount = new HashMap<>();
public void add(Column column) {
public void add(int columnId, String columnName) {
_columnList.add(column);
_columnIndex.put(column.getIdentifier(), _columnIndex.size());
if (_nameCount.containsKey(column.getName())) {
_nameCount.put(column.getName(), _nameCount.get(column.getName()) + 1);
if (columnName == null) {
throw new java.lang.IllegalArgumentException("Invalid column name: null");
}
Column column = new Column(columnId, columnName, _columnList.size(), this);
if (_nameCount.containsKey(columnName)) {
_nameCount.put(column.getName(), _nameCount.get(column.getName()) + 1);
} else {
_nameCount.put(column.getName(), 1);
}
_columnList.add(column);
_columnIndex.put(column.getIdentifier(), _columnIndex.size());
}
/**
* Check if the list contains a column with the given identifier.
*
@ -72,34 +69,56 @@ public class ColumnList implements Iterable<Column> {
}
/**
* The most descriptive column name. This is the given column name if it
* is unique. Otherwise it will be the spreadsheet column name. Should that
* name exist as well it will be the column identifier (prefixed by the
* COLUMN_ID_INDICATOR). If the column does not exists the result is the
* default UNKNOWN_COLUMN name.
*
* Column with the given identifier or null if no such column exists.
*
* @param columnId
* @return
*/
public String getDescriptiveName(int columnId) {
public Column getColumn(int columnId) {
int index = this.getIndexOf(columnId);
if (index != -1) {
Column column = _columnList.get(index);
if (_nameCount.get(column.getName()) == 1) {
return column.getName();
} else {
String name = SpreadsheetHelper.getColumnName(index);
if (_nameCount.containsKey(name)) {
return Column.COLUMN_ID_INDICATOR + column.getIdentifier();
} else {
return name;
return _columnList.get(index);
} else {
return null;
}
}
public void renameColumn(int columnId, String newName)
{
int index = this.getIndexOf(columnId);
Column col = _columnList.get(index);
String oldName = col.getName();
_nameCount.put(oldName, _nameCount.get(oldName) - 1);
if (_nameCount.containsKey(newName)) {
_nameCount.put(newName, _nameCount.get(newName) + 1);
} else {
_nameCount.put(newName, 1);
}
_columnList.set(index, new Column(columnId, newName, index, this));
}
/**
* The column identifier of the column with given name. Is UNKNOWN if either
* (i) no column with name exists, or (ii) multiple columns with name
* exist.
*
* @param name
* @return
*/
public int getIdentifierOf(String name) {
if (_nameCount.containsKey(name)) {
if (_nameCount.get(name) != 1) {
return CellCoordinates.UNKNOWN_COLUMN;
}
for (Column column : _columnList) {
if (column.getName().equals(name)) {
return column.getIdentifier();
}
}
} else {
return UNKNOWN_COLUMN;
}
return CellCoordinates.UNKNOWN_COLUMN;
}
/**
@ -117,6 +136,15 @@ public class ColumnList implements Iterable<Column> {
}
}
public boolean isUniqueName(String name) {
if (_nameCount.containsKey(name)) {
return (_nameCount.get(name) <= 1);
} else {
return true;
}
}
@Override
public Iterator<Column> iterator() {

View File

@ -29,7 +29,8 @@ public class Notebook implements Comparable<Notebook> {
private final VersionGraph _history;
private final int _identifier;
private String _name;
private int _rowCount;
private int _rowCount = 0;
private int _valueCount = 0;
public Notebook(int identifier, String name, VizierDB db) {
@ -101,6 +102,17 @@ public class Notebook implements Comparable<Notebook> {
return _rowCount++;
}
/**
* Next unique value identifier. Called when adding a new cell to a
* notebook.
*
* @return
*/
public synchronized int nextValueId() {
return _valueCount++;
}
/**
* Set the notebook name.
*

View File

@ -0,0 +1,51 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database;
import org.vizierdb.database.value.Value;
/**
* Row in a spreadsheet. Primarily used to group cells for evaluation in filter
* conditions.
*
* @author Heiko Mueller
*/
public class Row {
private final CellSet _cells;
private final int _rowId;
public Row(int rowId, CellSet cells) {
_rowId = rowId;
_cells = cells;
}
/**
* Value for column with given identifier. The result is null if the row
* does not have a value for the given column.
*
* @param columnId
* @return
*/
public Value getColumnValue(int columnId) {
Cell cell = _cells.getCell(new CellCoordinates(columnId, _rowId));
if (cell != null) {
return cell.getValue();
} else {
return null;
}
}
}

View File

@ -281,7 +281,7 @@ public class SimpleVizierDBM implements VizierDB {
if (branch.getHead() != UNKNOWN_SNAPSHOT) {
return this.getSnapshot(notebookIdentifier, branch.getHead());
} else {
return new Snapshot(UNKNOWN_SNAPSHOT, new ColumnList(), new RowList(), new ArrayList<Cell>());
return new Snapshot(UNKNOWN_SNAPSHOT, new ColumnList(), new RowList(), new CellSet());
}
}
}

View File

@ -13,8 +13,6 @@
*/
package org.vizierdb.database;
import java.util.List;
/**
* Snapshot of the data in a notebook. Each operation in the script that is
* associated with a notebook will modify the current snapshot.
@ -26,12 +24,12 @@ import java.util.List;
*/
public class Snapshot {
private final List<Cell> _cells;
private final CellSet _cells;
private final ColumnList _columns;
private final int _identifier;
private final RowList _rows;
public Snapshot(int identifier, ColumnList columns, RowList rows, List<Cell> cells) {
public Snapshot(int identifier, ColumnList columns, RowList rows, CellSet cells) {
_identifier = identifier;
_columns = columns;
@ -44,7 +42,7 @@ public class Snapshot {
*
* @return
*/
public List<Cell> getCells() {
public CellSet getCells() {
return _cells;
}

View File

@ -14,11 +14,9 @@
package org.vizierdb.database;
import com.google.gson.JsonObject;
import java.util.HashMap;
import java.util.List;
import org.vizierdb.database.history.Branch;
import org.vizierdb.database.script.Operation;
import org.vizierdb.database.script.OperationType;
import org.vizierdb.database.script.VizUALScript;
/**

View File

@ -0,0 +1,39 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.Row;
/**
*
* @author heiko
*/
public class ANDOp extends LogicOp {
public ANDOp(Condition left, Condition right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
if (this.left().eval(row)) {
return this.right().eval(row);
} else {
return false;
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.ColumnList;
/**
*
* @author heiko
*/
public abstract class BinaryOp implements Condition {
private final Term _left;
private final Term _right;
public BinaryOp(Term left, Term right) {
_left = left;
_right = right;
}
@Override
public boolean isApplicable(ColumnList columns) {
Integer col = _left.getReferencedColumn();
if (col != null) {
if (!columns.contains(col)) {
return false;
}
}
col = _right.getReferencedColumn();
if (col != null) {
if (!columns.contains(col)) {
return false;
}
}
return true;
}
public Term left() {
return _left;
}
public Term rigth() {
return _right;
}
}

View File

@ -0,0 +1,44 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
* Term that returns value of column with specific identifier.
*
* @author Heiko Mueller
*/
public class ColumnTerm implements Term {
private final int _columnId;
public ColumnTerm(int columnId) {
_columnId = columnId;
}
@Override
public Value getValue(Row row) {
return row.getColumnValue(_columnId);
}
@Override
public Integer getReferencedColumn() {
return _columnId;
}
}

View File

@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.Row;
/**
* Condition in a VizUAL filter. Conditions are evaluated over rows in a
* spreadsheet.
*
* @author Heiko Mueller
*/
public interface Condition {
/**
* Evaluate the condition on a spreadsheet row.
*
* @param row
* @return
*/
public boolean eval(Row row);
/**
* Test if all column terms can be evaluated over given list of columns.
*
* @param columns
* @return
*/
public boolean isApplicable(ColumnList columns);
}

View File

@ -0,0 +1,45 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
* Constant value term.
*
* @author heiko
*/
public class ConstantTerm implements Term{
private final Value _value;
public ConstantTerm(Value value) {
_value = value;
}
@Override
public Value getValue(Row row) {
return _value;
}
@Override
public Integer getReferencedColumn() {
return null;
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class EQOp extends BinaryOp {
public EQOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) == 0);
} catch (Exception exception) {
return leftVal.getAsString().equals(rightVal.getAsString());
}
} else {
return ((leftVal == null) && (rightVal == null));
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class GEQOp extends BinaryOp {
public GEQOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) >= 0);
} catch (Exception exception) {
return (leftVal.getAsString().compareTo(rightVal.getAsString()) >= 0);
}
} else {
return ((leftVal == null) && (rightVal == null));
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class GTOp extends BinaryOp {
public GTOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) > 0);
} catch (Exception exception) {
return (leftVal.getAsString().compareTo(rightVal.getAsString()) > 0);
}
} else {
return false;
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class LEQOp extends BinaryOp {
public LEQOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) <= 0);
} catch (Exception exception) {
return (leftVal.getAsString().compareTo(rightVal.getAsString()) <= 0);
}
} else {
return ((leftVal == null) && (rightVal == null));
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class LTOp extends BinaryOp {
public LTOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) < 0);
} catch (Exception exception) {
return (leftVal.getAsString().compareTo(rightVal.getAsString()) < 0);
}
} else {
return false;
}
}
}

View File

@ -0,0 +1,52 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.ColumnList;
/**
*
* @author heiko
*/
public abstract class LogicOp implements Condition {
private final Condition _left;
private final Condition _right;
public LogicOp(Condition left, Condition right) {
_left = left;
_right = right;
}
@Override
public boolean isApplicable(ColumnList columns) {
if (_left.isApplicable(columns)) {
return _right.isApplicable(columns);
} else {
return false;
}
}
public Condition left() {
return _left;
}
public Condition right() {
return _right;
}
}

View File

@ -0,0 +1,61 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import java.util.regex.Pattern;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class MatchesOp implements Condition {
private final Pattern _pattern;
private final Term _term;
public MatchesOp(Term term, Pattern pattern) {
_term = term;
_pattern = pattern;
}
@Override
public boolean eval(Row row) {
Value val = _term.getValue(row);
if (val != null) {
try {
return _pattern.matcher(val.getAsString()).matches();
} catch (Exception exception) {
return false;
}
} else {
return false;
}
}
@Override
public boolean isApplicable(ColumnList columns) {
Integer col = _term.getReferencedColumn();
if (col != null) {
return (columns.contains(col));
}
return false;
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
*
* @author heiko
*/
public class NEQOp extends BinaryOp {
public NEQOp(Term left, Term right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
Value leftVal = this.left().getValue(row);
Value rightVal = this.rigth().getValue(row);
if ((leftVal != null) && (rightVal != null)) {
try {
return (leftVal.getAsBigDecimal().compareTo(rightVal.getAsBigDecimal()) != 0);
} catch (Exception exception) {
return !leftVal.getAsString().equals(rightVal.getAsString());
}
} else {
return !((leftVal == null) && (rightVal == null));
}
}
}

View File

@ -0,0 +1,38 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
/**
*
* @author heiko
*/
public class OROp extends LogicOp {
public OROp(Condition left, Condition right) {
super(left, right);
}
@Override
public boolean eval(Row row) {
if (this.left().eval(row)) {
return true;
} else {
return this.right().eval(row);
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.filter;
import org.vizierdb.database.Row;
import org.vizierdb.database.value.Value;
/**
* Value expression in a filter condition operator. Returns a value. Could
* either be a constant value or the value of a cell in a spreadsheet row.
*
* @author Heiko Mueller
*/
public interface Term {
/**
* The value that the term evaluates to for the given row.
*
* @param row
* @return
*/
public Value getValue(Row row);
/**
* The identifier of the column from which the value is extracted. The
* result is null if the term represents a constant value.
* @return
*/
public Integer getReferencedColumn();
}

View File

@ -30,6 +30,7 @@ import org.vizierdb.database.script.VizUALStatement;
public class VGEdge {
private final Operation _operation;
private final String _sqlStatement;
private final VizUALStatement _stmt;
private final VGNode _target;
@ -40,8 +41,9 @@ public class VGEdge {
* @param target
* @param operation
* @param stmt
* @param sqlStatement
*/
public VGEdge(VGNode target, Operation operation, VizUALStatement stmt) {
public VGEdge(VGNode target, Operation operation, VizUALStatement stmt, String sqlStatement) {
if (operation == null) {
throw new java.lang.IllegalArgumentException("Derivation operation: null");
@ -50,6 +52,7 @@ public class VGEdge {
_target = target;
_operation = operation;
_stmt = stmt;
_sqlStatement = sqlStatement;
}
/**
@ -57,10 +60,11 @@ public class VGEdge {
*
* @param operation
* @param stmt
* @param sqlStatement
*/
public VGEdge(Operation operation, VizUALStatement stmt) {
public VGEdge(Operation operation, VizUALStatement stmt, String sqlStatement) {
this(null, operation, stmt);
this(null, operation, stmt, sqlStatement);
}
/**
@ -79,11 +83,16 @@ public class VGEdge {
*
* @return
*/
public VizUALStatement getStatement() {
public VizUALStatement getVizUALStatement() {
return _stmt;
}
public String getSQLStatement() {
return _sqlStatement;
}
/**
* Node representing the target snapshot.
*

View File

@ -20,6 +20,7 @@ import org.vizierdb.database.Snapshot;
import org.vizierdb.database.script.Operation;
import org.vizierdb.database.script.VizUALScript;
import org.vizierdb.database.VizierDB;
import org.vizierdb.database.script.op.CSVFileLoad;
/**
* The version graph maintains information how snapshots in a notebook's
@ -38,6 +39,7 @@ public class VersionGraph {
private Branch _currentBranch;
private final HashMap<Integer, VGNode> _nodes;
private VGNode _root;
private String _tableName = null;
/**
* Create an empty graph. HEAD and ROOT are undefined for an empty graph.
@ -92,7 +94,16 @@ public class VersionGraph {
if (_root != null) {
throw new java.lang.IllegalStateException("Version graph root has been set");
}
_root = new VGNode(targetId, new VGEdge(operation, operation.getStatement(source)));
/**
* NOTE: This is a hack. requires the first operation to be a load
* operation. Should be changed.
*/
_tableName = ((CSVFileLoad)operation).getFileName();
int pos = _tableName.indexOf(".");
if (pos != -1) {
_tableName = _tableName.substring(0, pos);
}
_root = new VGNode(targetId, new VGEdge(operation, operation.getVizUALStatement(source), operation.getSQLStatement(source, _tableName)));
_nodes.put(targetId, _root);
_currentBranch.setHead(targetId);
return _root;
@ -104,7 +115,7 @@ public class VersionGraph {
if (parent == null) {
throw new java.lang.IllegalArgumentException("Unknown snapshot: " + sourceId);
}
VGNode node = new VGNode(targetId, new VGEdge(parent, operation, operation.getStatement(source)));
VGNode node = new VGNode(targetId, new VGEdge(parent, operation, operation.getVizUALStatement(source), operation.getSQLStatement(source, _tableName)));
_nodes.put(targetId, node);
/**
* If the source snapshot is head of a branch then we will extend that
@ -225,11 +236,11 @@ public class VersionGraph {
VGNode node = _nodes.get(branch.getHead());
if (node != null) {
VGEdge derivation = node.getParent();
script.addAtBeginning(derivation.getOperation(), derivation.getStatement(), node.getSnapshotIdentifier());
script.addAtBeginning(derivation.getOperation(), derivation.getVizUALStatement(), derivation.getSQLStatement(), node.getSnapshotIdentifier());
while (derivation.hasTarget()) {
node = derivation.getTarget();
derivation = node.getParent();
script.addAtBeginning(derivation.getOperation(), derivation.getStatement(), node.getSnapshotIdentifier());
script.addAtBeginning(derivation.getOperation(), derivation.getVizUALStatement(), derivation.getSQLStatement(), node.getSnapshotIdentifier());
}
}

View File

@ -50,7 +50,16 @@ public abstract class Operation {
* @param snapshot
* @return
*/
public abstract VizUALStatement getStatement(Snapshot snapshot);
public abstract VizUALStatement getVizUALStatement(Snapshot snapshot);
/**
* SQL statement representing the operation when applied to the given
* snapshot.
*
* @param snapshot
* @return
*/
public abstract String getSQLStatement(Snapshot snapshot, String tableName);
/**
* Operation type.

View File

@ -62,6 +62,7 @@ public enum OperationType {
DeleteColumn,
DeleteRow,
Filter,
InsertColumn,
InsertRow,
LoadFile,

View File

@ -28,12 +28,14 @@ public class VizUALScript {
public final Operation op;
public final int snapshot;
public final String sqlStmt;
public final VizUALStatement stmt;
public ScriptOp(Operation op, VizUALStatement stmt, int snapshot) {
public ScriptOp(Operation op, VizUALStatement stmt, String sqlStmt, int snapshot) {
this.op = op;
this.stmt = stmt;
this.sqlStmt = sqlStmt;
this.snapshot = snapshot;
}
}
@ -45,11 +47,25 @@ public class VizUALScript {
*
* @param operation
* @param stmt
* @param sqlStmt
* @param snapshotIdentifier
*/
public void addAtBeginning(Operation operation, VizUALStatement stmt, int snapshotIdentifier) {
public void addAtBeginning(Operation operation, VizUALStatement stmt, String sqlStmt, int snapshotIdentifier) {
_ops.addFirst(new ScriptOp(operation, stmt, snapshotIdentifier));
_ops.addFirst(new ScriptOp(operation, stmt, sqlStmt, snapshotIdentifier));
}
/**
* Add an operation to the end of the script.
*
* @param operation
* @param stmt
* @param sqlStmt
* @param snapshotIdentifier
*/
public void addAtEnd(Operation operation, VizUALStatement stmt, String sqlStmt, int snapshotIdentifier) {
_ops.add(new ScriptOp(operation, stmt, sqlStmt, snapshotIdentifier));
}
/**
@ -99,11 +115,16 @@ public class VizUALScript {
* @param index
* @return
*/
public VizUALStatement getStatement(int index) {
public VizUALStatement getVizUALStatement(int index) {
return _ops.get(index).stmt;
}
public String getSQLStatement(int index) {
return _ops.get(index).sqlStmt;
}
/**
* Number of operations in the script.
*

View File

@ -1,5 +1,7 @@
package org.vizierdb.database.script;
import org.vizierdb.VizirDBException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
@ -19,7 +21,7 @@ public class VizualTranslator implements Serializable {
public static void main(String[] args) throws ParseException {
ArrayList<String> script = new ArrayList<>();
String test = "move row 2 to 3";
String test = "sort rows asc";
script.add(test);
VizualTranslator parser = new VizualTranslator(script);
@ -54,11 +56,11 @@ public class VizualTranslator implements Serializable {
return getVizQL(vizualLine);
}
private void setTableName(String tableName) {
public void setTableName(String tableName) {
VizualTranslator.tableName = tableName;
}
private String getVizQL(String line) throws ParseException {
public String getVizQL(String line) throws ParseException {
String firstWord;
String constructedSQL;
String[] tokens;
@ -117,13 +119,27 @@ public class VizualTranslator implements Serializable {
}
break;
case "SORT": {
String order;
if (tokens.length == 2) order = "ASC";
else if (tokens.length == 3) order = "DESC";
else throw new VizualTranslator.ParseException("Unknown sort order.");
constructedSQL = "UPDATE " + tableName +
" SET VIZIER_ROWID = (SELECT NEW_RID FROM" +
" (SELECT VIZIER_ROWID AS OLDID, " +
" ROW_NUMBER() AS NEW_RID FROM " + tableName +
" ORDER BY " + order + ") sub " +
" WHERE OLDID = VIZIER_ROWID);";
}
break;
default:
throw new ParseException("Unhandled operation : " + firstWord.toUpperCase());
}
return constructedSQL;
}
private class ParseException extends Exception implements Serializable {
public class ParseException extends Exception implements Serializable {
ParseException(String errorMessage) {
super(errorMessage);
}

View File

@ -15,17 +15,18 @@ package org.vizierdb.database.script.op;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVFormat.Predefined;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.vizierdb.RequestParameterException;
import org.vizierdb.VizirDBException;
import org.vizierdb.database.Cell;
import org.vizierdb.database.Column;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.value.ConstantValue;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.RowList;
import org.vizierdb.database.Snapshot;
@ -80,12 +81,30 @@ public class CSVFileLoad extends Operation {
_headline = headline;
}
public CSVFileLoad(File file, CSVFormat format, boolean headline) {
super(OperationType.LoadFile);
_file = file;
_fileName = file.getName();
_format = format;
_headline = headline;
String formatName = "UNDEFINED";
for (Predefined predefined : CSVFormat.Predefined.values()) {
if (predefined.getFormat().equals(format)) {
formatName = predefined.name();
}
}
_formatName = formatName;
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) throws org.vizierdb.VizirDBException {
ColumnList columns = new ColumnList();
RowList rows = new RowList();
ArrayList<Cell> cells = new ArrayList<>();
CellSet cells = new CellSet();
try (CSVParser parser = new CSVParser(new FileReader(_file), _format)) {
List<CSVRecord> records = parser.getRecords();
@ -93,7 +112,11 @@ public class CSVFileLoad extends Operation {
if (_headline) {
CSVRecord record = records.get(0);
for (int iColumn = 0; iColumn < record.size(); iColumn++) {
columns.add(new Column(notebook.nextColumnId(), record.get(iColumn)));
String columnName = record.get(iColumn).trim();
if (columnName.equals("")) {
columnName = SpreadsheetHelper.getColumnName(iColumn);
}
columns.add(notebook.nextColumnId(), columnName);
}
offset = 1;
} else {
@ -104,7 +127,7 @@ public class CSVFileLoad extends Operation {
}
}
for (int iCol = 0; iCol < maxCols; iCol++) {
columns.add(new Column(notebook.nextColumnId(), SpreadsheetHelper.getColumnName(iCol)));
columns.add(notebook.nextColumnId(), SpreadsheetHelper.getColumnName(iCol));
}
}
for (int iRecord = offset; iRecord < records.size(); iRecord++) {
@ -112,7 +135,7 @@ public class CSVFileLoad extends Operation {
rows.add(rowId);
CSVRecord record = records.get(iRecord);
for (int iValue = 0; iValue < Math.min(columns.size(), record.size()); iValue++) {
cells.add(new Cell(columns.get(iValue).getIdentifier(), rowId, record.get(iValue)));
cells.add(new Cell(columns.get(iValue).getIdentifier(), rowId, new ConstantValue(notebook.nextValueId(), record.get(iValue))));
}
}
} catch (java.io.IOException ioException) {
@ -173,7 +196,7 @@ public class CSVFileLoad extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String cmd = "LOAD FILE " + _fileName + " OF TYPE " + _formatName;
String html = "<span class=\"cmd-txt\">LOAD FILE</span> <span class=\"cmd-para\">" + _fileName + "</span>";
@ -191,6 +214,12 @@ public class CSVFileLoad extends Operation {
return new VizUALStatement(cmd, html, "LOAD FILE " + _fileName);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "CREATE TABLE " + tableName + " AS SELECT *, ROWID AS VIZIER_ROWID " + "FROM " + _fileName + ";";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -15,13 +15,27 @@ package org.vizierdb.database.script.op;
import java.util.ArrayList;
import java.util.HashMap;
import org.parboiled.Parboiled;
import org.parboiled.parserunners.ReportingParseRunner;
import org.parboiled.support.ParsingResult;
import org.vizierdb.RequestParameterException;
import org.vizierdb.database.Cell;
import org.vizierdb.database.CellCoordinates;
import org.vizierdb.database.CellSetFactory;
import org.vizierdb.database.Column;
import org.vizierdb.database.value.ConstantValue;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.Snapshot;
import org.vizierdb.database.value.Value;
import org.vizierdb.database.value.formula.FormulaNode;
import org.vizierdb.database.value.formula.FormulaParser;
import org.vizierdb.database.script.Operation;
import org.vizierdb.database.script.OperationType;
import org.vizierdb.database.script.VizUALStatement;
import org.vizierdb.database.value.ErrorValue;
import org.vizierdb.database.value.FormulaValue;
import org.vizierdb.database.value.formula.CellReference;
import org.vizierdb.database.value.formula.Formula;
/**
* Update a cell in a notebook snapshot. The cell is identified by the column
@ -36,6 +50,7 @@ public class CellUpdate extends Operation {
public static final String PARAMETER_VALUE = "value";
private final int _columnId;
private String _printValue;
private final int _rowId;
private final String _value;
@ -77,31 +92,169 @@ public class CellUpdate extends Operation {
value = parameters.get(PARAMETER_VALUE);
}
_value = value;
_printValue = value;
}
public CellUpdate(Snapshot snapshot, int column, int row, String value) throws org.vizierdb.RequestParameterException {
super(OperationType.UpdateCell);
if ((column < 0) || (column >= snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_COLUMN, "Invalid column: " + column);
}
_columnId = snapshot.getColumns().get(column).getIdentifier();
if ((row < 0) || (row >= snapshot.getRows().size())) {
throw new RequestParameterException(PARAMETER_ROW, "Invalid row: " + row);
}
_rowId = snapshot.getRows().get(row);
_value = value;
_printValue = value;
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
CellSetFactory cells = new CellSetFactory();
/*
* For new columns or row no cell objects are initially created. Thus,
* the cell that is updated may need to be added if it is not contained
* in the current set of cells.
* Start by finding the updated cell. For new columns or row no cell
* objects are initially created. Thus, the cell that is updated may
* need to be added if it is not contained in the current set of cells.
*/
boolean added = false;
ArrayList<Cell> cells = new ArrayList<>();
Cell updatedCell = null;
for (Cell cell : snapshot.getCells()) {
if ((cell.getColumnId() == _columnId) && (cell.getRowId() == _rowId)) {
cells.add(new Cell(cell.getColumnId(), cell.getRowId(), _value));
added = true;
updatedCell = cell;
} else {
cells.add(cell);
}
}
if (!added) {
cells.add(new Cell(_columnId, _rowId, _value));
/*
* Identifier of updated cell. If this cell has not been created yet,
* assign a new value identifier.
*/
int valueIdentifier;
if (updatedCell != null) {
valueIdentifier = updatedCell.getValue().getIdentifier();
} else {
valueIdentifier = notebook.nextValueId();
}
return new Snapshot(resultIdentifier, snapshot.getColumns(), snapshot.getRows(), cells);
/*
* Create the new updated value. THis can either be a formula or a
* constant value.
*/
Value value = null;
if (_value.trim().startsWith("=")) {
/**
* New value is a formula. There are four different error conditions
* the need to be handled:
*
* #SYNTAX!: Formula does not match the parsers grammar
* #NAME? : Formula contains references to unknown columns or rows
* #REF! : Formula introduces circular references (or contains self-reference)
* #VALUE! : At least one of the referenced values could not be converted to a number
*/
FormulaParser<FormulaNode> parser = Parboiled.createParser(FormulaParser.class);
ParsingResult<?> result = new ReportingParseRunner(parser.Formula()).run(_value.trim());
if (result.matched) {
FormulaNode root = (FormulaNode)result.parseTreeRoot.getValue();
/*
* Get identifier of all values that are associated with cells
* that are referenced in the formula.
*/
ArrayList<Integer> valueReferences = new ArrayList<>();
for (CellReference ref : root.getCellReferences()) {
CellCoordinates coord = ref.getCoordinates(snapshot);
if ((coord.getColumnId() == CellCoordinates.UNKNOWN_COLUMN) || (coord.getRowId() == CellCoordinates.UNKNOWN_ROW)) {
// #NAME: Reference to unknown column or row
value = new ErrorValue(valueIdentifier, Formula.ERROR_UNKNOWN_NAME, _value);
break;
} else {
Cell cell = cells.get(coord.getKey());
if (cell == null) {
if ((coord.getColumnId() == _columnId) && (coord.getRowId() == _rowId)) {
// #REF: Self-reference
value = new ErrorValue(valueIdentifier, Formula.ERROR_INVALID_REFERENCE, _value);
break;
} else {
/*
* Reference to empty cell. Create the cell with
* an empty value
*/
cell = new Cell(coord.getColumnId(), coord.getRowId(), new ConstantValue(notebook.nextValueId(), ""));
cells.add(cell);
}
}
valueReferences.add(cell.getValue().getIdentifier());
ref.setReferencedValue(cell.getValue().getIdentifier());
}
}
/*
* The value will still be null if no error condition occurred.
*/
if (value == null) {
/*
* Ensure that value references do not create circular
* references. The value can only be referenced from
* another formula if it previously existed (i.e.,
* updatedCell != null);
*/
if (updatedCell != null) {
for (int sourceId : valueReferences) {
if (cells.getDependencyGraph().createsCycle(sourceId, valueIdentifier)) {
// #REF: Cyclic references
value = new ErrorValue(valueIdentifier, Formula.ERROR_INVALID_REFERENCE, _value);
break;
}
}
}
/*
* Compute the formula value if no cycle was detected.
*/
if (value == null) {
value = new FormulaValue(valueIdentifier, root, valueReferences, cells.getSet());
}
}
} else {
// #SYNTAX: There was a parse error
value = new ErrorValue(valueIdentifier, Formula.ERROR_SYNTAX, _value);
}
} else {
/*
* New value is a constant value.
*/
value = new ConstantValue(valueIdentifier, _value);
}
/*
* Add the updated cell and create the new snapshot. At this point all
* values that depend on the modified value have not been updated.
*/
cells.add(new Cell(_columnId, _rowId, value));
Snapshot nextSnapshot = new Snapshot(resultIdentifier, snapshot.getColumns(), snapshot.getRows(), cells.getSet());
/*
* Get the printable version of the value (requires the snapshot to be
* instantiated first).
*/
if (value.isDerived()) {
_printValue = value.getFormula(nextSnapshot);
} else {
_printValue = _value;
}
/*
* Re-evaluate all formulas that depend on the updated value. Use the
* wasUpdated() method of the cell factory to ensure that the cell set
* which was used to generate the new snapshot is modified.
*/
if (updatedCell != null) {
cells.evalForUpdatedValue(valueIdentifier);
}
return nextSnapshot;
}
/**
@ -130,30 +283,51 @@ public class CellUpdate extends Operation {
* @return
*/
public String getValue() {
return _value;
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String columnName = snapshot.getColumns().getDescriptiveName(_columnId);
String rowName = snapshot.getRows().getDescriptiveName(_rowId);
String shortCmd = "UPDATE CELL [" + columnName + "," + rowName + "]";
String cmd = shortCmd + " = ";
String html = "<span class=\"cmd-txt\">UPDATE CELL</span> [<span class=\"cmd-para\">" + columnName + "</span>,<span class=\"cmd-para\">" + rowName + "</span>] = ";
if (_value != null) {
cmd += "'" + _value + "'";
html += "\'" + _value + "\'";
} else {
cmd += "''";
html += "\'\'";
}
String cellReference;
String cellReferenceHtml;
String rowName = snapshot.getRows().getDescriptiveName(_rowId);
Column column = snapshot.getColumns().getColumn(_columnId);
if (column.hasUniqueName()) {
cellReference = "[" + column.getName() + "," + rowName + "]";
cellReferenceHtml = "[<span class=\"cmd-para\">" + column.getName() + "</span>,<span class=\"cmd-para\">" + rowName + "</span>]";
} else {
cellReference = column.getLabel() + rowName;
cellReferenceHtml = "<span class=\"cmd-para\">" + cellReference + "</span>";
}
String shortCmd = "UPDATE CELL " + cellReference;
String cmd = shortCmd;
String html = "<span class=\"cmd-txt\">UPDATE CELL</span> " + cellReferenceHtml;
if (_printValue != null) {
if (_printValue.trim().startsWith("=")) {
cmd += " " + _printValue.trim();
html += " " + _printValue.trim();
} else {
cmd += " = '" + _printValue + "'";
html += " = \'" + _printValue + "\'";
}
} else {
cmd += " = ''";
html += " = \'\'";
}
return new VizUALStatement(cmd, html, shortCmd);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "UPDATE TABLE " + tableName + " SET " + snapshot.getColumns().getColumn(_columnId).getDescriptiveName() + " = '" + _value
+ "' WHERE VIZIER_ROWID = " + _rowId + ";";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import org.vizierdb.RequestParameterException;
import org.vizierdb.database.Cell;
import org.vizierdb.database.CellSetFactory;
import org.vizierdb.database.Column;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.Notebook;
@ -58,24 +59,45 @@ public class ColumnDelete extends Operation {
_columnId = snapshot.getColumns().get(column).getIdentifier();
}
public ColumnDelete(Snapshot snapshot, int column) throws org.vizierdb.RequestParameterException {
super(OperationType.DeleteColumn);
if ((column < 0) || (column >= snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_COLUMN, "Invalid column: " + column);
}
_columnId = snapshot.getColumns().get(column).getIdentifier();
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
ColumnList columns = new ColumnList();
for (Column column : snapshot.getColumns()) {
if (column.getIdentifier() != _columnId) {
columns.add(column);
columns.add(column.getIdentifier(), column.getName());
}
}
ArrayList<Cell> cells = new ArrayList<>();
CellSetFactory cells = new CellSetFactory();
ArrayList<Integer> deletedValues = new ArrayList<>();
for (Cell cell : snapshot.getCells()) {
if (cell.getColumnId() != _columnId) {
cells.add(cell);
} else {
deletedValues.add(cell.getValue().getIdentifier());
}
}
return new Snapshot(resultIdentifier, columns, snapshot.getRows(), cells);
/*
* Create new snapshot and updated values that are depending on values
* in the deleted column.
*/
Snapshot nextSnapshot = new Snapshot(resultIdentifier, columns, snapshot.getRows(), cells.getSet());
if (!deletedValues.isEmpty()) {
cells.evalForDeletedValues(nextSnapshot, deletedValues);
}
return nextSnapshot;
}
/**
@ -89,14 +111,20 @@ public class ColumnDelete extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String name = snapshot.getColumns().getDescriptiveName(_columnId);
String name = snapshot.getColumns().getColumn(_columnId).getDescriptiveName();
String cmd = "DELETE COLUMN " + name;
String html = "<span class=\"cmd-txt\">DELETE COLUMN</span> <span class=\"cmd-para\">" + name + "</span>";
return new VizUALStatement(cmd, html);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "ALTER TABLE " + tableName + " DROP COLUMN " + snapshot.getColumns().getColumn(_columnId).getDescriptiveName() + ";";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -72,22 +72,37 @@ public class ColumnInsert extends Operation {
}
}
public ColumnInsert(Snapshot snapshot, int position, String name) throws org.vizierdb.RequestParameterException {
super(OperationType.InsertColumn);
_position = position;
if ((_position < 0) || (_position > snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_POSITION, "Invalid position: " + _position);
}
if (name.equals("")) {
_name = SpreadsheetHelper.getColumnName(_position);
} else {
_name = name;
}
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
ColumnList columns = new ColumnList();
for (Column column : snapshot.getColumns()) {
if (columns.size() == _position) {
columns.add(new Column(notebook.nextColumnId(), _name));
columns.add(notebook.nextColumnId(), _name);
}
columns.add(column);
columns.add(column.getIdentifier(), column.getName());
}
/**
* Column may not have been added if the position equals the size of the
* column list.
*/
if (columns.size() == _position) {
columns.add(new Column(notebook.nextColumnId(), _name));
columns.add(notebook.nextColumnId(), _name);
}
return new Snapshot(resultIdentifier, columns, snapshot.getRows(), snapshot.getCells());
@ -114,7 +129,7 @@ public class ColumnInsert extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String cmd = "INSERT COLUMN " + _name + " AT POSITION " + _position;
String html = "<span class=\"cmd-txt\">INSERT COLUMN <span class=\"cmd-para\">" + _name + "</span> AT POSITION <span class=\"cmd-para\">" + _position + "</span>";
@ -122,6 +137,12 @@ public class ColumnInsert extends Operation {
return new VizUALStatement(cmd, html, "INSERT COLUMN " + _name);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "ALTER TABLE " + tableName + " ADD COLUMN " + _name + " CHAR(100);";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -70,6 +70,21 @@ public class ColumnMove extends Operation {
}
}
public ColumnMove(Snapshot snapshot, int column, int position) throws org.vizierdb.RequestParameterException {
super(OperationType.MoveColumn);
if ((column < 0) || (column >= snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_COLUMN, "Invalid column: " + column);
}
_columnId = snapshot.getColumns().get(column).getIdentifier();
_position = position;
if ((_position < 0) || (_position > snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_POSITION, "Invalid target column: " + _position);
}
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
@ -81,22 +96,25 @@ public class ColumnMove extends Operation {
for (int iColumn = 0; iColumn < currentColumns.size(); iColumn++) {
if (iColumn == _position) {
if (columnIndex < _position) {
modifiedColumns.add(currentColumns.get(iColumn));
modifiedColumns.add(column);
Column mColumn = currentColumns.get(iColumn);
modifiedColumns.add(mColumn.getIdentifier(), mColumn.getName());
modifiedColumns.add(column.getIdentifier(), column.getName());
} else {
modifiedColumns.add(column);
modifiedColumns.add(currentColumns.get(iColumn));
modifiedColumns.add(column.getIdentifier(), column.getName());
Column mColumn = currentColumns.get(iColumn);
modifiedColumns.add(mColumn.getIdentifier(), mColumn.getName());
}
} else if (iColumn != columnIndex) {
modifiedColumns.add(currentColumns.get(iColumn));
Column mColumn = currentColumns.get(iColumn);
modifiedColumns.add(mColumn.getIdentifier(), mColumn.getName());
}
}
if (_position == currentColumns.size()) {
modifiedColumns.add(column);
modifiedColumns.add(column.getIdentifier(), column.getName());
}
} else {
for (Column column : currentColumns) {
modifiedColumns.add(column);
modifiedColumns.add(column.getIdentifier(), column.getName());
}
}
@ -124,15 +142,20 @@ public class ColumnMove extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String columnName = snapshot.getColumns().getDescriptiveName(_columnId);
String columnName = snapshot.getColumns().getColumn(_columnId).getDescriptiveName();
String cmd = "MOVE COLUMN " + columnName + " TO POSITION " + _position;
String html = "<span class=\"cmd-txt\">MOVE COLUMN</span> <span class=\"cmd-para\">" + columnName + "</span> TO POSITION <span class=\"cmd-para\">" + _position + "</span>";
return new VizUALStatement(cmd, html, "MOVE COLUMN " + columnName);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "UNDEFINED: MOVE COLUMN";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -60,7 +60,19 @@ public class ColumnRename extends Operation {
if (parameters.containsKey(PARAMETER_NAME)) {
name = parameters.get(PARAMETER_NAME);
}
_name = name;
_name = name.trim();
}
public ColumnRename(Snapshot snapshot, int column, String name) throws org.vizierdb.RequestParameterException {
super(OperationType.RenameColumn);
if ((column < 0) || (column >= snapshot.getColumns().size())) {
throw new RequestParameterException(PARAMETER_COLUMN, "Invalid column: " + column);
}
_columnId = snapshot.getColumns().get(column).getIdentifier();
_name = name.trim();
}
@Override
@ -69,9 +81,9 @@ public class ColumnRename extends Operation {
ColumnList columns = new ColumnList();
for (Column column : snapshot.getColumns()) {
if (column.getIdentifier() == _columnId) {
columns.add(new Column(column.getIdentifier(), _name));
columns.add(column.getIdentifier(), _name);
} else {
columns.add(column);
columns.add(column.getIdentifier(), column.getName());
}
}
@ -99,15 +111,21 @@ public class ColumnRename extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String columnName = snapshot.getColumns().getDescriptiveName(_columnId);
String columnName = snapshot.getColumns().getColumn(_columnId).getDescriptiveName();
String cmd = "RENAME COLUMN " + columnName + " AS " + _name;
String html = "<span class=\"cmd-txt\">RENAME COLUMN </span> <span class=\"cmd-para\">" + columnName + "</span> AS <span class=\"cmd-para\">" + _name + "</span>";
return new VizUALStatement(cmd, html, "RENAME COLUMN " + columnName);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "ALTER TABLE " + tableName + " RENAME COLUMN " + snapshot.getColumns().getColumn(_columnId).getDescriptiveName() + " TO " + _name + ";";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import org.vizierdb.RequestParameterException;
import org.vizierdb.database.Cell;
import org.vizierdb.database.CellSetFactory;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.RowList;
import org.vizierdb.database.Snapshot;
@ -57,6 +58,16 @@ public class RowDelete extends Operation {
_rowId = snapshot.getRows().get(row);
}
public RowDelete(Snapshot snapshot, int row) throws org.vizierdb.RequestParameterException {
super(OperationType.DeleteRow);
if ((row < 0) || (row >= snapshot.getRows().size())) {
throw new RequestParameterException(PARAMETER_ROW, "Invalid row: " + row);
}
_rowId = snapshot.getRows().get(row);
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
@ -68,13 +79,24 @@ public class RowDelete extends Operation {
}
if (rows.size() != snapshot.getRows().size()) {
ArrayList<Cell> cells = new ArrayList<>();
CellSetFactory cells = new CellSetFactory();
ArrayList<Integer> deletedValues = new ArrayList<>();
for (Cell cell : snapshot.getCells()) {
if (cell.getRowId() != _rowId) {
cells.add(cell);
} else {
deletedValues.add(cell.getValue().getIdentifier());
}
}
return new Snapshot(resultIdentifier, snapshot.getColumns(), rows, cells);
/*
* Create new snapshot and update values that depend on values in
* the deleted row.
*/
Snapshot nextSnapshot = new Snapshot(resultIdentifier, snapshot.getColumns(), rows, cells.getSet());
if (!deletedValues.isEmpty()) {
cells.evalForDeletedValues(nextSnapshot, deletedValues);
}
return nextSnapshot;
} else {
return new Snapshot(resultIdentifier, snapshot.getColumns(), snapshot.getRows(), snapshot.getCells());
}
@ -91,7 +113,7 @@ public class RowDelete extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String rowName = snapshot.getRows().getDescriptiveName(_rowId);
String cmd = "DELETE ROW " + rowName;
@ -100,6 +122,12 @@ public class RowDelete extends Operation {
return new VizUALStatement(cmd, html);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "DELETE FROM " + tableName + " WHERE VIZIER_ROWID = " + _rowId + ";";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -0,0 +1,90 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.script.op;
import java.util.ArrayList;
import org.vizierdb.database.Cell;
import org.vizierdb.database.CellSetFactory;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.Row;
import org.vizierdb.database.RowList;
import org.vizierdb.database.Snapshot;
import org.vizierdb.database.filter.Condition;
import org.vizierdb.database.script.Operation;
import org.vizierdb.database.script.OperationType;
import org.vizierdb.database.script.VizUALStatement;
/**
*
* @author heiko
*/
public class RowFilter extends Operation {
private final Condition _filter;
public RowFilter(Condition filter) {
super(OperationType.Filter);
_filter = filter;
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
RowList rows = new RowList();
for (int rowId : snapshot.getRows()) {
Row row = new Row(rowId, snapshot.getCells());
if (_filter.eval(row)) {
rows.add(rowId);
}
}
CellSetFactory cells = new CellSetFactory();
ArrayList<Integer> deletedValues = new ArrayList<>();
for (Cell cell : snapshot.getCells()) {
if (rows.contains(cell.getRowId())) {
cells.add(cell);
} else {
deletedValues.add(cell.getValue().getIdentifier());
}
}
/*
* Create new snapshot and update values that depend on values in
* the deleted row.
*/
Snapshot nextSnapshot = new Snapshot(resultIdentifier, snapshot.getColumns(), rows, cells.getSet());
if (!deletedValues.isEmpty()) {
cells.evalForDeletedValues(nextSnapshot, deletedValues);
}
return nextSnapshot;
}
@Override
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean isApplicable(Snapshot snapshot) {
return _filter.isApplicable(snapshot.getColumns());
}
}

View File

@ -15,6 +15,7 @@ package org.vizierdb.database.script.op;
import java.util.HashMap;
import org.vizierdb.RequestParameterException;
import org.vizierdb.database.Column;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.RowList;
import org.vizierdb.database.Snapshot;
@ -53,6 +54,16 @@ public class RowInsert extends Operation {
}
}
public RowInsert(Snapshot snapshot, int position) throws org.vizierdb.RequestParameterException {
super(OperationType.InsertRow);
_position = position;
if ((_position < 0) || (_position > snapshot.getRows().size())) {
throw new RequestParameterException(PARAMETER_POSITION, "Invalid position: " + _position);
}
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
@ -85,7 +96,7 @@ public class RowInsert extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String cmd = "INSERT ROW AT POSITION " + _position;
String html = "<span class=\"cmd-txt\">INSERT ROW</span> AT POSITION <span class=\"cmd-para\">" + _position + "</span>";
@ -93,6 +104,18 @@ public class RowInsert extends Operation {
return new VizUALStatement(cmd, html);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
String columnList = "VIZIER_ROWID";
String valueList = Integer.toString(snapshot.getRows().size());
for (Column column : snapshot.getColumns()) {
columnList = columnList + ", " + column.getDescriptiveName();
valueList = valueList + ", ''";
}
return "INSERT INTO " + tableName + "(" + columnList + ") VALUES(" + valueList + ");";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -69,6 +69,21 @@ public class RowMove extends Operation {
}
}
public RowMove(Snapshot snapshot, int row, int position) throws org.vizierdb.RequestParameterException {
super(OperationType.MoveRow);
if ((row < 0) || (row >= snapshot.getRows().size())) {
throw new RequestParameterException(PARAMETER_ROW, "Invalid row: " + row);
}
_rowId = snapshot.getRows().get(row);
_position = position;
if ((_position < 0) || (_position > snapshot.getRows().size())) {
throw new RequestParameterException(PARAMETER_POSITION, "Invalid target row: " + _position);
}
}
@Override
public Snapshot exec(Notebook notebook, Snapshot snapshot, int resultIdentifier) {
@ -123,7 +138,7 @@ public class RowMove extends Operation {
}
@Override
public VizUALStatement getStatement(Snapshot snapshot) {
public VizUALStatement getVizUALStatement(Snapshot snapshot) {
String rowName = snapshot.getRows().getDescriptiveName(_rowId);
String cmd = "MOVE ROW " + rowName + " TO POSITION " + _position;
@ -132,6 +147,11 @@ public class RowMove extends Operation {
return new VizUALStatement(cmd, html, "MOVE ROW " + rowName);
}
@Override
public String getSQLStatement(Snapshot snapshot, String tableName) {
return "UNDEFINED: MOVE ROW";
}
@Override
public boolean isApplicable(Snapshot snapshot) {

View File

@ -0,0 +1,74 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
* Constant cell value. For constant values the formula is basically the value.
* The formula flag is set to false although the formula value will not be null.
*
* @author Heiko Mueller
*/
public class ConstantValue extends Value {
private final String _value;
public ConstantValue(int identifier, String value) {
super(identifier);
_value = value;
}
@Override
public Value eval(CellSet cells) {
return this;
}
@Override
public BigDecimal getAsBigDecimal() {
return new BigDecimal(_value);
}
@Override
public String getAsString() {
return _value;
}
@Override
public List<Integer> getDependencies() {
return new ArrayList<>();
}
@Override
public String getFormula(Snapshot snapshot) {
return this.getAsString();
}
@Override
public boolean isDerived() {
return false;
}
}

View File

@ -0,0 +1,153 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
/**
* Graph containing information about derivation dependencies for values as
* defined by their formulas. An edge source -> target indicates that source
* uses target (or depends on target).
*
* @author Heiko Mueller
*/
public class DependencyGraph {
private final HashMap<Integer, HashSet<Integer>> _incomingEdges = new HashMap<>();
private final HashMap<Integer, HashSet<Integer>> _outgoingEdges = new HashMap<>();
public void addEdge(int source, int target) {
this.addEdge(source, target, _outgoingEdges);
this.addEdge(target, source, _incomingEdges);
}
private void addEdge(int node, int target, HashMap<Integer, HashSet<Integer>> edges) {
HashSet<Integer> references;
if (edges.containsKey(node)) {
references = edges.get(node);
} else {
references = new HashSet<>();
edges.put(node, references);
}
references.add(target);
}
/**
* True, if inserting the given edge will create a cycle. Note, this assumes
* that the graph is acyclic at the moment. Checks whether there exists a
* path from the target to the source.
*
* @param source
* @param target
* @return
*/
public boolean createsCycle(int source, int target) {
HashSet<Integer> reachable = new HashSet<>();
reachable.add(target);
this.getReachableNodes(target, reachable, source);
return reachable.contains(source);
}
/**
* Returns a topologically sorted list of nodes that depend on the given
* target. Note, that this operation will modify the graph by removing
* edges!
*
* @param target
* @return
*/
public List<Integer> getDependentValues(int target) {
/**
* Find all start nodes reachable from the target
*/
HashSet<Integer> nodes = new HashSet<>();
ArrayList<Integer> startNodes = new ArrayList<>();
if (_incomingEdges.containsKey(target)) {
this.getIncomingNodes(target, nodes, startNodes);
}
ArrayList<Integer> result = new ArrayList<>();
while (!startNodes.isEmpty()) {
int node = startNodes.remove(0);
result.add(node);
HashSet<Integer> outEdges = _outgoingEdges.get(node);
if (outEdges != null) {
for (int nextNode : outEdges) {
HashSet<Integer> inEdges = _incomingEdges.get(nextNode);
inEdges.remove(node);
if ((inEdges.isEmpty()) && (nextNode != target)) {
startNodes.add(nextNode);
}
}
}
}
Collections.reverse(result);
return result;
}
/**
* List all values that depend directly on the value with the given
* identifier.
*
* @param valueId
* @return
*/
public List<Integer> getDirectDependentValues(int valueId) {
if (_incomingEdges.containsKey(valueId)) {
return new ArrayList<>(_incomingEdges.get(valueId));
} else {
return new ArrayList<>();
}
}
private void getIncomingNodes(int target, HashSet<Integer> nodes, ArrayList<Integer> startNodes) {
for (int source : _incomingEdges.get(target)) {
nodes.add(source);
if (_incomingEdges.containsKey(source)) {
this.getIncomingNodes(source, nodes, startNodes);
} else {
startNodes.add(source);
}
}
}
private void getReachableNodes(int source, HashSet<Integer> visited, int aimedTarget) {
if (_outgoingEdges.containsKey(source)) {
for (int target : _outgoingEdges.get(source)) {
if (!visited.contains(target)) {
visited.add(target);
if (target == aimedTarget) {
return;
}
this.getReachableNodes(target, visited, aimedTarget);
if (visited.contains(aimedTarget)) {
return;
}
}
}
}
}
}

View File

@ -0,0 +1,74 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
*
* @author heiko
*/
public class ErrorValue extends Value {
private final String _formula;
private final String _message;
public ErrorValue(int identifier, String message, String formula) {
super(identifier);
_message = message;
_formula = formula;
}
@Override
public Value eval(CellSet cells) {
return this;
}
@Override
public BigDecimal getAsBigDecimal() {
throw new java.lang.NumberFormatException();
}
@Override
public String getAsString() {
return _message;
}
@Override
public List<Integer> getDependencies() {
return new ArrayList<>();
}
@Override
public String getFormula(Snapshot snapshot) {
return _formula;
}
@Override
public boolean isDerived() {
return true;
}
}

View File

@ -0,0 +1,92 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value;
import java.math.BigDecimal;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
import org.vizierdb.database.value.formula.Formula;
import org.vizierdb.database.value.formula.FormulaNode;
/**
*
* @author heiko
*/
public class FormulaValue extends Value {
private final List<Integer> _dependencies;
private final FormulaNode _formula;
private final BigDecimal _value;
private String _text;
public FormulaValue(int valueIdentifier, FormulaNode formula, List<Integer> dependencies, CellSet cells) {
super(valueIdentifier);
_formula = formula;
_dependencies = dependencies;
BigDecimal value = null;
try {
value = _formula.eval(cells);
if (value != null) {
_text = value.toPlainString();
}
} catch (java.lang.NumberFormatException | java.lang.ArithmeticException ex) {
_text = Formula.ERROR_NOT_A_NUMBER;
}
_value = value;
}
@Override
public Value eval(CellSet cells) {
return new FormulaValue(this.getIdentifier(), _formula, _dependencies, cells);
}
@Override
public BigDecimal getAsBigDecimal() {
if ((_value == null) && (_text.equals(Formula.ERROR_NOT_A_NUMBER))) {
throw new java.lang.NumberFormatException();
} else {
return _value;
}
}
@Override
public String getAsString() {
return _text;
}
@Override
public List<Integer> getDependencies() {
return _dependencies;
}
@Override
public String getFormula(Snapshot snapshot) {
return "=" + _formula.toExternalForm(snapshot);
}
@Override
public boolean isDerived() {
return true;
}
}

View File

@ -0,0 +1,92 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value;
import java.math.BigDecimal;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
* A value in a spreadsheet cell. Each value has a unique identifier. THe value
* is either a constant or a formula.
*
* @author Heiko Mueller
*/
public abstract class Value {
private final int _identifier;
public Value(int identifier) {
_identifier = identifier;
}
/**
* Evaluate a formula. Only in effect for formula values. Returns the
* new value.
*
* @param cells
* @return
*/
public abstract Value eval(CellSet cells);
/**
* List of value identifier that this value is derived from.
*
* @return
*/
public abstract List<Integer> getDependencies();
/**
* The value as BigDecimal. May throw a NumberFormatException.
*
* @return
*/
public abstract BigDecimal getAsBigDecimal();
/**
* Text representation of the value.
*
* @return
*/
public abstract String getAsString();
/**
* Text representation of the values formula. The value is the same as the
* text for constant values.
*
* @param snapshot
* @return
*/
public abstract String getFormula(Snapshot snapshot);
/**
* Unique value identifier.
*
* @return
*/
public int getIdentifier() {
return _identifier;
}
/**
* Flag indicating whether the value is constant (false) or derived using
* a formula (true).
*
* @return
*/
public abstract boolean isDerived();
}

View File

@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import org.vizierdb.database.CellCoordinates;
import org.vizierdb.database.Snapshot;
/**
*
* @author heiko
*/
public interface CellReference {
/**
* The coordinates for the reference cell in the given snapshot. If either
* the referenced column or row are invalid the respective coordinate is
* UNKNOWN.
*
* @param snapshot
* @return
*/
public CellCoordinates getCoordinates(Snapshot snapshot);
/**
* Set the identifier of the value that is associated with the referenced
* cell.
*
* @param valueIdentifier
*/
public void setReferencedValue(int valueIdentifier);
}

View File

@ -0,0 +1,108 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.vizierdb.database.CellCoordinates;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Column;
import org.vizierdb.database.Snapshot;
import org.vizierdb.database.value.Value;
import org.vizierdb.util.SpreadsheetHelper;
/**
* Cell reference in formula. The column may be a reference to the name of a
* column in the spreadsheet or a spreadsheet column identifier.
*
* @author Heiko Mueller
*/
public class CellReferenceNode extends FormulaNode implements CellReference {
private final String _col;
private final boolean _isColumnName;
private int _referencedValueIdentifier = -1;
private final int _row;
public CellReferenceNode(String col, int row, boolean isColumnName) {
super(null, null);
_col = col;
_row = row;
_isColumnName = isColumnName;
}
@Override
public BigDecimal eval(CellSet cells) {
Value ref = cells.getValue(_referencedValueIdentifier);
if (ref != null) {
return ref.getAsBigDecimal();
} else {
return null;
}
}
@Override
public List<CellReference> getCellReferences() {
ArrayList<CellReference> references = new ArrayList<>();
references.add(this);
return references;
}
@Override
public CellCoordinates getCoordinates(Snapshot snapshot) {
int columnId = CellCoordinates.UNKNOWN_COLUMN;
int rowId = CellCoordinates.UNKNOWN_ROW;
if ((_row >= 0) && (_row < snapshot.getRows().size())) {
rowId = snapshot.getRows().get(_row);
if (_isColumnName) {
columnId = snapshot.getColumns().getIdentifierOf(_col);
} else {
int columnIndex = SpreadsheetHelper.getColumnIndex(_col);
if ((columnIndex >= 0) && (columnIndex < snapshot.getColumns().size())) {
columnId = snapshot.getColumns().get(columnIndex).getIdentifier();
}
}
}
return new CellCoordinates(columnId, rowId);
}
@Override
public void setReferencedValue(int valueIdentifier) {
_referencedValueIdentifier = valueIdentifier;
}
@Override
public String toExternalForm(Snapshot snapshot) {
CellCoordinates cell = snapshot.getCells().getCellForValue(_referencedValueIdentifier);
if (cell != null) {
Column column = snapshot.getColumns().getColumn(cell.getColumnId());
if (column.hasUniqueName()) {
return "[" + column.getName() + "," + snapshot.getRows().getDescriptiveName(cell.getRowId()) + "]";
} else {
return column.getLabel() + snapshot.getRows().getDescriptiveName(cell.getRowId());
}
} else {
return Formula.ERROR_UNKNOWN_NAME;
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
/**
* Collection of constants for formulas.
*
* @author Heiko Mueller
*/
public final class Formula {
public static final String ERROR_INVALID_REFERENCE = "#REF!";
public static final String ERROR_NOT_A_NUMBER = "#VALUE!";
public static final String ERROR_SYNTAX = "#SYNTAX!";
public static final String ERROR_UNKNOWN_NAME = "#NAME?";
}

View File

@ -0,0 +1,59 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import java.math.BigDecimal;
import java.util.List;
import org.parboiled.trees.ImmutableBinaryTreeNode;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
* The AST node for spreadsheet cell formulas. Internal nodes are operators
* while leave nodes represent scalars. These can either be constant values
* or cell references.
*/
public abstract class FormulaNode extends ImmutableBinaryTreeNode<FormulaNode> {
public FormulaNode(FormulaNode left, FormulaNode right) {
super(left, right);
}
/**
* Evaluates the formula. Returns null if any of the referenced cells is
* empty. Throws NuberFormatException if any of the referenced values is
* not a number.
*
* @param cells
* @return
*/
public abstract BigDecimal eval(CellSet cells);
/**
* List of all cell references by this node and all of it's
* children.
*
* @return
*/
public abstract List<CellReference> getCellReferences();
/**
* String representation of the formula for a given snapshot.
*
* @param snapshot
* @return
*/
public abstract String toExternalForm(Snapshot snapshot);
}

View File

@ -0,0 +1,181 @@
/*
* Copyright (C) 2009-2011 Mathias Doenitz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import java.math.BigDecimal;
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.BuildParseTree;
import org.parboiled.support.Var;
/**
* A calculator parser building an AST representing the expression structure before performing the actual calculation.
* The value field of the parse tree nodes is used for AST nodes.
* As opposed to the CalculatorParser2 this parser also supports floating point operations, negative numbers, a "power"
* and a "SQRT" operation as well as optional whitespace between the various expressions components.
* @param <V>
*/
@BuildParseTree
public class FormulaParser<V> extends BaseParser<FormulaNode> {
public Rule Formula() {
return Sequence(
'=',
Optional(Whitespace()),
Expression(),
EOI
);
}
public Rule Expression() {
Var<Character> op = new Var<>();
return Sequence(
Term(),
ZeroOrMore(
Optional(Whitespace()),
FirstOf('+', '-'),
op.set(matchedChar()),
Optional(Whitespace()),
Term(),
push(new OpNode(op.get(), pop(1), pop()))
)
);
}
public Rule Term() {
Var<Character> op = new Var<>();
return Sequence(
Factor(),
ZeroOrMore(
Optional(Whitespace()),
FirstOf('*', '/'),
op.set(matchedChar()),
Optional(Whitespace()),
Factor(),
push(new OpNode(op.get(), pop(1), pop()))
)
);
}
public Rule Factor() {
return Sequence(
Atom(),
ZeroOrMore(
Optional(Whitespace()),
'^',
Optional(Whitespace()),
Atom(),
push(new OpNode('^', pop(1), pop()))
)
);
}
public Rule Atom() {
return FirstOf(Number(), CellReference(), SquareRoot(), Parens());
}
public Rule CellReference() {
return FirstOf(SpreadsheetCell(), TableCell());
}
public Rule SpreadsheetCell() {
Var<String> col = new Var<>();
Var<String> row = new Var<>();
return Sequence(
OneOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'))),
col.set(matchOrDefault("").toUpperCase()),
OneOrMore(Digit()),
row.set(matchOrDefault("")),
push(new CellReferenceNode(col.get(), Integer.parseInt(row.get()), false))
);
}
public Rule TableCell() {
Var<String> col = new Var<>();
Var<String> row = new Var<>();
return Sequence(
'[',
Optional(Whitespace()),
OneOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), '-', '_')),
col.set(matchOrDefault("")),
Optional(Whitespace()),
',',
Optional(Whitespace()),
OneOrMore(Digit()),
row.set(matchOrDefault("")),
Optional(Whitespace()),
']',
push(new CellReferenceNode(col.get(), Integer.parseInt(row.get()), true))
);
}
public Rule SquareRoot() {
return Sequence(
"SQRT",
Optional(Whitespace()),
Parens(),
push(new OpNode('R', pop(), null))
);
}
public Rule Parens() {
return Sequence(
'(',
Optional(Whitespace()),
Expression(),
Optional(Whitespace()),
')');
}
public Rule Number() {
return Sequence(
// we use another Sequence in the "Number" Sequence so we can easily access the input text matched
// by the three enclosed rules with "match()" or "matchOrDefault()"
Sequence(
Optional('-'),
OneOrMore(Digit()),
Optional('.', OneOrMore(Digit()))
),
// the matchOrDefault() call returns the matched input text of the immediately preceding rule
// or a default string (in this case if it is run during error recovery (resynchronization))
push(new ValueNode(new BigDecimal(matchOrDefault("0")))),
Whitespace()
);
}
public Rule Digit() {
return CharRange('0', '9');
}
public Rule Whitespace() {
return ZeroOrMore(AnyOf(" \t\f"));
}
}

View File

@ -0,0 +1,100 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
* Internal operator node in the formula AST. Only node with a left and right
* child.
*
* @author Heiko Mueller
*/
public class OpNode extends FormulaNode {
private final Character _operator;
public OpNode(Character operator, FormulaNode left, FormulaNode right) {
super(left, right);
_operator = operator;
}
@Override
public List<CellReference> getCellReferences() {
ArrayList<CellReference> references = new ArrayList<>();
references.addAll(this.left().getCellReferences());
references.addAll(this.right().getCellReferences());
return references;
}
@Override
public BigDecimal eval(CellSet cells) {
BigDecimal left = this.left().eval(cells);
if (left == null) {
return null;
}
if (_operator == 'R') {
return new BigDecimal(Math.sqrt(left.doubleValue()));
} else {
BigDecimal right = this.right().eval(cells);
if (right == null) {
return null;
}
switch (_operator) {
case '+':
return left.add(right);
case '-':
return left.subtract(right);
case '*':
return left.multiply(right).setScale(Math.max(left.scale(), right.scale()), RoundingMode.CEILING);
case '/':
return left.divide(right, Math.max(left.scale(), right.scale()), RoundingMode.CEILING);
case '^':
return new BigDecimal(Math.pow(left.doubleValue(), right.doubleValue()));
default:
throw new IllegalStateException();
}
}
}
@Override
public String toExternalForm(Snapshot snapshot) {
switch (_operator) {
case '+':
return "(" + left().toExternalForm(snapshot) + " + " + right().toExternalForm(snapshot) + ")";
case '-':
return "(" + left().toExternalForm(snapshot) + " - " + right().toExternalForm(snapshot) + ")";
case '*':
return "(" + left().toExternalForm(snapshot) + " * " + right().toExternalForm(snapshot) + ")";
case '/':
return "(" + left().toExternalForm(snapshot) + " / " + right().toExternalForm(snapshot) + ")";
case '^':
return left().toExternalForm(snapshot) + "^" + right().toExternalForm(snapshot);
case 'R':
return "SQRT (" + left().toExternalForm(snapshot) + ")";
default:
throw new IllegalStateException();
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import org.parboiled.Parboiled;
import org.parboiled.errors.ErrorUtils;
import org.parboiled.parserunners.ReportingParseRunner;
import org.parboiled.support.ParsingResult;
import static org.parboiled.support.ParseTreeUtils.printNodeTree;
/**
*
* @author heiko
*/
public class ParserTest {
public static void main(String[] args) {
FormulaParser<FormulaNode> parser = Parboiled.createParser(FormulaParser.class);
ParsingResult<?> result = new ReportingParseRunner(parser.Formula()).run("= 2 + ( A3 ^ ( 2 ) - 1) * C2");
if (!result.parseErrors.isEmpty()) {
System.out.println(ErrorUtils.printParseError(result.parseErrors.get(0)));
} else {
System.out.println(printNodeTree(result) + '\n');
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.database.value.formula;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.vizierdb.database.CellSet;
import org.vizierdb.database.Snapshot;
/**
* Constant value node in formula AST.
*
* @author Heiko Mueller
*/
public class ValueNode extends FormulaNode {
private final BigDecimal _value;
public ValueNode(BigDecimal value) {
super(null, null);
_value = value;
}
@Override
public BigDecimal eval(CellSet cells) {
return _value;
}
@Override
public List<CellReference> getCellReferences() {
return new ArrayList<>();
}
@Override
public String toExternalForm(Snapshot snapshot) {
return _value.toPlainString();
}
}

View File

@ -48,6 +48,7 @@ import org.vizierdb.database.VizierDB;
import org.vizierdb.database.script.Operation;
import org.vizierdb.resources.ResourceManager;
import org.vizierdb.server.io.FileListingStream;
import org.vizierdb.server.io.ScriptSQLStatementStream;
/**
* The Vizier Database Web API Server.
@ -72,12 +73,12 @@ public class DatabaseServer {
/*
* Uncomment for local web server
*/
//_urls = new URLFactory("http://localhost:8080/vizier-db/api/v1");
_urls = new URLFactory("http://localhost:8080/vizier-db/api/v1");
/*
* Uncomment for current AWS deployment
*/
_urls = new URLFactory("http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com/api/v1");
//_urls = new URLFactory("http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com/api/v1");
_resources = new ResourceManager(new File(context.getRealPath("/WEB-INF/resources")));
_vdb = new SimpleVizierDBM(_resources);
@ -295,6 +296,39 @@ public class DatabaseServer {
}
}
/**
* Return the VizUAL script associated with a given branch as an array of
* SQL statements.
*
* @param notebookIdentifier Notebook identifier
* @param branchIdentifier Branch identifier
* @return
* @throws java.io.IOException
*/
@Path("/notebooks/{notebookIdentifier}/branches/{branchIdentifier}/script/sql")
@GET
@Produces({MediaType.APPLICATION_JSON})
public Response getBranchScriptSQLExport(@PathParam("notebookIdentifier") int notebookIdentifier, @PathParam("branchIdentifier") int branchIdentifier) throws java.io.IOException, javax.ws.rs.WebApplicationException {
VizUALScript script = null;
try {
script = _vdb.getScript(notebookIdentifier, branchIdentifier);
} catch (org.vizierdb.VizirDBException vizierException ){
Logger.getLogger(DatabaseServer.class.getName()).log(Level.SEVERE, null, vizierException);
throw new WebApplicationException(500);
}
if (script != null) {
try {
return Response.ok().entity(new ScriptSQLStatementStream(_vdb.getNotebook(notebookIdentifier), script)).type(MediaType.APPLICATION_JSON).build();
} catch (org.vizierdb.VizirDBException vizierException ){
Logger.getLogger(DatabaseServer.class.getName()).log(Level.SEVERE, null, vizierException);
throw new WebApplicationException(500);
}
} else {
throw new WebApplicationException(404);
}
}
/**
* Execute an operation on the head of the given branch.
*

View File

@ -44,6 +44,19 @@ public class URLFactory {
return this.getNotebookBranchURL(notebookIdentifier, branchIdentifier) + "/script";
}
/**
* URL referencing SQL translation of the script resource for a branch in a
* notebook.
*
* @param notebookIdentifier Notebook identifier
* @param branchIdentifier Branch identifier
* @return
*/
public String getBranchScriptSQLExportURL(int notebookIdentifier, int branchIdentifier) {
return this.getNotebookBranchURL(notebookIdentifier, branchIdentifier) + "/script/sql";
}
/**
* URL referencing script resource for a branch in a notebook.
*

View File

@ -24,6 +24,7 @@ import org.vizierdb.database.Cell;
import org.vizierdb.database.Column;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.Snapshot;
import org.vizierdb.database.value.Value;
import org.vizierdb.database.history.Branch;
import org.vizierdb.database.history.VGEdge;
import org.vizierdb.database.history.VGNode;
@ -200,7 +201,9 @@ public class ResourceStreamWriter implements AutoCloseable {
for (Column column : snapshot.getColumns()) {
_out.beginObject();
_out.name("name").value(column.getName());
_out.name("refName").value(snapshot.getColumns().getDescriptiveName(column.getIdentifier()));
_out.name("label").value(column.getLabel());
_out.name("isUniqueName").value(column.hasUniqueName());
_out.name("uniqueName").value(column.getDescriptiveName());
_out.endObject();
columnMapping.put(column.getIdentifier(), columnMapping.size());
}
@ -217,7 +220,13 @@ public class ResourceStreamWriter implements AutoCloseable {
_out.beginObject();
_out.name("col").value(columnMapping.get(cell.getColumnId()));
_out.name("row").value(rowMapping.get(cell.getRowId()));
_out.name("value").value(cell.getValue());
_out.name("value").beginObject();
Value value = cell.getValue();
_out.name("text").value(value.getAsString());
if (value.isDerived()) {
_out.name("formula").value(value.getFormula(snapshot));
}
_out.endObject();
_out.endObject();
}
_out.endArray();
@ -283,9 +292,9 @@ public class ResourceStreamWriter implements AutoCloseable {
_out.endObject();
VGEdge edge = node.getParent();
if (edge.hasTarget()) {
edges.add(new Edge(edge.getTarget().getSnapshotIdentifier(), edge.getStatement(), node.getSnapshotIdentifier()));
edges.add(new Edge(edge.getTarget().getSnapshotIdentifier(), edge.getVizUALStatement(), node.getSnapshotIdentifier()));
} else {
edges.add(new Edge(VizierDB.UNKNOWN_SNAPSHOT, edge.getStatement(), node.getSnapshotIdentifier()));
edges.add(new Edge(VizierDB.UNKNOWN_SNAPSHOT, edge.getVizUALStatement(), node.getSnapshotIdentifier()));
}
}
_out.endArray();

View File

@ -16,6 +16,7 @@ package org.vizierdb.server.io;
import java.io.OutputStream;
import javax.ws.rs.core.StreamingOutput;
import org.vizierdb.database.script.VizUALScript;
import org.vizierdb.server.ReferenceObject;
import org.vizierdb.server.URLFactory;
/**
@ -45,9 +46,12 @@ public class ScriptObjectStream implements StreamingOutput {
writer.getWriter().beginObject();
writer.getWriter().name("operations").beginArray();
for (int iOp = 0; iOp < _script.size(); iOp++) {
writer.writeOperation(_script.getStatement(iOp), _notebookIdentifier, _branchIdentifier, _script.getSnapshotIdentifier(iOp), _urls);
writer.writeOperation(_script.getVizUALStatement(iOp), _notebookIdentifier, _branchIdentifier, _script.getSnapshotIdentifier(iOp), _urls);
}
writer.getWriter().endArray();
writer.getWriter().name("links").beginArray();
writer.writeReference(new ReferenceObject("sql", _urls.getBranchScriptSQLExportURL(_notebookIdentifier, _branchIdentifier)));
writer.getWriter().endArray();
writer.getWriter().endObject();
}
}

View File

@ -0,0 +1,63 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.server.io;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.StreamingOutput;
import org.vizierdb.database.Column;
import org.vizierdb.database.ColumnList;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.script.VizUALScript;
import org.vizierdb.sql.MimirAdaptor;
/**
*
* @author heiko
*/
public class ScriptSQLStatementStream implements StreamingOutput{
private final Notebook _notebook;
private final VizUALScript _script;
public ScriptSQLStatementStream(Notebook notebook, VizUALScript script) {
_script = script;
_notebook = notebook;
}
@Override
public void write(OutputStream out) throws java.io.IOException, javax.ws.rs.WebApplicationException {
try (ResourceStreamWriter writer = new ResourceStreamWriter(out)) {
writer.getWriter().beginObject();
writer.getWriter().name("operations").beginArray();
for (int iOp = 0; iOp < _script.size(); iOp++) {
writer.getWriter().beginObject();
writer.getWriter().name("sql").value(_script.getSQLStatement(iOp));
writer.getWriter().endObject();
}
writer.getWriter().endArray();
try {
writer.getWriter().name("mimir").value(MimirAdaptor.compileToSQL(_notebook));
} catch (org.vizierdb.VizirDBException ex) {
writer.getWriter().name("mimir").value(ex.getMessage());
}
writer.getWriter().endObject();
}
}
}

View File

@ -0,0 +1,188 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizierdb.sql;
import java.util.*;
import scala.Enumeration;
import org.vizierdb.*;
import org.vizierdb.database.*;
import org.vizierdb.database.history.*;
import org.vizierdb.database.script.*;
import org.vizierdb.database.script.op.*;
import mimir.algebra.Table;
import mimir.algebra.Project;
import mimir.algebra.ProjectArg;
import mimir.algebra.Select;
import mimir.algebra.Union;
/**
* A script in VizUAL is a sequence of operations. Each operation generates a
* new snapshot. Operations and generated snapshot identifiers are recorded as
* part of the script.
*
* @author Oliver Kennedy
*/
public class MimirAdaptor {
public static <A, B> scala.collection.immutable.Map<A, B> toScalaMap(Map<A, B> m) {
return scala.collection.JavaConverters.mapAsScalaMapConverter(m).asScala().toMap(
scala.Predef.<scala.Tuple2<A, B>>conforms()
);
}
public static scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> makeMimirSchema(Collection<String> cols)
{
return makeMimirSchema(cols, mimir.algebra.Type.withName("TString"));
}
public static scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> makeMimirSchema(Collection<String> cols, scala.Enumeration.Value t)
{
scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> ret =
scala.collection.immutable.List$.MODULE$.empty();
for(String col : cols){
ret = new scala.collection.immutable.$colon$colon<scala.Tuple2<String,scala.Enumeration.Value>>(
new scala.Tuple2<String,scala.Enumeration.Value>(col, t), ret
);
}
return ret;
}
public static mimir.algebra.Operator compileToRA(VizUALScript script, Map<String, List<String>> schemas)
{
mimir.algebra.Operator raTree = null;
ColumnList cols = new ColumnList();
int colIdx = 0;
BitSet deleted = new BitSet();
for(int x = 0; x < script.size(); x++){
Operation step = script.getOperation(x);
// System.out.println("CONVERT: "+step);
if(step instanceof CellUpdate){
CellUpdate update = (CellUpdate)step;
String targetCol = cols.get(update.getColumnId()).getName();
raTree = mimir.algebra.OperatorUtils$.MODULE$.replaceColumn(
targetCol,
(mimir.algebra.Expression)(new mimir.algebra.Conditional(
new mimir.algebra.Comparison(
mimir.algebra.Cmp.withName("Eq"),
new mimir.algebra.Var("ROWID_MIMIR"),
new mimir.algebra.RowIdPrimitive(""+update.getRowId())
),
new mimir.algebra.StringPrimitive(update.getValue()),
new mimir.algebra.Var(targetCol)
)),
raTree
);
} else if(step instanceof ColumnDelete){
ColumnDelete delete = (ColumnDelete)step;
String targetCol = cols.get(delete.getColumnId()).getName();
// System.out.println("Deleting "+ targetCol);
raTree = mimir.algebra.OperatorUtils$.MODULE$.projectAwayColumn(targetCol, raTree);
deleted.set(delete.getColumnId());
} else if(step instanceof ColumnInsert){
ColumnInsert insert = (ColumnInsert)step;
raTree = mimir.algebra.OperatorUtils$.MODULE$.projectInColumn(insert.getName(), new mimir.algebra.NullPrimitive(), raTree);
cols.add(colIdx++, insert.getName());
} else if(step instanceof ColumnMove){
//ignore positions for now
} else if(step instanceof ColumnRename){
ColumnRename rename = (ColumnRename)step;
String targetCol = cols.get(rename.getColumnId()).getName();
raTree = mimir.algebra.OperatorUtils$.MODULE$.renameColumn(targetCol, rename.getName(), raTree);
cols.renameColumn(rename.getColumnId(), rename.getName());
} else if(step instanceof CSVFileLoad){
String relName = ((CSVFileLoad)step).getFileName().replaceFirst("\\..*$", "");
colIdx = 0;
cols = new ColumnList();
for(String col : schemas.get(relName)){
cols.add(colIdx++, col);
}
raTree = new mimir.algebra.Table(relName,
makeMimirSchema(schemas.get(relName)),
makeMimirSchema(Arrays.asList("ROWID_MIMIR"), mimir.algebra.Type.withName("TRowId"))
);
} else if(step instanceof RowDelete){
RowDelete delete = (RowDelete)step;
raTree = new mimir.algebra.Select(
(mimir.algebra.Expression)(new mimir.algebra.Comparison(
mimir.algebra.Cmp.withName("Neq"),
new mimir.algebra.Var("ROWID_MIMIR"),
new mimir.algebra.RowIdPrimitive(""+delete.getRowId())
)),
raTree
);
} else if(step instanceof RowInsert){
mimir.algebra.Operator dual = new mimir.algebra.Table("dual",
makeMimirSchema(schemas.get("dual")),
makeMimirSchema(Arrays.asList("ROWID_MIMIR"), mimir.algebra.Type.withName("TRowId"))
);
for(int i = 0; i < colIdx; i++){
if(!deleted.get(i)){
dual = mimir.algebra.OperatorUtils$.MODULE$.projectInColumn(cols.getColumn(i).getName(), new mimir.algebra.NullPrimitive(), dual);
}
}
dual = mimir.optimizer.InlineProjections$.MODULE$.optimize(dual);
raTree = new mimir.algebra.Union(dual, raTree);
} else if(step instanceof RowMove){
} else {
}
}
return mimir.algebra.OperatorUtils$.MODULE$.projectAwayColumn("ROWID_MIMIR", raTree);
}
public static String compileToSQL(mimir.algebra.Operator raTree, Map<String, List<String>> schemas)
{
Map<String,
scala.collection.immutable.List<
scala.Tuple2<String,scala.Enumeration.Value>>> scalaSchemas = new HashMap<>();
for(Map.Entry<String, List<String>> table : schemas.entrySet()){
scalaSchemas.put(table.getKey(), makeMimirSchema(table.getValue()));
}
mimir.Database db = new mimir.Database("Test DB",
new mimir.sql.NullBackend(toScalaMap(scalaSchemas)));
return db.convert(raTree).toString();
}
public static String compileToSQL(VizUALScript script, Map<String, List<String>> schemas)
{
return compileToSQL(compileToRA(script, schemas), schemas);
}
public static String compileToSQL(Notebook notebook)
throws VizirDBException
{
VersionGraph history = notebook.getHistory();
VizUALScript script = history.getScript(history.getCurrentBranch().getIdentifier());
CSVFileLoad load = (CSVFileLoad)script.getOperation(0);
ColumnList cols = load.exec(notebook, null, 0).getColumns();
List<String> colNames = new ArrayList<String>();
for(Column col : cols){ colNames.add(col.getName()); }
Map<String, List<String>> schemas = new HashMap<String, List<String>>();
String tableName = load.getFileName().replaceFirst("\\..*$", "");
schemas.put(tableName, colNames);
schemas.put("dual", new ArrayList<String>());
return compileToSQL(script, schemas);
}
public static class UnsupportedFeature extends Exception {
public UnsupportedFeature(String msg) { super(msg); }
}
}

View File

@ -19,7 +19,38 @@ package org.vizierdb.util;
* @author Heiko Mueller
*/
public final class SpreadsheetHelper {
/**
* The index position (starting at 1) derived from a given spreadsheet
* column name.
*
* @param name
* @return
*/
public static int getColumnIndex(String name) {
int columnIndex = 0;
for (int iPos = 0; iPos < name.length(); iPos++) {
char c = name.charAt((name.length() - 1) - iPos);
int index = c - 'A';
if ((index < 0) || (index > 26)) {
throw new java.lang.IllegalArgumentException(name);
}
if (iPos > 0) {
index++;
}
columnIndex += (Math.pow(26, iPos) * index);
}
return columnIndex;
}
/**
* The spreadsheet name of the column. Columns in spreadsheets are name
* with strings starting at A, B, C, ... AA, AB, AC, ....
*
* @param columnIndex
* @return
*/
public static String getColumnName(int columnIndex) {
if (columnIndex < 0) {

View File

@ -49,93 +49,3 @@ site oel_tthm_g_l_a lraa_haa5_g_l_b oel_haa5_g_l_b location result_haa5_g_l_b sa
33450 36 32 34 "SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\""" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 44 37 2015-05-05T00:00:00
33950 34 32 34 "SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\""" 41 2015-05-05T00:00:00 2015-05-08T00:00:00 43 36 2015-05-05T00:00:00
37950 27 30 32 "SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\""" 37 2015-05-05T00:00:00 2015-05-09T00:00:00 30 33 2015-05-05T00:00:00
38250 29 32 33 "SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\""" 37 2015-05-05T00:00:00 2015-05-13T00:00:00 32 34 2015-05-05T00:00:00
39650 27 31 31 "SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\""" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 27 32 2015-05-05T00:00:00
44350 28 29 30 "SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\""" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 29 31 2015-05-05T00:00:00
45250 27 33 32 "SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\""" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 30 29 2015-05-05T00:00:00
50250 26 39 34 "SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\""" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
50750 35 37 34 "SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\""" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 39 38 2015-05-06T00:00:00
50850 30 40 37 "SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\""" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 32 33 2015-05-06T00:00:00
52050 32 38 35 "SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\""" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 33 35 2015-05-05T00:00:00
58650 34 39 36 "SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\""" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 36 37 2015-05-06T00:00:00
77650 27 32 31 SS - OPP 110-52 E/S 207th St 34 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
15150 26 28 29 "SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\""" 34 2015-05-05T00:00:00 2015-05-07T00:00:00 30 30 2015-05-06T00:00:00
18650 22 29 29 "SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\""" 34 2015-05-05T00:00:00 2015-05-07T00:00:00 25 24 2015-05-06T00:00:00
23450 31 30 31 "SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\""" 36 2015-05-05T00:00:00 2015-05-08T00:00:00 39 31 2015-05-06T00:00:00
24350 32 32 34 "SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\""" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 36 34 2015-05-05T00:00:00
31750 36 31 33 "SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\""" 39 2015-05-05T00:00:00 2015-05-08T00:00:00 42 37 2015-05-05T00:00:00
31850 34 30 32 "SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\""" 38 2015-05-05T00:00:00 2015-05-08T00:00:00 41 36 2015-05-05T00:00:00
32350 33 31 33 "SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\""" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 39 36 2015-05-05T00:00:00
33450 36 32 34 "SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\""" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 44 37 2015-05-05T00:00:00
33950 34 32 34 "SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\""" 41 2015-05-05T00:00:00 2015-05-08T00:00:00 43 36 2015-05-05T00:00:00
37950 27 30 32 "SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\""" 37 2015-05-05T00:00:00 2015-05-09T00:00:00 30 33 2015-05-05T00:00:00
38250 29 32 33 "SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\""" 37 2015-05-05T00:00:00 2015-05-13T00:00:00 32 34 2015-05-05T00:00:00
39650 27 31 31 "SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\""" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 27 32 2015-05-05T00:00:00
44350 28 29 30 "SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\""" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 29 31 2015-05-05T00:00:00
45250 27 33 32 "SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\""" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 30 29 2015-05-05T00:00:00
50250 26 39 34 "SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\""" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
50750 35 37 34 "SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\""" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 39 38 2015-05-06T00:00:00
50850 30 40 37 "SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\""" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 32 33 2015-05-06T00:00:00
52050 32 38 35 "SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\""" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 33 35 2015-05-05T00:00:00
58650 34 39 36 "SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\""" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 36 37 2015-05-06T00:00:00
77650 27 32 31 SS - OPP 110-52 E/S 207th St 34 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
15150 40 28 29 "SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\""" 30 2015-08-04T00:00:00 2015-08-08T00:00:00 58 33 2015-08-06T00:00:00
18650 30 27 27 "SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\""" 27 2015-08-04T00:00:00 2015-08-08T00:00:00 40 26 2015-08-06T00:00:00
23450 41 29 30 "SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\""" 30 2015-08-04T00:00:00 2015-08-08T00:00:00 54 35 2015-08-06T00:00:00
24350 44 32 32 "SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\""" 32 2015-08-04T00:00:00 2015-08-08T00:00:00 61 38 2015-08-07T00:00:00
31750 39 31 33 "SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\""" 32 2015-08-04T00:00:00 2015-08-08T00:00:00 46 37 2015-08-07T00:00:00
31850 44 29 30 "SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\""" 28 2015-08-04T00:00:00 2015-08-08T00:00:00 60 39 2015-08-07T00:00:00
32350 42 30 30 "SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\""" 28 2015-08-04T00:00:00 2015-08-08T00:00:00 56 37 2015-08-07T00:00:00
33450 33 30 29 "SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\""" 25 2015-08-04T00:00:00 2015-08-08T00:00:00 36 34 2015-08-07T00:00:00
33950 33 30 29 "SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\""" 25 2015-08-04T00:00:00 2015-08-08T00:00:00 37 33 2015-08-07T00:00:00
37950 36 30 31 "SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\""" 31 2015-08-04T00:00:00 2015-08-10T00:00:00 48 32 2015-08-07T00:00:00
38250 41 32 33 "SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\""" 35 2015-08-19T00:00:00 2015-08-10T00:00:00 57 35 2015-08-21T00:00:00
39650 35 31 32 "SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\""" 34 2015-08-04T00:00:00 2015-08-11T00:00:00 49 32 2015-08-07T00:00:00
44350 27 30 30 "SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\""" 32 2015-08-04T00:00:00 2015-08-11T00:00:00 31 28 2015-08-07T00:00:00
45250 38 30 30 "SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\""" 28 2015-08-04T00:00:00 2015-08-11T00:00:00 53 32 2015-08-07T00:00:00
50250 33 36 37 "SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\""" 43 2015-08-19T00:00:00 2015-08-11T00:00:00 43 30 2015-08-21T00:00:00
50750 46 33 31 "SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\""" 30 2015-08-04T00:00:00 2015-08-11T00:00:00 62 40 2015-08-07T00:00:00
50850 39 36 35 "SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\""" 35 2015-08-04T00:00:00 2015-08-11T00:00:00 53 35 2015-08-07T00:00:00
52050 41 34 33 "SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\""" 31 2015-08-04T00:00:00 2015-08-11T00:00:00 56 38 2015-08-07T00:00:00
58650 40 36 36 "SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\""" 38 2015-08-04T00:00:00 2015-08-10T00:00:00 50 37 2015-08-07T00:00:00
77650 32 30 30 SS - OPP 110-52 E/S 207th St 31 2015-08-04T00:00:00 2015-08-10T00:00:00 42 30 2015-08-07T00:00:00
15150 44 33 39 "SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\""" 45 2015-11-04T00:00:00 2015-11-05T00:00:00 44 37 2015-11-06T00:00:00
18650 34 30 34 "SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\""" 37 2015-11-04T00:00:00 2015-11-20T00:00:00 35 28 2015-11-06T00:00:00
23450 42 32 35 "SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\""" 37 2015-11-04T00:00:00 2015-11-05T00:00:00 38 37 2015-11-06T00:00:00
24350 44 33 36 "SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\""" 35 2015-11-04T00:00:00 2015-11-07T00:00:00 39 38 2015-11-05T00:00:00
31750 46 31 30 "SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\""" 25 2015-11-04T00:00:00 2015-11-07T00:00:00 47 39 2015-11-05T00:00:00
31850 50 31 34 "SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\""" 35 2015-11-04T00:00:00 2015-11-09T00:00:00 50 42 2015-11-06T00:00:00
32350 47 31 33 "SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\""" 31 2015-11-04T00:00:00 2015-11-07T00:00:00 47 40 2015-11-05T00:00:00
33450 39 29 30 "SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\""" 27 2015-11-04T00:00:00 2015-11-11T00:00:00 37 34 2015-11-06T00:00:00
33950 39 29 31 "SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\""" 28 2015-11-04T00:00:00 2015-11-11T00:00:00 37 33 2015-11-06T00:00:00
37950 44 30 31 "SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\""" 28 2015-11-04T00:00:00 2015-11-07T00:00:00 48 36 2015-11-06T00:00:00
38250 48 37 44 "SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\""" 51 2015-11-04T00:00:00 2015-11-11T00:00:00 51 39 2015-11-06T00:00:00
39650 44 34 39 "SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\""" 42 2015-11-04T00:00:00 2015-11-11T00:00:00 49 35 2015-11-06T00:00:00
44350 33 31 34 "SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\""" 35 2015-11-04T00:00:00 2015-11-05T00:00:00 35 28 2015-11-05T00:00:00
45250 38 31 32 "SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\""" 33 2015-11-04T00:00:00 2015-11-07T00:00:00 34 34 2015-11-05T00:00:00
50250 37 36 38 "SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\""" 36 2015-11-04T00:00:00 2015-11-07T00:00:00 38 31 2015-11-05T00:00:00
50750 49 29 27 "SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\""" 22 2015-11-04T00:00:00 2015-11-07T00:00:00 47 42 2015-11-06T00:00:00
50850 42 34 35 "SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\""" 33 2015-11-04T00:00:00 2015-11-09T00:00:00 42 36 2015-11-05T00:00:00
52050 45 31 30 "SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\""" 25 2015-11-04T00:00:00 2015-11-07T00:00:00 45 38 2015-11-05T00:00:00
58650 45 34 34 "SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\""" 31 2015-11-04T00:00:00 2015-11-09T00:00:00 46 39 2015-11-05T00:00:00
77650 36 31 33 SS - OPP 110-52 E/S 207th St 33 2015-11-04T00:00:00 2015-11-07T00:00:00 37 31 2015-11-05T00:00:00
15150 43 36 36 "SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\""" 35 2016-02-02T00:00:00 2016-02-04T00:00:00 34 42 2016-02-03T00:00:00
18650 30 31 29 "SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\""" 25 2016-02-02T00:00:00 2016-02-05T00:00:00 23 31 2016-02-02T00:00:00
23450 37 33 31 "SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\""" 29 2016-02-02T00:00:00 2016-02-05T00:00:00 27 40 2016-02-02T00:00:00
24350 44 36 35 "SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\""" 36 2016-02-02T00:00:00 2016-02-05T00:00:00 38 44 2016-02-02T00:00:00
31750 42 31 28 "SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\""" 27 2016-02-02T00:00:00 2016-02-06T00:00:00 38 43 2016-02-02T00:00:00
31850 47 33 30 "SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\""" 29 2016-02-02T00:00:00 2016-02-06T00:00:00 38 47 2016-02-02T00:00:00
32350 44 34 32 "SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\""" 35 2016-02-02T00:00:00 2016-02-06T00:00:00 37 45 2016-02-03T00:00:00
33450 31 29 24 "SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\""" 22 2016-02-02T00:00:00 2016-02-06T00:00:00 25 36 2016-02-03T00:00:00
33950 31 29 24 "SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\""" 22 2016-02-02T00:00:00 2016-02-06T00:00:00 25 36 2016-02-03T00:00:00
37950 45 33 33 "SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\""" 36 2016-02-02T00:00:00 2016-02-06T00:00:00 41 42 2016-02-03T00:00:00
38250 47 41 42 "SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\""" 40 2016-02-02T00:00:00 2016-02-06T00:00:00 39 45 2016-02-03T00:00:00
39650 43 37 37 "SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\""" 36 2016-02-02T00:00:00 2016-02-08T00:00:00 37 41 2016-02-03T00:00:00
44350 38 36 38 "SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\""" 42 2016-02-02T00:00:00 2016-02-08T00:00:00 42 34 2016-02-03T00:00:00
45250 35 32 31 "SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\""" 31 2016-02-02T00:00:00 2016-02-09T00:00:00 26 36 2016-02-03T00:00:00
50250 33 37 36 "SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\""" 32 2016-02-02T00:00:00 2016-02-09T00:00:00 26 34 2016-02-03T00:00:00
50750 42 30 31 "SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\""" 35 2016-02-02T00:00:00 2016-02-09T00:00:00 29 44 2016-02-03T00:00:00
50850 38 35 34 "SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\""" 33 2016-02-02T00:00:00 2016-02-09T00:00:00 28 39 2016-02-03T00:00:00
52050 40 32 31 "SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\""" 34 2016-02-02T00:00:00 2016-02-09T00:00:00 30 41 2016-02-03T00:00:00
58650 41 35 35 "SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\""" 35 2016-02-02T00:00:00 2016-02-09T00:00:00 34 42 2016-02-03T00:00:00
77650 32 32 31 SS - OPP 110-52 E/S 207th St 29 2016-02-02T00:00:00 2016-02-09T00:00:00 24 33 2016-02-03T00:00:00

1 site oel_tthm_g_l_a lraa_haa5_g_l_b oel_haa5_g_l_b location result_haa5_g_l_b sample_date analysis_date_haa5_g_l_b result_tthm_g_l_a lraa_tthm_g_l_a analysis_date_tthm_g_l_a
49 33450 36 32 34 SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 44 37 2015-05-05T00:00:00
50 33950 34 32 34 SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\" 41 2015-05-05T00:00:00 2015-05-08T00:00:00 43 36 2015-05-05T00:00:00
51 37950 27 30 32 SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\" 37 2015-05-05T00:00:00 2015-05-09T00:00:00 30 33 2015-05-05T00:00:00
38250 29 32 33 SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\" 37 2015-05-05T00:00:00 2015-05-13T00:00:00 32 34 2015-05-05T00:00:00
39650 27 31 31 SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 27 32 2015-05-05T00:00:00
44350 28 29 30 SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 29 31 2015-05-05T00:00:00
45250 27 33 32 SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 30 29 2015-05-05T00:00:00
50250 26 39 34 SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
50750 35 37 34 SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 39 38 2015-05-06T00:00:00
50850 30 40 37 SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 32 33 2015-05-06T00:00:00
52050 32 38 35 SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 33 35 2015-05-05T00:00:00
58650 34 39 36 SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 36 37 2015-05-06T00:00:00
77650 27 32 31 SS - OPP 110-52 E/S 207th St 34 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
15150 26 28 29 SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\" 34 2015-05-05T00:00:00 2015-05-07T00:00:00 30 30 2015-05-06T00:00:00
18650 22 29 29 SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\" 34 2015-05-05T00:00:00 2015-05-07T00:00:00 25 24 2015-05-06T00:00:00
23450 31 30 31 SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\" 36 2015-05-05T00:00:00 2015-05-08T00:00:00 39 31 2015-05-06T00:00:00
24350 32 32 34 SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 36 34 2015-05-05T00:00:00
31750 36 31 33 SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\" 39 2015-05-05T00:00:00 2015-05-08T00:00:00 42 37 2015-05-05T00:00:00
31850 34 30 32 SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\" 38 2015-05-05T00:00:00 2015-05-08T00:00:00 41 36 2015-05-05T00:00:00
32350 33 31 33 SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 39 36 2015-05-05T00:00:00
33450 36 32 34 SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\" 40 2015-05-05T00:00:00 2015-05-08T00:00:00 44 37 2015-05-05T00:00:00
33950 34 32 34 SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\" 41 2015-05-05T00:00:00 2015-05-08T00:00:00 43 36 2015-05-05T00:00:00
37950 27 30 32 SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\" 37 2015-05-05T00:00:00 2015-05-09T00:00:00 30 33 2015-05-05T00:00:00
38250 29 32 33 SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\" 37 2015-05-05T00:00:00 2015-05-13T00:00:00 32 34 2015-05-05T00:00:00
39650 27 31 31 SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 27 32 2015-05-05T00:00:00
44350 28 29 30 SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 29 31 2015-05-05T00:00:00
45250 27 33 32 SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 30 29 2015-05-05T00:00:00
50250 26 39 34 SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\" 36 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
50750 35 37 34 SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\" 33 2015-05-05T00:00:00 2015-05-09T00:00:00 39 38 2015-05-06T00:00:00
50850 30 40 37 SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 32 33 2015-05-06T00:00:00
52050 32 38 35 SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\" 38 2015-05-05T00:00:00 2015-05-09T00:00:00 33 35 2015-05-05T00:00:00
58650 34 39 36 SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\" 35 2015-05-05T00:00:00 2015-05-09T00:00:00 36 37 2015-05-06T00:00:00
77650 27 32 31 SS - OPP 110-52 E/S 207th St 34 2015-05-05T00:00:00 2015-05-09T00:00:00 28 30 2015-05-05T00:00:00
15150 40 28 29 SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\" 30 2015-08-04T00:00:00 2015-08-08T00:00:00 58 33 2015-08-06T00:00:00
18650 30 27 27 SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\" 27 2015-08-04T00:00:00 2015-08-08T00:00:00 40 26 2015-08-06T00:00:00
23450 41 29 30 SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\" 30 2015-08-04T00:00:00 2015-08-08T00:00:00 54 35 2015-08-06T00:00:00
24350 44 32 32 SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\" 32 2015-08-04T00:00:00 2015-08-08T00:00:00 61 38 2015-08-07T00:00:00
31750 39 31 33 SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\" 32 2015-08-04T00:00:00 2015-08-08T00:00:00 46 37 2015-08-07T00:00:00
31850 44 29 30 SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\" 28 2015-08-04T00:00:00 2015-08-08T00:00:00 60 39 2015-08-07T00:00:00
32350 42 30 30 SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\" 28 2015-08-04T00:00:00 2015-08-08T00:00:00 56 37 2015-08-07T00:00:00
33450 33 30 29 SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\" 25 2015-08-04T00:00:00 2015-08-08T00:00:00 36 34 2015-08-07T00:00:00
33950 33 30 29 SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\" 25 2015-08-04T00:00:00 2015-08-08T00:00:00 37 33 2015-08-07T00:00:00
37950 36 30 31 SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\" 31 2015-08-04T00:00:00 2015-08-10T00:00:00 48 32 2015-08-07T00:00:00
38250 41 32 33 SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\" 35 2015-08-19T00:00:00 2015-08-10T00:00:00 57 35 2015-08-21T00:00:00
39650 35 31 32 SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\" 34 2015-08-04T00:00:00 2015-08-11T00:00:00 49 32 2015-08-07T00:00:00
44350 27 30 30 SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\" 32 2015-08-04T00:00:00 2015-08-11T00:00:00 31 28 2015-08-07T00:00:00
45250 38 30 30 SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\" 28 2015-08-04T00:00:00 2015-08-11T00:00:00 53 32 2015-08-07T00:00:00
50250 33 36 37 SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\" 43 2015-08-19T00:00:00 2015-08-11T00:00:00 43 30 2015-08-21T00:00:00
50750 46 33 31 SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\" 30 2015-08-04T00:00:00 2015-08-11T00:00:00 62 40 2015-08-07T00:00:00
50850 39 36 35 SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\" 35 2015-08-04T00:00:00 2015-08-11T00:00:00 53 35 2015-08-07T00:00:00
52050 41 34 33 SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\" 31 2015-08-04T00:00:00 2015-08-11T00:00:00 56 38 2015-08-07T00:00:00
58650 40 36 36 SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\" 38 2015-08-04T00:00:00 2015-08-10T00:00:00 50 37 2015-08-07T00:00:00
77650 32 30 30 SS - OPP 110-52 E/S 207th St 31 2015-08-04T00:00:00 2015-08-10T00:00:00 42 30 2015-08-07T00:00:00
15150 44 33 39 SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\" 45 2015-11-04T00:00:00 2015-11-05T00:00:00 44 37 2015-11-06T00:00:00
18650 34 30 34 SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\" 37 2015-11-04T00:00:00 2015-11-20T00:00:00 35 28 2015-11-06T00:00:00
23450 42 32 35 SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\" 37 2015-11-04T00:00:00 2015-11-05T00:00:00 38 37 2015-11-06T00:00:00
24350 44 33 36 SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\" 35 2015-11-04T00:00:00 2015-11-07T00:00:00 39 38 2015-11-05T00:00:00
31750 46 31 30 SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\" 25 2015-11-04T00:00:00 2015-11-07T00:00:00 47 39 2015-11-05T00:00:00
31850 50 31 34 SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\" 35 2015-11-04T00:00:00 2015-11-09T00:00:00 50 42 2015-11-06T00:00:00
32350 47 31 33 SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\" 31 2015-11-04T00:00:00 2015-11-07T00:00:00 47 40 2015-11-05T00:00:00
33450 39 29 30 SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\" 27 2015-11-04T00:00:00 2015-11-11T00:00:00 37 34 2015-11-06T00:00:00
33950 39 29 31 SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\" 28 2015-11-04T00:00:00 2015-11-11T00:00:00 37 33 2015-11-06T00:00:00
37950 44 30 31 SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\" 28 2015-11-04T00:00:00 2015-11-07T00:00:00 48 36 2015-11-06T00:00:00
38250 48 37 44 SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\" 51 2015-11-04T00:00:00 2015-11-11T00:00:00 51 39 2015-11-06T00:00:00
39650 44 34 39 SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\" 42 2015-11-04T00:00:00 2015-11-11T00:00:00 49 35 2015-11-06T00:00:00
44350 33 31 34 SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\" 35 2015-11-04T00:00:00 2015-11-05T00:00:00 35 28 2015-11-05T00:00:00
45250 38 31 32 SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\" 33 2015-11-04T00:00:00 2015-11-07T00:00:00 34 34 2015-11-05T00:00:00
50250 37 36 38 SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\" 36 2015-11-04T00:00:00 2015-11-07T00:00:00 38 31 2015-11-05T00:00:00
50750 49 29 27 SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\" 22 2015-11-04T00:00:00 2015-11-07T00:00:00 47 42 2015-11-06T00:00:00
50850 42 34 35 SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\" 33 2015-11-04T00:00:00 2015-11-09T00:00:00 42 36 2015-11-05T00:00:00
52050 45 31 30 SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\" 25 2015-11-04T00:00:00 2015-11-07T00:00:00 45 38 2015-11-05T00:00:00
58650 45 34 34 SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\" 31 2015-11-04T00:00:00 2015-11-09T00:00:00 46 39 2015-11-05T00:00:00
77650 36 31 33 SS - OPP 110-52 E/S 207th St 33 2015-11-04T00:00:00 2015-11-07T00:00:00 37 31 2015-11-05T00:00:00
15150 43 36 36 SS - IFO 1420 E/S Grand Concourse, 1st SS S/O E 171st St, 20\" 35 2016-02-02T00:00:00 2016-02-04T00:00:00 34 42 2016-02-03T00:00:00
18650 30 31 29 SS - N/S Dewey Ave, btw Quincy & Swinton Aves, 12\" 25 2016-02-02T00:00:00 2016-02-05T00:00:00 23 31 2016-02-02T00:00:00
23450 37 33 31 SS - N/S Jefferson Avenue, 2nd SS W/O Lewis Avenue, 20\" 29 2016-02-02T00:00:00 2016-02-05T00:00:00 27 40 2016-02-02T00:00:00
24350 44 36 35 SS - W/S Brighton 11th Street, 2nd SS S/O Cass Place, 12\" 36 2016-02-02T00:00:00 2016-02-05T00:00:00 38 44 2016-02-02T00:00:00
31750 42 31 28 SS - IFO 427 N/S W 26th St, 2nd SS W/O 9th Ave, 12\" 27 2016-02-02T00:00:00 2016-02-06T00:00:00 38 43 2016-02-02T00:00:00
31850 47 33 30 SS - IFO 82 S/S Warren St, 2nd SS E/O Greenwich St, 12\" 29 2016-02-02T00:00:00 2016-02-06T00:00:00 38 47 2016-02-02T00:00:00
32350 44 34 32 SS - IFO 116 E/S Ave C, 2nd SS N/O E 7th St, 12\" 35 2016-02-02T00:00:00 2016-02-06T00:00:00 37 45 2016-02-03T00:00:00
33450 31 29 24 SS - IFO 135 N/S W 112th St, 2nd SS W/O St Nicholas Ave, 12\" 22 2016-02-02T00:00:00 2016-02-06T00:00:00 25 36 2016-02-03T00:00:00
33950 31 29 24 SS - N/S E 104th Street, 2nd SS E/O 3rd Avenue, 12\" 22 2016-02-02T00:00:00 2016-02-06T00:00:00 25 36 2016-02-03T00:00:00
37950 45 33 33 SS - IFO 325 N/S E 12th Street, 2nd SS E/O 2nd Ave, 12\" 36 2016-02-02T00:00:00 2016-02-06T00:00:00 41 42 2016-02-03T00:00:00
38250 47 41 42 SS - IFO 309 N/S E 87th St, 2nd SS W/O 1st Ave, 12\" 40 2016-02-02T00:00:00 2016-02-06T00:00:00 39 45 2016-02-03T00:00:00
39650 43 37 37 SS - IFO 229 N/S E 49th St, 2nd SS W/O 2nd Ave, 12\" 36 2016-02-02T00:00:00 2016-02-08T00:00:00 37 41 2016-02-03T00:00:00
44350 38 36 38 SS - IFO 21-55 N/S 34th Ave, 1st SS W/O 24th St, 12\" 42 2016-02-02T00:00:00 2016-02-08T00:00:00 42 34 2016-02-03T00:00:00
45250 35 32 31 SS - E/S Beach 58th St, 2nd SS N/O Beach Channel Drive, 12\" 31 2016-02-02T00:00:00 2016-02-09T00:00:00 26 36 2016-02-03T00:00:00
50250 33 37 36 SS - IFO 937 N/S Victory Blvd, 2nd SS E/O Highland Ave, 20\" 32 2016-02-02T00:00:00 2016-02-09T00:00:00 26 34 2016-02-03T00:00:00
50750 42 30 31 SS - E/S Woodhull Ave, 1st SS S/O Albourne Ave, 8\" 35 2016-02-02T00:00:00 2016-02-09T00:00:00 29 44 2016-02-03T00:00:00
50850 38 35 34 SS - IFO 512 W/S Arlene St, 1st SS N/O Dawson Ct, 12\" 33 2016-02-02T00:00:00 2016-02-09T00:00:00 28 39 2016-02-03T00:00:00
52050 40 32 31 SS - IFO 218 W/S Nicholas Ave, 1st SS S/O Charles Ave, 12\" 34 2016-02-02T00:00:00 2016-02-09T00:00:00 30 41 2016-02-03T00:00:00
58650 41 35 35 SS - IFO 510 W/S Main St, 2nd SS S/O Hylan Blvd, 12\" 35 2016-02-02T00:00:00 2016-02-09T00:00:00 34 42 2016-02-03T00:00:00
77650 32 32 31 SS - OPP 110-52 E/S 207th St 29 2016-02-02T00:00:00 2016-02-09T00:00:00 24 33 2016-02-03T00:00:00

View File

@ -1,4 +1,4 @@
buildingid consttype boro geo_dist name projdesc award location_1/needs_recoding location_1/longitude location_1/latitude location_1/human_address/address location_1/human_address/city location_1/human_address/state location_1/human_address/zip
buildingid consttype boro geo_dist name projdesc award needs_recoding longitude latitude address city state zip
M092 CIP M 5 ACADEMY OF COLLABORATIVE ED EXTERIOR MASONRY/REPAIR WINDOWS 4678000 false -73.94493618207292 40.8149219739981 222 134 STREET New York NY 10030
K610 CIP K 14 AUTOMOTIVE TRADES VOC HS FIRE ALARM 402500 false -73.95311779468979 40.72215011764413 50 BEDFORD AVENUE Brooklyn NY 11222
K554 CAP K 78 All City Leadership School Lease 29299000 false -73.91312770264774 40.69743439114146 321 Palmetto St Brooklyn NY 11237
@ -48,392 +48,4 @@ M465 CIP M 6 GEORGE WASHINGTON H.S. FLOOD ELIMINATION/PARAPETS 12686000 false -7
M460 CIP M 2 GRAMERCY ARTS HS - M SCIENCE DEMO ROOM UPGRADE 1059950 false -73.98760494227764 40.735537114027146 40 IRVING PLACE New York NY 10003
M625 CIP M 2 GRAPHIC COMMUNICATION ARTS WINDOWS/EXTERIOR MASONRY/PLAZA DECK 12647000 false -73.9905041730044 40.76336102095483 439 49 STREET New York NY 10019
M465 CIP M 6 HEALTH CAREERS & SCIENCE FY11 RESO A ELECTRICAL SYSTEM 516000 false -73.92672451121956 40.856389753646916 549 AUDOBON AVENUE New York NY 10040
Q585 CAP Q 78 HS 585 New 70250000 false -73.87835115518163 40.73871040256307 54 40 74th St Elmhurst NY 11373
X783 CAP X 78 HS 783 New 0 false -73.92662867570321 40.816146910599706 201 144th St Bronx NY 10451
Q456 CIP Q 24 HS FOR ARTS & BUS (@ Q456) WINDOWS 837000 false -73.85304068857687 40.749678220373596 105 25 HORACE HARDING EXPRESSWAY QUEENS NY 11368
K465 CIP K 17 HS FOR SERVICE & LEARNING FIRE ALARM SYSTEM 2625000 false -73.95845755993555 40.649532936565414 911 FLATBUSH AVENUE Brooklyn NY 11226
Q490 CIP Q 29 HUMANITIES & ARTS FY08 RESO A TECHNOLOGY 17555.4 false -73.73568329125084 40.694293339066405 207 01 116TH AVENUE CAMBRIA HEIGHTS NY 11411
M908 CAP M 5 Harlem Promise Academy New 60000000 false -73.94715683161196 40.81182512837363 245 129th St New York NY 10027
M280 CAP M 5 Harlem Village Academy New 36336432.4 false -73.94391077367071 40.80627609017035 35 124th St New York NY 10027
M010 CIP M 5 I.S. 10 FLOOD ELIMINATION 5393000 false -73.93690714053237 40.82438364705368 2581 7TH AVENUE NEW YORK NY 10039
K111 CIP K 32 I.S. 111 LL 41/16 COMPLIANCE 370000 false -73.9274722005684 40.70073228077929 35 STARR STREET Brooklyn NY 11221
X115 CIP X 10 I.S. 115 (@X115) EXT MASONRY/ROOFS/REINFORCING SUPPORT/PARAPETS 3833000 false -73.9001023348563 40.859718306516946 120 184 STREET Bronx NY 10468
K117 CIP K 13 I.S. 117 ELECTRICAL SYSTEMS 990000 false -73.95894653911148 40.69261081871296 300 WILLOUGHBY AVENUE Brooklyn NY 11205
Q125 CIP Q 24 I.S. 125 LOW-VOLT ELEC SYSTEMS 980000 false -73.9048471440804 40.74519376448069 46 02 47 AVENUE QUEENS NY 11377
M131 CIP M 2 I.S. 131 LL 41/16 COMPLIANCE 139807.64 false -73.99286250634624 40.71645702482035 100 HESTER STREET New York NY 10002
X131 CIP X 8 I.S. 131 ROOFS/SAFETY SYSTEM/EXT MASONRY/FLOOD ELIMINATION 6780000 false -73.85977399112697 40.82386302071817 885 BOLTON AVENUE Bronx NY 10473
X135 CIP X 11 I.S. 135 EXT MASONRY/WINDOWS/ROOFS 6988000 false -73.86461178363403 40.86208256356063 2441 WALLACE AVENUE Bronx NY 10467
X137 CIP X 10 I.S. 137 PLANYC BOILER CONVERSION/PLANYC CLIMATE CTRL 4680000 false -73.89664962860274 40.85466127151118 2225 WEBSTER AVENUE Bronx NY 10457
X139 CIP X 7 I.S. 139 EXT MASONRY/PARAPETS/FLOOD ELMNTN/WINDOWS/ROOFS 13447000 false -73.91782345430987 40.81004862442692 345 BROOK AVENUE Bronx NY 10454
K014 CIP K 22 I.S. 14 PAVED AREA - BLACKTOP 659572.05
X142 CIP X 11 I.S. 142 FY09 RESO A SCIENCE LAB 735800 false -73.84075720750138 40.88554553526394 3750 BAYCHESTER AVENUE Bronx NY 10466
M143 CIP M 6 I.S. 143 ROOFS/FLOOD ELMNTN/EXT MASONRY 4237000 false -73.9320770216135 40.84941102208005 511 182 STREET New York NY 10033
X144 CIP X 11 I.S. 144 ROOFS/EXT MASONRY/PARAPETS/FLOOD ELIMINATION 4891000 false -73.83609949442072 40.863858665108886 2545 GUNTHER AVENUE BRONX NY 10464
X151 CIP X 7 I.S. 151 WINDOWS/EXTERIOR MASONRY 3426000 false -73.9211309650046 40.82298359886116 250 156 STREET Bronx NY 10451
X158 CIP X 12 I.S. 158 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3918000 false -73.90004072543645 40.827686311428195 800 HOME STREET Bronx NY 10456
X166 CIP X 9 I.S. 166 PA SYSTEM 798000 false -73.91779283496383 40.82872889992432 250 164 STREET Bronx NY 10456
K171 CIP K 19 I.S. 171/P.S. 7 SWB-FACADE/PARAPETS/PAVED AREA-BLACKTOP/FENCING 4828290 false -73.86966791838911 40.6861530810444 528 RIDGEWOOD AVENUE BROOKLYN NY 11208
X183 CIP X 7 I.S. 183 PLANYC BOILER/PLANYC CLIMATE CTRL 3492000 false -73.92553701094046 40.813386726364335 339 MORRIS AVENUE Bronx NY 10451
X184 CIP X 7 I.S. 184 PLANYC BOILER/PLANYC CLIMATE CTRL 4910270 false -73.90589968772917 40.81888494686362 778 FOREST AVENUE BRONX NY 10456
X129 CIP X 12 I.S. 191 @X129 NEW SCIENCE DEMONSTRATION ROOM 438000 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
Q192 CIP Q 29 I.S. 192 CITY COUNCIL REQ - LIGHTING FIXTURES 1800000 false -73.75923519834566 40.69812711747255 109 89 204 STREET QUEENS NY 11412
X193 CIP X 12 I.S. 193 PLANYC BOILER/PLANYC CLIMATE CTRL 3885000 false -73.88973979569231 40.84359404962676 1919 PROSPECT AVENUE Bronx NY 10457
M195 CIP M 5 I.S. 195 (ECF) PAVED AREAS BLACKTOP 770000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
M195 CIP M 5 I.S. 195 (ECF) PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3788000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
M195 CIP M 5 I.S. 195 (ECF) SCIENCE DEMO ROOM UPGRADE 469000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
K002 CIP K 17 I.S. 2 SCIENCE DEMO ROOM UPGRADE 345000 false -73.95158492978685 40.6561968174429 655 PARKSIDE AVE BROOKLYN NY 11226
K211 CIP K 18 I.S. 211 WALK IN FREEZER REPLACEMENT 343200 false -73.89642371322941 40.64348164485336 1001 100 STREET BROOKLYN NY 11236
X116 CIP X 12 I.S. 216 (@X116) PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 4468000 false -73.89392410102988 40.822428225918 977 FOX STREET Bronx NY 10459
K218 CIP K 19 I.S. 218 WALK IN FREEZER REPLACEMENT 2120000 false -73.8742292684109 40.67070199017694 370 FOUNTAIN AVENUE Brooklyn NY 11208
M218 CIP M 6 I.S. 218 FLOOD ELIMINATION/WINDOWS/ROOFS 1867000
X148 CIP X 9 I.S. 219 (OLD I.S. 148) RETAINING WALL 583000 false -73.90440606498304 40.833636708483105 3630 THIRD AVENUE Bronx NY 10456
X022 CIP X 9 I.S. 22 FLOOD ELIMINATION/EXT MASONRY/PARAPETS 3990000 false -73.91408537225458 40.83322765425807 270 167 STREET Bronx NY 10456
X149 CIP X 7 I.S. 223 (@X149) FY10 RESO A LIBRARY 328000 false -73.92087771305378 40.814006958025736 360 145 STREET Bronx NY 10454
Q226 CIP Q 27 I.S. 226 EXT MASONRY/ROOFS 6691000 false -73.81770717164864 40.67334524268887 121 10 ROCKAWAY BLVD SO OZONE PARK NY 11420
Q227 CIP Q 30 I.S. 227 CLIMATE CONTROL/HEATING PLANT UPGRADE 5294240 false -73.8723788986672 40.76341327370369 32 02 JUNCTION BLVD QUEENS NY 11369
X082 CIP X 9 I.S. 232 (OLD 82) @X082 ACCESSIBILITY/FIRE ALARM 8193000 false -73.91609317547116 40.84901889749711 1700 MACOMBS ROAD Bronx NY 10453
R024 CIP R 31 I.S. 24 AUDITORIUM FLOORS 77000 false -74.14643932417457 40.54537484828736 225 CLEVELAND AVENUE Staten Island NY 10308
K246 CIP K 17 I.S. 246 SWB EXT MASONRY/SWB FLOOD/SWB WINDOWS/ROOF/PARAPET 4877000 false -73.95284496748633 40.64867994929756 72 VERONICA PLACE Brooklyn NY 11226
K252 CIP K 18 I.S. 252 LL 41/16 COMPLIANCE 29175.77 false -73.92001930874018 40.658327698451274 1084 LENOX ROAD Brooklyn NY 11212
M118 CIP M 3 I.S. 256 (@M118) IP SURVEILLANCE CAMERAS 216300 false -73.97053578315399 40.79156776872092 154 93 STREET New York NY 10025
M118 CIP M 3 I.S. 256 (@M118) STRUCTURAL BEAMS-REINFORCING 410160 false -73.97053578315399 40.79156776872092 154 93 STREET New York NY 10025
K265 CIP K 13 I.S. 265 SCIENCE LAB 765000 false -73.97572262403403 40.6963585351778 101 PARK AVENUE Brooklyn NY 11205
K278 CIP K 22 I.S. 278 ROOFS/EXT MASONRY/FLOOD ELMNTN 5700000 false -73.93925429415825 40.60673733465248 1925 STUART STREET Brooklyn NY 11229
K285 CIP K 18 I.S. 285 HEATING PLANT UPG/CLIMATE CTRL 4342000 false -73.921125893014 40.64688182984673 5905 BEVERLY ROAD Brooklyn NY 11203
K291 CIP K 32 I.S. 291 HEATING PLANT UPGRADE/LOW-VOLTAGE 15199800 false -73.91527095847802 40.695256718115104 231 PALMETTO STREET Brooklyn NY 11221
K292 CIP K 19 I.S. 292 CONCRETE FACADE 3477000 false -73.89288114787357 40.67148750548741 300 WYONA STREET Brooklyn NY 11207
K318 CIP K 14 I.S. 318 PARAPETS/EXT MASONRY/EAST ROOF & FAN ROOM ROOF 4340000 false -73.94902462531712 40.702422370537974 101 WALTON STREET Brooklyn NY 11206
K320 CIP K 17 I.S. 320 FLOOD ELMNTN/PARAPETS/SAFETY SYSTEMS/EXT MASONRY 3000050 false -73.95904314893046 40.66501317051537 46 MCKEEVER PLACE Brooklyn NY 11225
M125 CIP M 5 I.S. 362 @ M125 SCIENCE LAB 1354564 false -73.95506966627367 40.81015743904045 425 123 STREET New York NY 10027
X067 CIP X 12 I.S. 372 - X NEW SCIENCE LAB SUITE 945000 false -73.88479553814723 40.84392182388185 2024 MOHEGAN AVENUE Bronx NY 10460
K383 CIP K 32 I.S. 383 PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 4668000 false -73.91986972170302 40.69762704651303 1300 GREENE AVENUE Brooklyn NY 11237
K390 CIP K 17 I.S. 390 STAIRS IN STAIRWELL/FLOOD ELIM/CEC REQ-WINDOWS 4980000 false -73.93695770187597 40.67268717852895 1224 PARK PLACE Brooklyn NY 11213
K049 CIP K 14 I.S. 49 FIRE ALARM 468000
X052 CIP X 8 I.S. 52 PARAPETS/MASONRY/ROOFS/FLOOD/PAVED AREAS/SAFETY 8893000 false -73.90236106648733 40.815402542289604 681 KELLY STREET Bronx NY 10455
K055 CIP K 23 I.S. 55 SAFETY SYSTEM/EXT MASONRY/WINDOWS 4535000 false -73.91355073965249 40.67414724704465 2021 BERGEN STREET Brooklyn NY 11233
Q059 CIP Q 29 I.S. 59 LIBRARY UPGRADE 408000 false -73.75087393328533 40.66971118122609 132 55 RIDGEDALE STREET SPRINGFIELD GARDENS NY 11413
K061 CIP K 17 I.S. 61 BOILER REPLACEMENT/CONCRETE PAVER/CLIMATE CTRL 5462800 false -73.9494072266281 40.66397432612488 400 EMPIRE BLVD Brooklyn NY 11225
R072 CIP R 31 I.S. 72 ELEVATORS & ESCALATORS 691000 false -74.15872479868553 40.59325258206939 33 FERNDALE AVENUE Staten Island NY 10314
Q849 CIP Q 24 I.S. 77 AUDITORIUM UPGRADE 1588000 false -73.90222734682403 40.699542257956786 976 SENECA AVENUE RIDGEWOOD NY 11385
Q849 CIP Q 24 I.S. 77 EXTERIOR MASONRY/WINDOWS/ROOFS/PARAPETS/AC 12189000 false -73.90222734682403 40.699542257956786 976 SENECA AVENUE RIDGEWOOD NY 11385
K078 CIP K 22 I.S. 78 FLOOD ELMNTN/EXT MASONRY 1589500 false -73.91286070496677 40.62118169409423 1420 68 STREET Brooklyn NY 11234
X084 CIP X 12 I.S. 84 (@X084) PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3997000 false -73.88752511974951 40.830644846579055 1434 LONGFELLOW AVENUE Bronx NY 10459
K043 CIP K 21 I.S. 98 EXT MASONRY/ROOFS/SAFETY SYSTEMS/PARAPETS 4869000 false -73.95376310696645 40.58324060677732 1401 EMMONS AVENUE Brooklyn NY 11235
X098 CIP X 12 I.S. 98 RETAINING WALL 229571 false -73.89054065425974 40.83591680891802 1619 BOSTON ROAD Bronx NY 10460
X139 CIP X 7 INTERNATIONAL COMMUNITY NEW SCIENCE LAB SUITE 1182000 false -73.91782345430987 40.81004862442692 345 BROOK AVENUE Bronx NY 10454
X113 CIP X 11 IS 113 FY07 RES0 A PLAYGROUND REDEVELOPMENT 555000.05 false -73.86088460706405 40.88086639044798 3710 BARNES AVE Bronx NY 10467
X285 CAP X 9 IS 285 New 34111000 false -73.92787186717345 40.838131334426876 200 167th St Bronx NY 10452
Q297 CIP Q 30 IS 297 DEMOLITION FOR IS 297 746444 false -73.88361254528269 40.75163073936716 74 03 34TH AVE JACKSON HEIGHTS NY 11372
X147 CIP X 9 IS 339 (OLD IS 147X) PLANYC BOILER/PLANYC CLIMATE CTRL 7116000 false -73.90441220971972 40.84131870954352 1600 WEBSTER AVENUE Bronx NY 10457
Q404 CAP Q 78 IS/HS 404 New 61098000 false -73.93866902925225 40.74570244980828 1 50 51st Ave Long Island City NY 11101
K422 CAP K 78 IS/HS @ Spring Creek New 72847565 false -73.87479320757765 40.65755969070249 1065 Elton St Brooklyn NY 11208
X475 CIP X 10 J F KENNEDY HS FY09 FINAL C OF O FOR MULTI-CAMPUS 8387000 false -73.91213621128965 40.877210772673564 99 TERRACE VIEW AVENUE Bronx NY 10463
Q141 CIP Q 30 J.H.S. 141 ROOFS/SAFETY/EXT MASONRY/PARAPETS 7459000 false -73.90960650023976 40.780092072491186 37 11 21 AVENUE QUEENS NY 11105
X141 CIP X 10 J.H.S. 141 HEATING PLANT UPGRADE/CLIMATE CONTROL 3967000 false -73.9131873185513 40.88826732332943 660 237 STREET Bronx NY 10463
Q157 CIP Q 28 J.H.S. 157 ROOFS/WDWS/HEATING UPG/FLOOD/MASON/PARAPET/CLIMATE 14279000 false -73.86148084756303 40.72646491702238 63 55 102ND ST QUEENS NY 11374
Q168 CIP Q 25 J.H.S. 168 ACCESSIBILITY/FIRE ALARM/CLIM CTRL/HEAT PL UPG 8877000 false -73.79226817393703 40.72816440726166 158 40 76 ROAD QUEENS NY 11366
Q168 CIP Q 25 J.H.S. 168 SCIENCE LAB UPGRADE 972000 false -73.79226817393703 40.72816440726166 158 40 76 ROAD QUEENS NY 11366
Q180 CIP Q 27 J.H.S. 180 WINDOW/AC RETROFIT/AC SPLIT/MASONRY/PARAPET/ROOFS 22000000 false -73.85077700055808 40.57657830564432 3 20 BEACH 104 STREET ROCKAWAY NY 11694
Q237 CIP Q 25 J.H.S. 237 CEC REQUEST - SCIENCE LAB UPG 1176000 false -73.82147854789662 40.7512997969481 46 21 COLDEN STREET QUEENS NY 11355
Q025 CIP Q 25 J.H.S. 25 SWB-EXT MASONRY/ROOFS/PARAPETS 5618000 false -73.82147854789662 40.7512997969481 34 65 192 STREET QUEENS NY 11355
K303 CIP K 21 J.H.S. 303 FY11 RESO A ELECTRICAL SYSTEM 196000 false -73.9727279509789 40.582102240554626 501 WEST AVENUE Brooklyn NY 11224
K324 CIP K 16 J.H.S. 324 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3819000 false -73.93217356292678 40.68830858053017 800 GATES AVENUE Brooklyn NY 11221
M045 CIP M 4 J.H.S. 45 EXT MASONRY/ROOFS/PARAPETS 6670000 false -73.93335561512028 40.798869844574995 2351 1ST AVENUE New York NY 10035
K057 CIP K 16 J.H.S. 57 GYM ROOF/SEWAGE FLOODING/PARAPETS/EXT MASONRY 8625000 false -73.93365273330902 40.691184878420714 125 STUYVESANT AVENUE Brooklyn NY 11221
M070 CIP M 2 J.H.S. 70 EXTERIOR MASONRY/PARAPETS/ROOFS/WINDOWS 10489000 false -74.00204411405305 40.742083302451746 333 17 STREET NEW YORK NY 10011
Q072 CIP Q 28 J.H.S. 72 EXT MASONRY/ROOFS/FLOOD ELMNTN/PARAPETS 6176000 false -73.77530690169215 40.6769452621142 133 25 ROCHDALE VILLAG NY 11434
X080 CIP X 10 J.H.S. 80/P.S. 280 FLOOD ELIMINATION 1091773 false -73.88147439492262 40.87619978760749 149 MOSHOLU PKWY BRONX NY 10467
Q470 CIP Q 28 JAMAICA HS CLIMATE CONTROL/HEATING PLANT UPGRADE 8100000 false -73.79282099978928 40.71311535449007 167 01 GOTHIC DRIVE QUEENS NY 11432
M440 CIP M 2 JAMES BALDWIN HS LIBRARY UPGRADE 1132000 false -74.00211145861485 40.74287308397775 351 18 STREET New York NY 10011
K425 CIP K 22 JAMES MADISON HS FIRE ALARM 485500 false -73.94845748858913 40.609742865286414 3787 BEDFORD AVENUE Brooklyn NY 11229
K425 CIP K 22 JAMES MADISON HS SCIENCE LAB UPGRADE 985000 false -73.94845748858913 40.609742865286414 3787 BEDFORD AVENUE Brooklyn NY 11229
Q008 CIP Q 28 JHS 8 SCIENCE LAB UPGRADE 1081000 false -73.7875740339145 40.698104881734935 108 35 167 STREET JAMAICA NY 11433
Q425 CIP Q 25 JOHN BOWNE H.S. WIND REPLACE/AC RETROFIT/WIND BOE PORTION/UPG F.A. 27239000 false -73.82610630716033 40.730323085042414 63 25 MAIN STREET FLUSHING NY 11367
K460 CIP K 15 JOHN JAY HS CEC REQUEST-HEAT'G PLANT UPG/ELEC SYS/CLIMATE CTRL 8168000 false -73.97924096910276 40.669623280409056 237 7TH AVENUE Brooklyn NY 11215
K400 CIP K 21 LAFAYETTE HS UPGRADE BOILER PLANT/CLIMATE CONTROL 12400000 false -73.98615807328032 40.59448014682783 2630 BENSON AVENUE Brooklyn NY 11214
Q490 CIP Q 29 LAW, GOVERNMENT & COMMUNITY HS CAMPUS RESTRUCTURING 435000 false -73.73568329125084 40.694293339066405 207 01 116TH AVENUE CAMBRIA HEIGHTS NY 11411
X406 CIP X 8 LEHMAN AF ATHLETIC FIELDS 3748000 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE BRONX NY 10461
X405 CIP X 8 LEHMAN HS FY07 RESO A COMPUTER EQUIPMENT UPGR 75757.5758 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE Bronx NY 10461
X405 CIP X 8 LEHMAN HS STAIR WINDOWS 1087000 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE Bronx NY 10461
M645 CIP M 2 LIFE SCIENCE SECONDARY (@M645) FLOOD ELMNTN/EXT MASONRY/PARAPETS/ROOFS 7819500 false -74.03340357628376 40.616237105936534 320 96 STREET New York NY 10028
M490 CIP M 3 MARTIN LUTHER KING HS AUD/ALARM REPLACEMENT/FINAL C OF O/VENTILATION 4647000 false -73.98485156692796 40.77425845083081 122 AMSTERDAM AVENUE New York NY 10023
X099 CIP X 12 METROPOLITAN HS @ FORMER PS99X CODE COMPLIANCE/PA SYSTEM/PARAPET/MASONRY/ROOFS 5186000 false -73.89313106784448 40.82552621616202 1180 REVEREND JAMES POLITE AVE BRONX NY 10459
M081 CIP M 3 MID-MAN ADULT TRAINING CENTER VENTILATION/ELEC SYSTEM 3711000 false -73.95128826417978 40.80602392163958 212 120TH ST NEW YORK NY 10027
Q520 CIP Q 30 MIDDLE COLLEGE HS @LAGUARDIA DEMOLITION FOR MIDDLE COLLEGE HS 13112000 false -73.93866902925225 40.74570244980828 45 35 VAN DAM ST LONG ISLAND CITY NY 11101
K406 CIP K 21 MIDWOOD AF (MAIN) FY11 RESO A ATHLETIC FIELDS 2146000 false -73.95905922151692 40.62291467677543 1124 17TH STREET BROOKLYN NY 11230
M435 CIP M 4 MNHT CENTER FOR MATH & SCIENCE INTERIOR SPACES MARBLE PANELS ONLY 843000 false -73.9336482061862 40.794391919064594 260 PLEASANT AVENUE New York NY 10029
X400 CIP X 9 MORRIS HS CERTIFICATE OF OCCUPANCY 5229000 false -73.90448079300582 40.8276109731601 1110 BOSTON RD BRONX NY 10456
K390 CIP K 17 MS 334 SCIENCE DEMO ROOM UPGRADE 808000 false -73.93695770187597 40.67268717852895 1224 PARK PLACE Brooklyn NY 11213
Q520 CAP Q 78 Middle College HS @ LaGuardia New 27927000 false -73.93866902925225 40.74570244980828 45 35 Van Dam St Long Island City NY 11101
Q520 CAP Q 78 Middle College HS @ LaGuardia Room Conversion 13112000 false -73.93866902925225 40.74570244980828 45 35 Van Dam St Long Island City NY 11101
R435 CIP R 31 NEW DORP HS LL 41/16 COMPLIANCE 10621.99 false -74.10726241466374 40.56922370455037 465 NEW DORP LANE Staten Island NY 10306
K032 CIP K 15 NEW HORIZONS SCHOOL FY11 RESO A AUDITORIUM UPDATE 228000 false -73.99193273420018 40.680429275762485 317 HOYT STREET Brooklyn NY 11231
M868 CIP M 2 NEW HS DEMOLITION FOR IS/HS 868 2182222 false -73.99224802961538 40.73631370241236 10 15TH ST NEW YORK NY 10003
K445 CIP K 20 NEW UTRECHT HS EXT MASONRY/FLOOD ELMNTN/PARAPETS/ROOFS 10570000 false -74.00368977353216 40.61345273159829 1601 80TH ST Brooklyn NY 11214
K445 CIP K 20 NEW UTRECHT HS FY09 RESO A LIBRARY UPGRADE 353250 false -74.00368977353216 40.61345273159829 1601 80TH ST Brooklyn NY 11214
Q450 CIP Q 30 NEWCOMERS HS EXT MASONRY/PARAPETS/FLOOD ELMNTN 8395000 false -73.93866902925225 40.74570244980828 28 01 41ST AVENUE LONG ISLAND CITY NY 11101
Q455 CIP Q 24 NEWTOWN HS FLOORS 2662000 false -73.87475600018911 40.74125600016447 48 01 90 STREET QUEENS NY 11373-4099
M001 CIP M 2 P.S. 1 EXTERIOR MASONRY/PARAPETS/PAVED AREAS-CONCRETE 5139000 false -73.99734184420807 40.712756780441026 8 HENRY STREET New York NY 10038
X001 CIP X 7 P.S. 1 IP SURVEILLANCE CAMERAS 1056000 false -73.91874134609046 40.818762661509254 335 152 STREET Bronx NY 10451
Q100 CIP Q 27 P.S. 100 FLOOD ELMNTN/EXT MASONRY/PARAPETS 3199900 false -73.81770717164864 40.67334524268887 111 11 118 STREET JAMAICA NY 11420
K101 CIP K 21 P.S. 101 RESO A - RESO A SCIENCE LAB 268800 false -73.99175987597347 40.59787681678778 2360 BENSON AVENUE Brooklyn NY 11214
M101 CIP M 4 P.S. 101 ACCESSIBILITY 3689000 false -73.94443112132485 40.79566898981534 141 111 STREET NEW YORK NY 10029
M101 CIP M 4 P.S. 101 ELEC UPGRADE 287950 false -73.94443112132485 40.79566898981534 141 111 STREET NEW YORK NY 10029
X103 CIP X 11 P.S. 103 FY11 RESO A AUDITORIUM UPGRADE 419000 false -73.8614419003563 40.89224585042134 4125 CARPENTER AVENUE Bronx NY 10466
Q105 CIP Q 27 P.S. 105 SWB EXT MASONRY/PARAPETS 1050000 false -73.78189411037111 40.59623844790385 420 BEACH 51 STREET FAR ROCKAWAY NY 11691
K108 CIP K 19 P.S. 108 FY11 RESO A ELECTRICAL SYSTEM 345900 false -73.88403250144414 40.681012991519715 200 LINWOOD STREET Brooklyn NY 11208
Q108 CIP Q 27 P.S. 108 CAFE MULTIPURPOSE ROOM UPG 233000 false -73.81770717164864 40.67334524268887 108 10 109 AVENUE SO OZONE PARK NY 11420
X011 CIP X 9 P.S. 11 FLOOD ELMNTN/ROOFS/MASONRY/PARAPETS 6116000 false -73.92578827979769 40.83927054580515 1257 OGDEN AVENUE Bronx NY 10456
X011 CIP X 9 P.S. 11 SIDEWALK BRIDGE 19442.75 false -73.92578827979769 40.83927054580515 1257 OGDEN AVENUE Bronx NY 10456
K110 CIP K 14 P.S. 110 ROOFS/WINDOWS 3778000 false -73.94223625609604 40.723642548516075 124 MONITOR STREET Brooklyn NY 11222
M110 CIP M 1 P.S. 110 FLOOD ELIMINATION 547000 false -73.97981939917048 40.715620302518175 285 DELANCY STREET New York NY 10002
M111 CIP M 2 P.S. 111 CLIMATE CONTROL/HEATING PLANT UPGRADE 4305729 false -73.98953901918651 40.76616371249781 440 53 STREET New York NY 10019
Q111 CIP Q 30 P.S. 111 HEATING PLANT UPG/CLIMATE CTRL 3811000 false -73.93866902925225 40.74570244980828 37 15 13 STREET QUEENS NY 11101
K112 CIP K 20 P.S. 112 PARAPETS/EXT MASONRY/FLOOD ELMNTN 1420000 false -74.00071660633716 40.619828663672465 7115 15 AVENUE Brooklyn NY 11228
K115 CIP K 18 P.S. 115 EXT MASONRY/ROOFS/PARAPETS 5747000 false -73.89697682968284 40.63477746307819 1500 92ND ST Brooklyn NY 11236
M115 CIP M 6 P.S. 115 EXTERIOR MASONRY/HAZARDOUS-PARAPETS/ROOFS 2979000 false -73.93487128414608 40.84641769845956 586 177 STREET New York NY 10033
K116 CIP K 32 P.S. 116 FY11 RESO A SCIENCE 388000 false -73.91643018838859 40.69774977550555 515 KNICKERBOCKER AVENUE Brooklyn NY 11237
M116 CIP M 2 P.S. 116 FY11 RESO A PLAYGROUND REDEVELOPMENT 300000 false -73.97834193335258 40.74491153710013 210 33 STREET New York NY 10016
X012 CIP X 11 P.S. 12 HEATING PLT UPG/CLIMATE CNTRL/LOW-VOLT ELECTRICAL 5722850 false -73.84450496658253 40.84010546581863 2555 TRATMAN AVENUE Bronx NY 10461
K121 CIP K 21 P.S. 121 SWB-EXT MASONRY 1295000 false -73.97875690985585 40.62330608676003 5301 20TH AVENUE Brooklyn NY 11204
Q121 CIP Q 28 P.S. 121 CLIMATE CONTROL/HEATING PLANT UPGRADE 3305000 false -73.81770717164864 40.67334524268887 126 10 109 AVENUE SO OZONE PARK NY 11420
M123 CIP M 5 P.S. 123 FY10 RESO A SCIENCE LAB UPGRADE 444000 false -73.94425698262674 40.81972211192899 301 140 STREET New York NY 10030
Q124 CIP Q 27 P.S. 124 EXT MASONRY/PARAPETS 3342000 false -73.81770717164864 40.67334524268887 129 15 150 AVENUE SO OZONE PARK NY 11420
M124 CIP M 2 P.S. 124 (ECF) PARAPETS/EXTERIOR MASONRY 1367000 false -73.99579682364542 40.71420254465372 40 DIVISION STREET New York NY 10002
M126 CIP M 2 P.S. 126 FY10 RESO A LIBRARY 415000 false -73.9966721705172 40.710854298398544 80 CATHERINE STREET New York NY 10038
X126 CIP X 9 P.S. 126 (ECF) MASONRY/ROOFS/FLOOD ELMNTN/PARAPETS 5194000 false -73.9283372125368 40.83581122271332 175 166 STREET Bronx NY 10452
K127 CIP K 20 P.S. 127 EXT MASONRY 2149000 false -74.01885662493696 40.62406545959219 7805 7 AVENUE Brooklyn NY 11209
Q127 CIP Q 30 P.S. 127 AUD UPG/CAFETERIA MULTIPURPOSE RM UPG 985000 false -73.8723788986672 40.76341327370369 98 01 25 AVENUE EAST ELMHURST NY 11369
X129 CIP X 12 P.S. 129 (PAIRED W X234) EXTERIOR MASONRY 2598000 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
X129 CIP X 12 P.S. 129 (PAIRED W X234) SIDEWALK BRIDGE (EXT. MASONRY) 32157.31 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
K132 CIP K 14 P.S. 132 FLOOD ELMNTN/WINDOWS/PARAPETS 6597000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
K132 CIP K 14 P.S. 132 FY10 RESO A GYM RENOVATION 70000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
K132 CIP K 14 P.S. 132 WORK REQUIRED TO OBTAIN C OF O 932000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
M132 CIP M 6 P.S. 132 FY11 RESO A SCIENCE LAB 243500 false -73.93432269770818 40.85071645775963 185 WADSWORTH AVENUE New York NY 10033
X132 CIP X 9 P.S. 132 INTERIOR STRUCTURAL INVESTMENT - TEST 5005000 false -73.90656891847989 40.83194251909681 1245 WASHINGTON AVENUE Bronx NY 10456
K135 CIP K 18 P.S. 135 PARAPETS/FLOOD ELMNTN/ROOFS 1784000 false -73.93311810571299 40.65357812334444 684 LINDEN BLVD Brooklyn NY 11203
K138 CIP K 17 P.S. 138 ROOFS/PARAPETS/EXT MASONRY 2793000 false -73.95141196170016 40.674353675202426 760 PROSPECT PLACE Brooklyn NY 11216
K138 CIP K 17 P.S. 138 SCIENCE DEMO ROOM UPGRADE 762000 false -73.95141196170016 40.674353675202426 760 PROSPECT PLACE Brooklyn NY 11216
M844 CIP M 2 P.S. 138 (@M844) SWB - FACADE/PARAPETS/ROOFS 8833000 false -73.97802974198606 40.73757796345728 400 1ST AVENUE New York NY 10010
K849 CIP K 22 P.S. 139 AX (OLD 134) LL 41/16 COMPLIANCE 100000 false -73.97391982714538 40.632244467750226 4001 18 AVENUE Brooklyn NY 11208
R014 CIP R 31 P.S. 14 ROOFS/EXT MASONRY/WINDOWS/FLOORS/SAFETY SYSTEMS 3315000 false -74.07837687526822 40.622148795415534 100 TOMPKINS AVENUE Staten Island NY 10304
Q140 CIP Q 28 P.S. 140 PARAPETS 3269000 false -73.77530690169215 40.6769452621142 116 00 166 ST JAMAICA NY 11434
M142 CIP M 1 P.S. 142 ELEVATORS & ESCALATORS/TOILETS-STUDENTS 2995000 false -73.98376386528082 40.71945606619147 100 ATTORNEY STREET New York NY 10002
K145 CIP K 32 P.S. 145 PARAPETS/FLOOD ELMNTN/EXT MASONRY/EXT LIGHTING 4737575 false -73.93232374110994 40.7016598916867 100 NOLL STREET Brooklyn NY 11206
K142 CIP K 15 P.S. 146 (@K142) PARAPETS/EXTERIOR MASONRY/ROOFS/WINDOWS/FLOOD 13106731 false -74.00136121297172 40.68011121449034 610 HENRY STREET Brooklyn NY 11231
Q147 CIP Q 29 P.S. 147 FLOORS 537000
K015 CIP K 15 P.S. 15 LIBRARY UPGRADE 411054
M153 CIP M 6 P.S. 153 DEFECTIVE MASONRY/ROOFS/DOORS/PARAPETS 4134000 false -73.94689450753023 40.8262600138953 1750 AMSTERDAM AVENUE New York NY 10031
Q154 CIP Q 25 P.S. 154 ACCESSIBILITY/ELEC SYS/MASONRY/ROOFS/FLOOD/PARAPET 6127000 false -73.79226817393703 40.72816440726166 75 02 162 STREET FLUSHING NY 11366
M155 CIP M 4 P.S. 155 FLOOD ELMNTN/PARAPETS/EXT MASONRY 2350000 false -73.93679763009355 40.797501313680264 319 117 STREET New York NY 10035
Q156 CIP Q 29 P.S. 156 SWB - EXT MASONRY/FLOOD ELMNTN/WINDOWS/PARAPETS 7354000 false -73.75087393328533 40.66971118122609 229 02 137 AVENUE SPRINGFIELD GAR NY 11413
X156 CIP X 7 P.S. 156 CINDER BLOCK WALLS & CEILING BEAMS/FLOOD ELIMN 9780000 false -73.92024166597307 40.82226334901861 750 CONCOURSE VILLAGE Bronx NY 10451
K157 CIP K 14 P.S. 157 SWB-MASONRY 1843000 false -73.95959701353979 40.69546110023352 850 KENT AVENUE Brooklyn NY 11205
X157 CIP X 7 P.S. 157 FY11 RESO A LIBRARY UPGRADE 178000 false -73.90861019557366 40.81920242494304 757 CAULDWELL AVENUE Bronx NY 10456
K158 CIP K 19 P.S. 158 EXT MASONRY/FLOOD ELIMINATION 4244000 false -73.88480467674624 40.672471173748015 400 ASHFORD STREET Brooklyn NY 11207
K016 CIP K 14 P.S. 16 CEC REQUEST - STUDENT CAFETERIA UPG 1139000 false -73.96144993294666 40.706051659903764 157 WILSON STREET Brooklyn NY 11211
X160 CIP X 11 P.S. 160 FY11 RESO A LIBRARY 345300 false -73.8242748469253 40.86466106194175 4140 HUTCHINSON RIVER PARKWAY Bronx NY 10475
K161 CIP K 17 P.S. 161 LIBRARY UPGRADE 89500 false -73.94885261044026 40.66615564566118 330 CROWN STREET Brooklyn NY 11225
X163 CIP X 9 P.S. 163 INTERIOR MODERNIZATIONS/ROOFS 3143000 false -73.89841328719618 40.85190466527893 2075 WEBSTER AVENUE Bronx NY 10457
M165 CIP M 3 P.S. 165 ROOF TILES & SNOW GUARD/EXT MASONRY/FLOOD/PARAPETS 2118994.65 false -73.96526411800443 40.80275180384162 234 109 STREET New York NY 10025
K017 CIP K 14 P.S. 17 WINDOWS/EXT MASONRY/FLOOD ELMNTN/ROOFS/PARAPETS 7842000 false -73.95663645640386 40.715277522913524 208 5 STREET Brooklyn NY 11211
M173 CIP M 6 P.S. 173 FIRE ALARM 359900 false -73.94042010106682 40.84561730185351 306 FORT WASHINGTON AVE New York NY 10033
Q174 CIP Q 28 P.S. 174 FY11 RESO A LIBRARY UPGRADE 104000 false -73.86148084756303 40.72646491702238 65 10 DIETERLE CRESCENT REGO PARK NY 11374
Q175 CIP Q 28 P.S. 175 FY11 RESO A FENCING 319571 false -73.86148084756303 40.72646491702238 64 35 102 STREET REGO PARK NY 11374
X175 CIP X 11 P.S. 175 INTERIOR MODERNIZATIONS/WINDOWS 5296000 false -73.78516944174876 40.84381012246547 200 CITY ISLAND AVENUE Bronx NY 10464
K178 CIP K 23 P.S. 178 FLOORS 695000 false -73.9159181765978 40.675074588842676 2163 DEAN STREET Brooklyn NY 11212
Q178 CIP Q 26 P.S. 178 HEATING PLANT UPGRADE/CLIMATE CONTROL/MASONRY 7100000 false -73.7671414999802 40.71722229567246 189 10 RADNOR RD JAMAICA NY 11423
R018 CIP R 31 P.S. 18 BOILER REPLACEMENT 3171000 false -74.11747369098056 40.63603930909672 221 BROADWAY Staten Island NY 10310
X182 CIP X 8 P.S. 182 BRICK MASONRY WATER PENETRATION/WINDOWS 3464027 false -73.85625766017206 40.817936957362555 601 STICKBALL BLVD BRONX NY 10473
Q183 CIP Q 27 P.S. 183 MSNRY/SFTY/WINDOW/LIBRARY UPG/HVAC/ROOF/FIRE ALARM 8248000 false -73.82495531523557 40.6183036047276 2 45 BEACH 79 STREET ROCKAWAY BEACH NY 11693
M137 CIP M 1 P.S. 184 (SHUANG WEN @M137) FY11 RESO A PLAYGROUND REDEVELOPMENT 230000 false -73.98042410080346 40.71217484702834 327 CHERRY ST New York NY 10002
M137 CIP M 1 P.S. 184 (SHUANG WEN @M137) SWB-HAZARDOUS VIOLATION/ROOFS 979000 false -73.98042410080346 40.71217484702834 327 CHERRY ST New York NY 10002
Q186 CIP Q 26 P.S. 186 ACCESSIBILITY/FIRE ALARM SYSTEM/ELECTRICAL SYSTEMS 4577000 false -73.72415699894628 40.73704138495202 252 12 72 AVENUE BELLEROSE NY 11426
Q186 CIP Q 26 P.S. 186 FLOOD ELIMINATION 968000 false -73.72415699894628 40.73704138495202 252 12 72 AVENUE BELLEROSE NY 11426
K188 CIP K 21 P.S. 188 RESO A GYM ADDITION/FY10 RESO A PLAYGROUND 7879007 false -74.00012292790208 40.57720405091032 3314 NEPTUNE AVENUE Brooklyn NY 11224
M188 CIP M 1 P.S. 188 ACCESSIBILITY 6422000 false -73.97792876586212 40.719709960041634 442 HOUSTON STREET New York NY 10002
M188 CIP M 1 P.S. 188 EXTERIOR MASONRY/ROOFS/PARAPETS/WINDOWS 13457000 false -73.97792876586212 40.719709960041634 442 HOUSTON STREET New York NY 10002
K189 CIP K 17 P.S. 189 LOW-VOLT SYSTEM 840000 false -73.92626797722787 40.66553683638519 1100 NEW YORK AVE Brooklyn NY 11212
Q019 CIP Q 24 P.S. 19 SWB - EXT MASONRY/ROOFS/FLOOD ELIMINATION/PARAPETS 16175000 false -73.85304068857687 40.749678220373596 98 02 ROOSEVELT AVE CORONA NY 11368
R019 CIP R 31 P.S. 19 IP SURVEILLANCE CAMERAS 1270000 false -74.127115288525 40.631189624083056 780 POST AVENUE Staten Island NY 10310
K190 CIP K 19 P.S. 190 PARAPETS/ROOFS/EXT MASONRY 6720000 false -73.89448660618348 40.66233878188243 590 SHEFFIELD AVENUE Brooklyn NY 11207
K191 CIP K 17 P.S. 191 SAFETY SYSTEMS 345900 false -73.92433266937152 40.671984269991356 1600 PARK PLACE Brooklyn NY 11233
X198 CIP X 12 P.S. 198 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3794000 false -73.90058806585479 40.82868626889099 1180 TINTON AVENUE Bronx NY 10456
K199 CIP K 21 P.S. 199 FY11 RESO A LIBRARY 369000 false -73.96308897272426 40.61673348809886 1100 ELM AVENUE Brooklyn NY 11230
R020 CIP R 31 P.S. 20 EXT MASONRY/ROOFS/WINDOWS 3285000 false -74.13295576709373 40.63651173103697 161 PARK AVENUE Staten Island NY 10302
X020 CIP X 10 P.S. 20 ROOFS 1470000 false -73.87958395897564 40.869529034465444 3020 WEBSTER AVENUE BRONX NY 10467
K203 CIP K 22 P.S. 203 EXT MASONRY/ROOFS/PARAPETS/FLOOD ELMNTN 5668000 false -73.92773224974349 40.61636866748006 5101 AVENUE Brooklyn NY 11234
Q206 CIP Q 28 P.S. 206 FLOOD ELIMINATION 283000 false -73.86148084756303 40.72646491702238 61 02 98TH STREET REGO PARK NY 11374
M206 CIP M 4 P.S. 206 (TANDEM PS 112) EXT MASONRY/PARAPETS/FLD ELIMINATION/ROOFS/WALKWAY 5822870 false -73.93112623193574 40.79754733338499 508 120TH STREET New York NY 10035
R021 CIP R 31 P.S. 21 FLOORS 418000 false -74.14676832354822 40.63194814504947 168 HOOKER PLACE Staten Island NY 10303
X021 CIP X 11 P.S. 21 PARAPETS/EXT MASONRY/FLOOD ELIMINATION/ROOFS 5259000 false -73.86044891659131 40.88782430615607 715 225 STREET Bronx NY 10466
K214 CIP K 19 P.S. 214 EXT MASONRY/PARAPETS/FLOOD/WINDOWS/ROOFS 7654000 false -73.8631601400929 40.67649228343164 2944 PITKIN AVENUE Brooklyn NY 11208
Q215 CIP Q 27 P.S. 215 FY11 RESO A SCIENCE LAB UPGRADES 260000 false -73.75832418340367 40.59915376512268 535 BRIAR PLACE FAR ROCKAWAY NY 11691
K219 CIP K 18 P.S. 219 EXT MASONRY/PARAPETS/ROOFS 3079000 false -73.92291949545782 40.65925656671725 1060 CLARKSON AVENUE Brooklyn NY 11212
Q022 CIP Q 25 P.S. 22 FY10 RESO A NEW PLAYGROUND 180000 false -73.82147854789662 40.7512997969481 153 01 SANFORD AVENUE FLUSHING NY 11355
R022 CIP R 31 P.S. 22 LIBRARY UPGRADE 340000 false -74.15109445915424 40.62530363633885 1860 FOREST AVENUE Staten Island NY 10303
K225 CIP K 21 P.S. 225 ACCESSIBILITY/FIRE ALARM/ELECTRICAL SYSTEMS 4105450 false -73.95643350547934 40.5797910944251 1075 OCEAN VIEW AVENUE Brooklyn NY 11235
Q229 CIP Q 24 P.S. 229 SWB - MASONRY/ROOFS 3633000 false -73.9048471440804 40.74519376448069 67 25 51 ROAD WOODSIDE NY 11377
X229 CIP X 9 P.S. 229 ELEVATORS & ESCALATORS 1327150 false -73.92150462714196 40.85261854069672 275 HARLEM RIVER PARK BR Bronx NY 10453
X229 CIP X 9 P.S. 229 PLANYC BOILER/PLANYC CLIMATE CTRL 2910000 false -73.92150462714196 40.85261854069672 275 HARLEM RIVER PARK BR Bronx NY 10453
K230 CIP K 15 P.S. 230 ACCESSIBILITY 4392000 false -73.98088211473515 40.64501828504539 1 ALBEMARLE ROAD Brooklyn NY 11210
Q232 CIP Q 27 P.S. 232 FY11 RESO A SCIENCE LAB UPGRADES 384000 false -73.84496263981396 40.65817022817356 153 23 83 STREET HOWARD BEACH NY 11414
K236 CIP K 22 P.S. 236 EXT MASONRY/FLOOD ELIMINATION 1054000 false -73.92773224974349 40.61636866748006 6302 AVENUE Brooklyn NY 11234
K249 CIP K 17 P.S. 249 EXT MASONRY/ROOFS/PARAPETS 4474000 false -73.96609617601914 40.649842155595174 18 MARLBOROUGH ROAD Brooklyn NY 11226
K249 CIP K 17 P.S. 249 FY11 RESO A AUDITORIUM UPGRADE 198000 false -73.96609617601914 40.649842155595174 18 MARLBOROUGH ROAD Brooklyn NY 11226
K253 CIP K 21 P.S. 253 BOILER PLANT/CLIMATE CONTROL 4282800 false -73.96219337408164 40.579594157400855 601 OCEAN VIEW AVENUE Brooklyn NY 11235
Q816 CIP Q 27 P.S. 256 ANNEX WINDOWS/EXT MASONRY 5282000 false -73.85454217391299 40.576996863641924 445 BEACH 135 STREET QUEENS NY 11694
K026 CIP K 16 P.S. 26 PLANYC BOILER/PLANYC CLIMATE CTRL 3960000 false -73.93167037460694 40.69211086975316 1010 LAFAYETTE AVENUE Brooklyn NY 11221
Q026 CIP Q 26 P.S. 26 ELECTRICAL SYSTEM 594999 false -73.79462153515567 40.73987184371066 195 02 69 AVENUE FLUSHING NY 11365
K262 CIP K 16 P.S. 262 NEW SCIENCE DEMONSTRATION ROOM 534000 false -73.93085733477353 40.68321860795158 500 MACON STREET Brooklyn NY 11233
K273 CIP K 19 P.S. 273 EXT MASONRY/ROOFS/PARAPETS 5335000 false -73.87935692616207 40.65796581134507 923 JEROME STREET Brooklyn NY 11207
X027 CIP X 7 P.S. 277 (@ X027) SWB-ROOF/SWB-EXT MASONRY/WINDOWS/PARAPETS/ HEATING 15843000 false -73.91337206062776 40.813641430845045 519 ST ANNS AVENUE Bronx NY 10451
X279 CIP X 10 P.S. 279 FIRE ALARM UPGRADE 2998000 false -73.90550751626725 40.85444390420279 2100 WALTON AVE BRONX NY 10453
X028 CIP X 9 P.S. 28 EXTERIOR MASONRY/PARAPETS/FLOOD ELIMINATION 5016000 false -73.90357863607737 40.84796917302349 1861 ANTHONY AVENUE Bronx NY 10456
K284 CIP K 23 P.S. 284 SWB-PARAPET-MASONRY/EXTERIOR MASONRY 5680000 false -73.90818838446248 40.66735004908563 213 OSBORN STREET Brooklyn NY 11212
K289 CIP K 17 P.S. 289 WINDOW/CAFE MULTIPURPOSE RM UPG/MASONRY/PARAPET/PA 4440000 false -73.94240595654854 40.67477355898667 900 ST MARKS AVENUE Brooklyn NY 11213
R029 CIP R 31 P.S. 29 PARAPETS/EXT MASONRY/ROOFS 3826000 false -74.11613224214713 40.61361168930647 1581 VICTORY BLVD Staten Island NY 10314
K003 CIP K 13 P.S. 3 PARAPETS/EXT MASONRY/ROOF/PLAYGROUND REDEVELOPMENT 4820800 false -73.9554933572393 40.68262499957862 50 JEFFERSON AVENUE Brooklyn NY 11216
M003 CIP M 2 P.S. 3 FLOORS/INTERIOR SPACES 3824000 false -74.00641883360943 40.73261607852907 490 HUDSON STREET New York NY 10014
R003 CIP R 31 P.S. 3 LIGHTING FIXTURES 934104 false -74.21279962614892 40.52665926345466 80 GOFF AVENUE Staten Island NY 10309
K306 CIP K 19 P.S. 306 PLAYGROUND REDEVELOPMENT 1071501 false -73.88669548652338 40.65614802525013 970 VERMONT STREET Brooklyn NY 11207
K308 CIP K 16 P.S. 308 PAVED AREA-BLACKTOP & TCU 437000 false -73.93578222590314 40.6886393472372 616 QUINCY STREET Brooklyn NY 11221
X122 CIP X 10 P.S. 310 (@ X122) FY10 RESO A AUDITORIUM UPG 205000 false -73.90565533914132 40.873019134707036 260 KINGSBRIDGE RD Bronx NY 10463
K316 CIP K 17 P.S. 316 HOT WATER HEATER 375000 false -73.96025809844292 40.67448517044413 750 CLASSON AVENUE Brooklyn NY 11238
K032 CIP K 15 P.S. 32 FY11 RESO A LIBRARY UPGRADE 357960 false -73.99193273420018 40.680429275762485 317 HOYT STREET Brooklyn NY 11231
X032 CIP X 10 P.S. 32 VINYL FLR/BOILER RM/CLIMATE CTRL/HEAT PLANT 15839000 false -73.88593877891165 40.85208555646217 690 183 STREET Bronx NY 10458
K329 CIP K 21 P.S. 329 WINDOWS/ROOFS 4659000 false -73.99625853857127 40.5746069203897 2929 30 STREET Brooklyn NY 11212
X033 CIP X 10 P.S. 33 GUTTERS, DOWNSPOUTS & DRAINGAGE/FLOOD/EXT MASONRY 2965000 false -73.90165549892143 40.86194912850306 2424 JEROME AVENUE Bronx NY 10468
K034 CIP K 14 P.S. 34 ROOFS 1297000 false -73.94966946764082 40.72614326106391 131 NORMAN AVENUE Brooklyn NY 11222
Q034 CIP Q 29 P.S. 34 PLAYGROUND & TCU REMOVAL 1375500 false -73.74193729726841 40.721396964798146 104 12 SPRINGFIELD BLVD QUEENS VILLAGE NY 11428
M036 CIP M 5 P.S. 36 REINFORCE SUPPRT ELEMT/MASONRY/FLOOD/PARAPET/ ROOF 7179000 false -73.95760614504678 40.81034589186436 123 MORNINGSIDE DRIVE New York NY 10027
R036 CIP R 31 P.S. 36 PARAPETS 617000 false -74.18245006610681 40.54294395216458 255 IONIA AVENUE Staten Island NY 10312
Q037 CIP Q 29 P.S. 37 FLOOD ELMNTN 4627000 false -73.77530690169215 40.6769452621142 179 37 137 AVENUE JAMAICA NY 11434
K370 CIP K 21 P.S. 370 PLAYGROUND REDEVELOPMENT 2587000 false -73.96958337858405 40.577497294548174 3000 1 STREET Brooklyn NY 11224
K370 CIP K 21 P.S. 370 WINDOWS/FLOOD ELIMNTN/MASONRY/ROOFS/PARAPETS 6920000 false -73.96958337858405 40.577497294548174 3000 1 STREET Brooklyn NY 11224
R040 CIP R 31 P.S. 373 (SP ED) @R040 ROOFS/PARAPETS 824000 false -74.09531252948968 40.64071111953775 91 HENDERSON AVENUE Staten Island NY 10301
K384 CIP K 32 P.S. 384 LL 41/16 COMPLIANCE 275000 false -73.90500308262318 40.69009686200851 242 COOPER STREET Brooklyn NY 11221
R004 CIP R 31 P.S. 4 FY09 RESO A TECHNOLOGY 90290.18
Q040 CIP Q 28 P.S. 40 CEC REQUEST-TOILETS STUDENTS 889000
Q040 CIP Q 28 P.S. 40 EXTERIOR MASONRY/PARAPETS 2520000
Q040 CIP Q 28 P.S. 40 PLAYGROUND REDEVELOPMENT 1424537
M041 CIP M 2 P.S. 41 SWB-EXTERIOR MASONRY/WINDOWS/AUD. CEILING/PARAPETS 3447868 false -73.99904466974961 40.735686525332646 116 11 STREET New York NY 10011
Q041 CIP Q 26 P.S. 41 MASONRY SUPPORT REPAIR/PARAPETS 2564500 false -73.77481079967868 40.773606900238235 214 43 35 AVENUE BAYSIDE NY 11261
R041 CIP R 31 P.S. 41 FY10 RESO A PA SYSTEMS 448000 false -74.10928336025026 40.574024158045525 216 CLAWSON STREET Staten Island NY 10306
R045 CIP R 31 P.S. 45 TOILETS STUDENTS 999999 false -74.10718417740732 40.62863428073003 58 LAWRENCE AVENUE Staten Island NY 10310
R045 CIP R 31 P.S. 45 WATER PENETRATION 579900 false -74.10718417740732 40.62863428073003 58 LAWRENCE AVENUE Staten Island NY 10310
K046 CIP K 13 P.S. 46 SCIENCE DEMO ROOM 376999 false -73.9711875089949 40.694634881525445 100 CLERMONT AVENUE Brooklyn NY 11205
M046 CIP M 5 P.S. 46 SCIENCE DEMO LAB 512000
Q046 CIP Q 26 P.S. 46 CORRIDOR SPACES 290000 false -73.75790275560763 40.745924680379744 64 45 218TH STREET QUEENS NY 11364
K048 CIP K 20 P.S. 48 EXT MASONRY/PARAPETS/ROOFS 5315000
Q050 CIP Q 28 P.S. 50 SWB EXT MASONRY/PARAPETS/ROOFS 1900000 false -73.80979665579099 40.70119264912154 143 26 101 AVENUE JAMAICA NY 11435
R050 CIP R 31 P.S. 50 BOILER REPLACEMENT/CLIMATE CONTROL 3330000 false -74.12474473444865 40.561729222740695 200 ADELAIDE AVENUE Staten Island NY 10306
X050 CIP X 12 P.S. 50 FLOOD ELIMINATION 818000 false -73.88769223705626 40.83380386816254 1550 VYSE AVENUE Bronx NY 10460
M050 CIP M 4 P.S. 50 (UDC & ECF) PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 3174000 false -73.94222449721103 40.78556522081211 433 100 STREET New York NY 10029
Q051 CIP Q 27 P.S. 51 (ECC) EXTERIOR MASONRY 1023000 false -73.84031024991805 40.69637041236467 87 45 117TH STREET QUEENS NY 11418
Q052 CIP Q 29 P.S. 52 SWB EXT MASONRY 2700000 false -73.77530690169215 40.6769452621142 178 37 146 TERRACE SPRINGFIELD GARDENS NY 11434
R053 CIP R 31 P.S. 53 FENCING/PAVED AREAS-CONCRETE 675000 false -74.13710643405284 40.55253899268856 330 DURANT AVENUE Staten Island NY 10308
R054 CIP R 31 P.S. 54 PARAPETS/ROOFS/WINDOWS/EXT MASONRY 5847000 false -74.13792964309168 40.60321556338597 1060 WILLOWBROOK RD Staten Island NY 10314
Q055 CIP Q 28 P.S. 55 SWB-BULGING MASONRY/PARAPETS 4795000 false -73.82288833053201 40.68871379040917 131 10 97 AVENUE RICHMOND HILL NY 11419
R055 CIP R 31 P.S. 55 ROOFS/CEC REQUEST-MASONRY/FLOOD ELMNTN/PARAPETS 1890000 false -74.16332659953605 40.53686781464157 54 OSBORNE STREET Staten Island NY 10312
X055 CIP X 9 P.S. 55 EXTERIOR MASONRY/PARAPETS 1285000 false -73.90461113077222 40.836276563944345 450 SAINT PAUL'S PLACE Bronx NY 10456
K056 CIP K 13 P.S. 56 PLANYC CLIMATE/BOILER CONTROL 5240000 false -73.960643681102 40.68503684353989 170 GATES AVENUE Brooklyn NY 11238
R057 CIP R 31 P.S. 57 PLANYC PLAYGROUND 613715.9 false -74.08283106498078 40.61136129612238 140 PALMA DRIVE Staten Island NY 10304
K006 CIP K 17 P.S. 6 (PS 600B) BLDG MANAGEMENT SYSTEM 2269000
K006 CIP K 17 P.S. 6 (PS 600B) EXT MASONRY/ROOFS 773000
X060 CIP X 8 P.S. 60 FLOOD/EXT MASONRY/CEC REQUEST-PARAPET/ROOFS/WINDOW 14619000 false -73.89313106784448 40.82552621616202 888 REV J A POLITE AVE Bronx NY 10459
X061 CIP X 12 P.S. 61 FIRE ALARM 349119 false -73.89295310872916 40.836569959473785 1550 CROTONA PARK Bronx NY 10460
X061 CIP X 12 P.S. 61 IP SURVEILLANCE CAMERAS 1528000 false -73.89295310872916 40.836569959473785 1550 CROTONA PARK Bronx NY 10460
X064 CIP X 9 P.S. 64 BATHROOMS 4TH & 5TH FLR 508499 false -73.91558081775857 40.8401115358764 1425 WALTON AVENUE Bronx NY 10452
Q066 CIP Q 27 P.S. 66 FLOOD ELIMINATION/EXT MASONRY/PARAPETS 1110000 false -73.84031024991805 40.69637041236467 85 11 102 STREET RICHMOND HILL NY 11418
M066 CIP M 2 P.S. 66 (RICHARD R GREEN) CAFE MULTIPURPOSE ROOM 482000 false -74.02858656018857 40.62102637693336 421 88 STREET New York NY 10028
X068 CIP X 11 P.S. 68 ELEVATORS & ESCALATORS 688000 false -73.83837769297637 40.89141479468151 4011 MONTICELLO AVENUE Bronx NY 10466
R069 CIP R 31 P.S. 69 FENCING 234000 false -74.15650379993006 40.59169714382341 144 KEATING PLACE Staten Island NY 10314
X007 CIP X 10 P.S. 7 ROOFS/EXT MASONRY/PARAPETS 4700000 false -73.90547390792568 40.881013909978904 3201 KINGSBRIDGE AVENUE Bronx NY 10463
Q071 CIP Q 24 P.S. 71 FLOOD ELIMINATION 408990 false -73.88334858436963 40.70122489161548 62 85 FOREST AVENUE RIDGEWOOD NY 11385
X072 CIP X 8 P.S. 72 BATHROOM 668000 false -73.81850425419442 40.822539080023574 2951 DEWEY AVENUE Bronx NY 10465
K722 CIP K 21 P.S. 721 OTC TILTED FIELD LIGHTING 1396800 false -73.97331147204676 40.596939623165156 64 AVENUE Brooklyn NY 11223
M641 CIP M 2 P.S. 721 OTC SP ED FLOOD ELIMINATION 1897000 false -74.00542114697957 40.72862785368122 250 HOUSTON ST MANHATTAN NY 10014
K073 CIP K 23 P.S. 73 SWB EXT MSNRY/SWB PARAPETS/SWB FLOOD/ROOFS 3084000 false -73.91089377023927 40.68032732647815 251 MCDOUGAL STREET Brooklyn NY 11233
X075 CIP X 8 P.S. 75 ROOFS/EXT MASONRY 2549000 false -73.88942113898915 40.822818392634325 984 FAILE STREET Bronx NY 10459
X155 CIP X 7 P.S. 754 (@X155) CAFE/MULTIPURPOSE RM UPGRADE/FLOOD ELIMINATION 1230000 false -73.90975689502312 40.81117582303449 470 JACKSON AVENUE BRONX NY 10455
X155 CIP X 7 P.S. 754 (@X155) FY11 REOS A LIBRARY UPGRADE 299155 false -73.90975689502312 40.81117582303449 470 JACKSON AVENUE BRONX NY 10455
Q076 CIP Q 30 P.S. 76 EXTERIOR MASONRY/PARAPETS 2284875 false -73.91327185810974 40.76286893025696 36 36 10 STREET QUEENS NY 11103
X076 CIP X 11 P.S. 76 MASONRY/PARAPETS/FLOOD ELMNTN/ROOFS 4042000 false -73.8614028579785 40.86957454109854 900 ADEE AVENUE Bronx NY 10469
X078 CIP X 11 P.S. 78 AUDITORIUM UPGRADE/STUDENT TOILETS 715000 false -73.8513380848076 40.87847023359842 1400 NEEDHAM AVENUE Bronx NY 10469
Q079 CIP Q 25 P.S. 79 ELEC SYSTEMS 258100 false -73.81123206101074 40.78628404147537 147 27 15 DRIVE WHITESTONE NY 11357
R008 CIP R 31 P.S. 8 ELEC SYSTEM 790000 false -74.1517569152093 40.54764073027023 112 LINDENWOOD ROAD Staten Island NY 10308
R880 CIP R 31 P.S. 80 (PETRIDES BLDG B) WINDOWS/EXT MASONRY 3228000
Q081 CIP Q 24 P.S. 81 FLOOD ELIM/STRUCTURAL:FLOOR SYS/EXT MASONRY 1274800 false -73.91225035614077 40.70373293561221 559 CYPRESS AVENUE RIDGEWOOD NY 11237
X081 CIP X 10 P.S. 81 FLOOD ELIMINATION 474000 false -73.90520839316682 40.903559546831026 5550 RIVERDALE AVENUE Bronx NY 10471
Q848 CIP Q 24 P.S. 81 ANNEX (@Q848) FLOOD ELIMINATION/EXT MASONRY 2390270
Q811 CIP Q 26 P.S. 811 (OL 187 - CMCH) LL 41/16 COMPLIANCE 954000 false -73.73430017711144 40.759074216601846 61 25 MARATHON PKWY QUEENS NY 11362
Q811 CIP Q 26 P.S. 811 (OL 187 - CMCH) LOW VOLTAGE 560000 false -73.73430017711144 40.759074216601846 61 25 MARATHON PKWY QUEENS NY 11362
M841 CIP M 3 P.S. 811(@ M841) WORK REQUIRED TO OBTAIN C OF O 1880750 false -73.96653900057436 40.78362556816552 466 END AVENUE NEW YORK NY 10024
Q082 CIP Q 28 P.S. 82 WATER PENETRATION 1120000 false -73.80979665579099 40.70119264912154 88 02 144 STREET QUEENS NY 11435
X083 CIP X 11 P.S. 83 ACCESSIBILITY 3377000 false -73.85933122663833 40.849332468676785 950 RHINELANDER AVENUE Bronx NY 10462
Q085 CIP Q 30 P.S. 85 FLOOD ELMNTN/ROOFS/EXT MASONRY/PARAPETS 3111000 false -73.90960650023976 40.780092072491186 23 70 31 STREET QUEENS NY 11105
X085 CIP X 10 P.S. 85 RETAINING WALL 1596000 false -73.89472052099663 40.859331900138066 2400 MARION AVENUE Bronx NY 10458
K086 CIP K 32 P.S. 86 FLOOD ELMNTN/EXT MASONRY 4269000 false -73.91749723727719 40.7007452458598 220 IRVING AVENUE Brooklyn NY 11237
X086 CIP X 10 P.S. 86 ELEVATORS & ESCALATORS 747400 false -73.89880422371779 40.869715575827065 2756 RESERVOIR AVENUE Bronx NY 10468
K009 CIP K 13 P.S. 9 PAVED AREA - BLACKTOP 974000
X009 CIP X 10 P.S. 9 (OLD 115) ACCESSIBILITY 6177000 false -73.89936166242526 40.8571875830873 230 183 STREET Bronx NY 10458
Q090 CIP Q 27 P.S. 90 ELEC SYSTEMS 778000 false -73.84031024991805 40.69637041236467 86 50 109 STREET RICHMOND HILL NY 11418
Q090 CIP Q 27 P.S. 90 SWB - EMERGENCY MASONRY REPAIRS/PARAPETS 3769000 false -73.84031024991805 40.69637041236467 86 50 109 STREET RICHMOND HILL NY 11418
X090 CIP X 9 P.S. 90 EXTERIOR MASONRY/RETAINING WALLS 1857000 false -73.91794566527413 40.83197402670032 1116 SHERIDAN AVENUE Bronx NY 10456
K093 CIP K 13 P.S. 93 FLOORS 1748375 false -73.94682098403624 40.679147761017056 31 NEW YORK AVENUE Brooklyn NY 11216
K094 CIP K 15 P.S. 94 PLANYC PLAYGROUND 264500 false -74.0082060957207 40.64372817395559 5010 6TH AVENUE Brooklyn NY 11220
K095 CIP K 21 P.S. 95 EXT MASONRY/WINDOWS 3373000 false -73.97512954825021 40.595683557953876 345 VAN SICKLEN STREET Brooklyn NY 11223
M271 CIP M 2 P.S./I.S. 217 ROOSEVELT ISLAND ROOFS/EXT MASONRY/WINDOWS/PARAPETS 8444000 false -73.94703392787746 40.76494453865442 645 MAIN STREET New York NY 10044
M495 CIP M 4 PARK EAST ALT HS FY10 RESO A SCIENCE LAB 759354 false -73.94403228106489 40.79161072055837 230 34 EAST 105 STREET New York NY 10029
M495 CIP M 4 PARK EAST ALT HS WATER DAMAGE & MASONRY/ROOF/PARAPETS/WINDOWS 2887000 false -73.94403228106489 40.79161072055837 230 34 EAST 105 STREET New York NY 10029
Q102 CAP Q 24 PS 102 Addition Addition 56222000 false -73.87835115518163 40.73871040256307 55 24 Van Horn St Elmhurst NY 11373
Q013 CAP Q 24 PS 13 Addition Addition 41250000 false -73.87835115518163 40.73871040256307 55 01 94th St Elmhurst NY 11373
M130 CIP M 2 PS 130 SWB-WINDOWS 1327000 false -73.99859121725036 40.7186139475248 143 BAXTER STREET New York NY 10013
K317 CAP K 13 PS 133 New 66224000 false -73.98070466529857 40.68047819552629 610 Baltic St Brooklyn NY 11217
Q143 CIP Q 24 PS 143 FY10 RESO A PA SYSTEM 189000 false -73.85304068857687 40.749678220373596 34 74 113 STREET CORONA NY 11368
K160 CAP K 20 PS 160 Annex Addition 38772000 false -73.99911127943953 40.637367859169615 5105 Fort Hamilton Pkwy Brooklyn NY 11219
X136 CIP X 12 PS 186 COMPUTER LAB FLOOD ELIMINATION/EXTERIOR RAMPS & CANOPIES 968700 false -73.89748338090764 40.8318681052202 750 JENNINGS STREET Bronx NY 10459
Q196 CAP Q 28 PS 196 Addition Addition 29800000 false -73.84628429608335 40.720707263029794 71 25 113th St Forest Hills NY 11375
K264 CAP K 20 PS 264 New 39814903 false -74.02907223284222 40.62112765715576 8818 4th Ave Brooklyn NY 11209
Q280 CAP Q 30 PS 280 Lease 6230000 false -73.88361254528269 40.75163073936716 34 20 94th St Jackson Heights NY 11372
Q280 CAP Q 30 PS 280 Lease 7250000 false -73.88361254528269 40.75163073936716 34 20 94th St Jackson Heights NY 11372
Q029 CAP Q 25 PS 29 Addition Addition 20180000 false -73.84181070040347 40.7849280967543 125 10 23rd Ave College Point NY 11356
Q290 CIP Q 24 PS 290 DEMOLITION FOR PS 290 3370000 false -73.88334858436963 40.70122489161548 55 20 METROPOLITAN AVE RIDGEWOOD NY 11385
X292 CAP X 11 PS 292 New 31927000 false -73.86385184249058 40.85441144971648 800 Lydig Ave Bronx NY 10462
K310 CAP K 20 PS 310 New 26400000 false -74.00762713591367 40.632432204151364 942 62nd St Brooklyn NY 11219
K331 CAP K 20 PS 331 New 51133300 false -74.02392108137985 40.633713521609366 7002 4th Ave Brooklyn NY 11209
Q198 CIP Q 27 PS 333 @ 198 SCIENCE DEMO ROOM UPGRADE 670000 false -73.79540208463845 40.593133885620375 3 65 BEACH 56 STREET QUEENS NY 11692
Q042 CAP Q 27 PS 42 Addition Addition 43065000 false -73.79529882397365 40.59475372321819 488 Beach 66th St Arverne NY 11692
Q043 CIP Q 27 PS 43 FIRE ALARM SYSTEM 1982000 false -73.76182654029463 40.594515128003 160 BEACH 29TH STREET ROCKAWAY NY 11691
M338 CAP M 2 PS 51 New 54730000 false -73.99547864190042 40.761366217679694 525 44th St New York NY 10036
R071 CAP R 31 PS 71 New 53450000 false -74.09118595249046 40.60412964758937 1050 Targee St Staten Island NY 10304
K008 CAP K 13 PS 8 Addition Addition 21230000 false -73.9932378538064 40.700668802148385 37 Hicks St Brooklyn NY 11201
M916 CAP M 5 PS 916 Lease 0 false -73.95327141286555 40.81245030541294 168 Morningside Ave New York NY 10027
X177 CAP X 10 PS/IS 177 New 48888000 false -73.8752514350975 40.87277450072955 3177 Webster Ave Bronx NY 10467
Q277 CAP Q 28 PS/IS 277 New 47135000 false -73.79282099978928 40.71311535449007 153 27 88th Ave Jamaica NY 11432
M281 CAP M 2 PS/IS 281 New 47580000 false -73.97273509303172 40.74436150165521 425 35th St New York NY 10016
Q312 CAP Q 30 PS/IS 312 New 47820000 false -73.93866902925225 40.74570244980828 46 08 5th St Long Island City NY 11101
X784 CAP X 11 PS/IS 784 New 0 false -73.84367515955307 40.85710649548991 1500 Pelham Pkwy Bronx NY 10461
K990 CAP K 15 Pave Charter School New 25933333 false -74.00338737261256 40.67592711246962 732 Henry St Brooklyn NY 11231
Q475 CIP Q 27 RICHMOND HILL HS SWB - EXT MASONRY/WINDOWS/ROOFS 9333000 false -73.84031024991805 40.69637041236467 89 30 114 STREET QUEENS NY 11418
K655 CIP K 15 SARAH J HALE VOCATIONAL HS ACCESSIBILITY/SAFETY 2450000 false -73.98061564042008 40.68371105568558 345 DEAN STREET Brooklyn NY 11217
K218 CIP K 19 SCH FOR CLASSICS:ACAD OF THINK NEW SCIENCE LAB SUITE 845000 false -73.8742292684109 40.67070199017694 370 FOUNTAIN AVENUE Brooklyn NY 11208
M660 CIP M 2 SCHOOL OF THE FUTURE @MD BACON FLOOD ELIMINATION 618000 false -73.98552809234425 40.73900208799275 127 22 STREET NEW YORK NY 10010
Q751 CIP Q 30 SCHOOL SAFETY PARKING LOT SCHOOL SAFETY PARKING LOT 2648000 false -73.93866902925225 40.74570244980828 43 30 DUTCH KILLS STREET LONG ISLAND CITY NY 11101
M445 CIP M 2 SEWARD PARK HS CAFETERIA MULTIPURPOSE RM UPG 929000 false -73.98959502962896 40.716852373698316 350 GRAND STREET New York NY 10002
K515 CIP K 18 SOUTH SHORE HS ROOFS/EXT MASONRY/PARAPETS 18887000 false -73.91781691770764 40.63268510415105 6565 FLATLANDS AVENUE BROOKLYN NY 11236
M477 CIP M 2 STUYVESANT HS (NEW) EXT MASONRY/ROOFS 7752000
X240 CAP X 78 Settlement Housing PS/IS/HS New 83300000 false -73.91619367568833 40.84236125885491 1501 Jerome Ave Bronx NY 10452
X988 CAP X 78 Suspension Center - Bronx Lease 7335500 false -73.89020247936504 40.81655388322442 1231 Lafayette Ave Bronx NY 10474
X410 CIP X 9 TAFT HS PLANYC BOILER CONVERSION/PLANYC CLIMATE CTRL 10174000 false -73.9108816444482 40.84038797720987 240 172 STREET BRONX NY 10457
K485 CIP K 20 TELECOM ARTS & TECHNOLOGY H.S. EXT MASONRY 4138000 false -74.02385245520922 40.63726462862678 350 67TH ST Brooklyn NY 11220
X435 CIP X 10 THEODORE ROOSEVELT H.S. FLOORS 1593000 false -73.88817875264016 40.85990614640288 500 FORDHAM ROAD Bronx NY 10458
X435 CIP X 10 THEODORE ROOSEVELT H.S. SWB - COPPER SIDING 1500000 false -73.88817875264016 40.85990614640288 500 FORDHAM ROAD Bronx NY 10458
R455 CIP R 31 TOTTENVILLE H.S. FY10 RESO A AF REPLACEMENT 1452882 false -74.19217697672369 40.52826198723337 100 LUTEN AVENUE Staten Island NY 10312
R455 CIP R 31 TOTTENVILLE HS WINDOWS 7960000 false -74.19217697672369 40.52826198723337 100 LUTEN AVENUE Staten Island NY 10312
M971 CAP M 2 The Spruce Street Educational New 34146385.86 false -74.00596371272646 40.71174136432668 12 Spruce St New York NY 10038
M445 CIP M 2 URBAN ASSEMBLY ACADEMY GIRLS SHOWER ROOM 1014300 false -73.98959502962896 40.716852373698316 350 GRAND STREET New York NY 10002
R460 CIP R 31 WAGNER HS FY06 RESO A ATHLETIC FIELD 5799000 false -74.12366587081469 40.59771088831585 1200 MANOR ROAD Staten Island NY 10314
K805 CIP K 13 WATER'S EDGE EDUCATIONAL COMPL ELEVATOR UPGRADE 764398 false -73.98496543482732 40.69721149151847 49 FLATBUSH AVE EXTENSION BROOKLYN NY 11201
Q680 CIP Q 28 YOUNG WOMENS' LEADERSHIP SCHOO IP SURVEILLANCE CAMERAS 1047000 false -73.7875740339145 40.698104881734935 150 91 87TH ROAD JAMAICA NY 11433
Q585 CAP Q 78 HS 585 New 70250000 false -73.87835115518163 40.73871040256307 54 40 74th St Elmhurst NY 11373
1 buildingid consttype boro geo_dist name projdesc award location_1/needs_recoding needs_recoding location_1/longitude longitude location_1/latitude latitude location_1/human_address/address address location_1/human_address/city city location_1/human_address/state state location_1/human_address/zip zip
2 M092 CIP M 5 ACADEMY OF COLLABORATIVE ED EXTERIOR MASONRY/REPAIR WINDOWS 4678000 false -73.94493618207292 40.8149219739981 222 134 STREET New York NY 10030
3 K610 CIP K 14 AUTOMOTIVE TRADES VOC HS FIRE ALARM 402500 false -73.95311779468979 40.72215011764413 50 BEDFORD AVENUE Brooklyn NY 11222
4 K554 CAP K 78 All City Leadership School Lease 29299000 false -73.91312770264774 40.69743439114146 321 Palmetto St Brooklyn NY 11237
48 M460 CIP M 2 GRAMERCY ARTS HS - M SCIENCE DEMO ROOM UPGRADE 1059950 false -73.98760494227764 40.735537114027146 40 IRVING PLACE New York NY 10003
49 M625 CIP M 2 GRAPHIC COMMUNICATION ARTS WINDOWS/EXTERIOR MASONRY/PLAZA DECK 12647000 false -73.9905041730044 40.76336102095483 439 49 STREET New York NY 10019
50 M465 CIP M 6 HEALTH CAREERS & SCIENCE FY11 RESO A ELECTRICAL SYSTEM 516000 false -73.92672451121956 40.856389753646916 549 AUDOBON AVENUE New York NY 10040
51 Q585 CAP Q 78 HS 585 New 70250000 false -73.87835115518163 40.73871040256307 54 40 74th St Elmhurst NY 11373
X783 CAP X 78 HS 783 New 0 false -73.92662867570321 40.816146910599706 201 144th St Bronx NY 10451
Q456 CIP Q 24 HS FOR ARTS & BUS (@ Q456) WINDOWS 837000 false -73.85304068857687 40.749678220373596 105 25 HORACE HARDING EXPRESSWAY QUEENS NY 11368
K465 CIP K 17 HS FOR SERVICE & LEARNING FIRE ALARM SYSTEM 2625000 false -73.95845755993555 40.649532936565414 911 FLATBUSH AVENUE Brooklyn NY 11226
Q490 CIP Q 29 HUMANITIES & ARTS FY08 RESO A TECHNOLOGY 17555.4 false -73.73568329125084 40.694293339066405 207 01 116TH AVENUE CAMBRIA HEIGHTS NY 11411
M908 CAP M 5 Harlem Promise Academy New 60000000 false -73.94715683161196 40.81182512837363 245 129th St New York NY 10027
M280 CAP M 5 Harlem Village Academy New 36336432.4 false -73.94391077367071 40.80627609017035 35 124th St New York NY 10027
M010 CIP M 5 I.S. 10 FLOOD ELIMINATION 5393000 false -73.93690714053237 40.82438364705368 2581 7TH AVENUE NEW YORK NY 10039
K111 CIP K 32 I.S. 111 LL 41/16 COMPLIANCE 370000 false -73.9274722005684 40.70073228077929 35 STARR STREET Brooklyn NY 11221
X115 CIP X 10 I.S. 115 (@X115) EXT MASONRY/ROOFS/REINFORCING SUPPORT/PARAPETS 3833000 false -73.9001023348563 40.859718306516946 120 184 STREET Bronx NY 10468
K117 CIP K 13 I.S. 117 ELECTRICAL SYSTEMS 990000 false -73.95894653911148 40.69261081871296 300 WILLOUGHBY AVENUE Brooklyn NY 11205
Q125 CIP Q 24 I.S. 125 LOW-VOLT ELEC SYSTEMS 980000 false -73.9048471440804 40.74519376448069 46 02 47 AVENUE QUEENS NY 11377
M131 CIP M 2 I.S. 131 LL 41/16 COMPLIANCE 139807.64 false -73.99286250634624 40.71645702482035 100 HESTER STREET New York NY 10002
X131 CIP X 8 I.S. 131 ROOFS/SAFETY SYSTEM/EXT MASONRY/FLOOD ELIMINATION 6780000 false -73.85977399112697 40.82386302071817 885 BOLTON AVENUE Bronx NY 10473
X135 CIP X 11 I.S. 135 EXT MASONRY/WINDOWS/ROOFS 6988000 false -73.86461178363403 40.86208256356063 2441 WALLACE AVENUE Bronx NY 10467
X137 CIP X 10 I.S. 137 PLANYC BOILER CONVERSION/PLANYC CLIMATE CTRL 4680000 false -73.89664962860274 40.85466127151118 2225 WEBSTER AVENUE Bronx NY 10457
X139 CIP X 7 I.S. 139 EXT MASONRY/PARAPETS/FLOOD ELMNTN/WINDOWS/ROOFS 13447000 false -73.91782345430987 40.81004862442692 345 BROOK AVENUE Bronx NY 10454
K014 CIP K 22 I.S. 14 PAVED AREA - BLACKTOP 659572.05
X142 CIP X 11 I.S. 142 FY09 RESO A SCIENCE LAB 735800 false -73.84075720750138 40.88554553526394 3750 BAYCHESTER AVENUE Bronx NY 10466
M143 CIP M 6 I.S. 143 ROOFS/FLOOD ELMNTN/EXT MASONRY 4237000 false -73.9320770216135 40.84941102208005 511 182 STREET New York NY 10033
X144 CIP X 11 I.S. 144 ROOFS/EXT MASONRY/PARAPETS/FLOOD ELIMINATION 4891000 false -73.83609949442072 40.863858665108886 2545 GUNTHER AVENUE BRONX NY 10464
X151 CIP X 7 I.S. 151 WINDOWS/EXTERIOR MASONRY 3426000 false -73.9211309650046 40.82298359886116 250 156 STREET Bronx NY 10451
X158 CIP X 12 I.S. 158 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3918000 false -73.90004072543645 40.827686311428195 800 HOME STREET Bronx NY 10456
X166 CIP X 9 I.S. 166 PA SYSTEM 798000 false -73.91779283496383 40.82872889992432 250 164 STREET Bronx NY 10456
K171 CIP K 19 I.S. 171/P.S. 7 SWB-FACADE/PARAPETS/PAVED AREA-BLACKTOP/FENCING 4828290 false -73.86966791838911 40.6861530810444 528 RIDGEWOOD AVENUE BROOKLYN NY 11208
X183 CIP X 7 I.S. 183 PLANYC BOILER/PLANYC CLIMATE CTRL 3492000 false -73.92553701094046 40.813386726364335 339 MORRIS AVENUE Bronx NY 10451
X184 CIP X 7 I.S. 184 PLANYC BOILER/PLANYC CLIMATE CTRL 4910270 false -73.90589968772917 40.81888494686362 778 FOREST AVENUE BRONX NY 10456
X129 CIP X 12 I.S. 191 @X129 NEW SCIENCE DEMONSTRATION ROOM 438000 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
Q192 CIP Q 29 I.S. 192 CITY COUNCIL REQ - LIGHTING FIXTURES 1800000 false -73.75923519834566 40.69812711747255 109 89 204 STREET QUEENS NY 11412
X193 CIP X 12 I.S. 193 PLANYC BOILER/PLANYC CLIMATE CTRL 3885000 false -73.88973979569231 40.84359404962676 1919 PROSPECT AVENUE Bronx NY 10457
M195 CIP M 5 I.S. 195 (ECF) PAVED AREAS BLACKTOP 770000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
M195 CIP M 5 I.S. 195 (ECF) PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3788000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
M195 CIP M 5 I.S. 195 (ECF) SCIENCE DEMO ROOM UPGRADE 469000 false -73.95739030775974 40.81937508503853 625 133 STREET New York NY 10027
K002 CIP K 17 I.S. 2 SCIENCE DEMO ROOM UPGRADE 345000 false -73.95158492978685 40.6561968174429 655 PARKSIDE AVE BROOKLYN NY 11226
K211 CIP K 18 I.S. 211 WALK IN FREEZER REPLACEMENT 343200 false -73.89642371322941 40.64348164485336 1001 100 STREET BROOKLYN NY 11236
X116 CIP X 12 I.S. 216 (@X116) PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 4468000 false -73.89392410102988 40.822428225918 977 FOX STREET Bronx NY 10459
K218 CIP K 19 I.S. 218 WALK IN FREEZER REPLACEMENT 2120000 false -73.8742292684109 40.67070199017694 370 FOUNTAIN AVENUE Brooklyn NY 11208
M218 CIP M 6 I.S. 218 FLOOD ELIMINATION/WINDOWS/ROOFS 1867000
X148 CIP X 9 I.S. 219 (OLD I.S. 148) RETAINING WALL 583000 false -73.90440606498304 40.833636708483105 3630 THIRD AVENUE Bronx NY 10456
X022 CIP X 9 I.S. 22 FLOOD ELIMINATION/EXT MASONRY/PARAPETS 3990000 false -73.91408537225458 40.83322765425807 270 167 STREET Bronx NY 10456
X149 CIP X 7 I.S. 223 (@X149) FY10 RESO A LIBRARY 328000 false -73.92087771305378 40.814006958025736 360 145 STREET Bronx NY 10454
Q226 CIP Q 27 I.S. 226 EXT MASONRY/ROOFS 6691000 false -73.81770717164864 40.67334524268887 121 10 ROCKAWAY BLVD SO OZONE PARK NY 11420
Q227 CIP Q 30 I.S. 227 CLIMATE CONTROL/HEATING PLANT UPGRADE 5294240 false -73.8723788986672 40.76341327370369 32 02 JUNCTION BLVD QUEENS NY 11369
X082 CIP X 9 I.S. 232 (OLD 82) @X082 ACCESSIBILITY/FIRE ALARM 8193000 false -73.91609317547116 40.84901889749711 1700 MACOMBS ROAD Bronx NY 10453
R024 CIP R 31 I.S. 24 AUDITORIUM FLOORS 77000 false -74.14643932417457 40.54537484828736 225 CLEVELAND AVENUE Staten Island NY 10308
K246 CIP K 17 I.S. 246 SWB EXT MASONRY/SWB FLOOD/SWB WINDOWS/ROOF/PARAPET 4877000 false -73.95284496748633 40.64867994929756 72 VERONICA PLACE Brooklyn NY 11226
K252 CIP K 18 I.S. 252 LL 41/16 COMPLIANCE 29175.77 false -73.92001930874018 40.658327698451274 1084 LENOX ROAD Brooklyn NY 11212
M118 CIP M 3 I.S. 256 (@M118) IP SURVEILLANCE CAMERAS 216300 false -73.97053578315399 40.79156776872092 154 93 STREET New York NY 10025
M118 CIP M 3 I.S. 256 (@M118) STRUCTURAL BEAMS-REINFORCING 410160 false -73.97053578315399 40.79156776872092 154 93 STREET New York NY 10025
K265 CIP K 13 I.S. 265 SCIENCE LAB 765000 false -73.97572262403403 40.6963585351778 101 PARK AVENUE Brooklyn NY 11205
K278 CIP K 22 I.S. 278 ROOFS/EXT MASONRY/FLOOD ELMNTN 5700000 false -73.93925429415825 40.60673733465248 1925 STUART STREET Brooklyn NY 11229
K285 CIP K 18 I.S. 285 HEATING PLANT UPG/CLIMATE CTRL 4342000 false -73.921125893014 40.64688182984673 5905 BEVERLY ROAD Brooklyn NY 11203
K291 CIP K 32 I.S. 291 HEATING PLANT UPGRADE/LOW-VOLTAGE 15199800 false -73.91527095847802 40.695256718115104 231 PALMETTO STREET Brooklyn NY 11221
K292 CIP K 19 I.S. 292 CONCRETE FACADE 3477000 false -73.89288114787357 40.67148750548741 300 WYONA STREET Brooklyn NY 11207
K318 CIP K 14 I.S. 318 PARAPETS/EXT MASONRY/EAST ROOF & FAN ROOM ROOF 4340000 false -73.94902462531712 40.702422370537974 101 WALTON STREET Brooklyn NY 11206
K320 CIP K 17 I.S. 320 FLOOD ELMNTN/PARAPETS/SAFETY SYSTEMS/EXT MASONRY 3000050 false -73.95904314893046 40.66501317051537 46 MCKEEVER PLACE Brooklyn NY 11225
M125 CIP M 5 I.S. 362 @ M125 SCIENCE LAB 1354564 false -73.95506966627367 40.81015743904045 425 123 STREET New York NY 10027
X067 CIP X 12 I.S. 372 - X NEW SCIENCE LAB SUITE 945000 false -73.88479553814723 40.84392182388185 2024 MOHEGAN AVENUE Bronx NY 10460
K383 CIP K 32 I.S. 383 PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 4668000 false -73.91986972170302 40.69762704651303 1300 GREENE AVENUE Brooklyn NY 11237
K390 CIP K 17 I.S. 390 STAIRS IN STAIRWELL/FLOOD ELIM/CEC REQ-WINDOWS 4980000 false -73.93695770187597 40.67268717852895 1224 PARK PLACE Brooklyn NY 11213
K049 CIP K 14 I.S. 49 FIRE ALARM 468000
X052 CIP X 8 I.S. 52 PARAPETS/MASONRY/ROOFS/FLOOD/PAVED AREAS/SAFETY 8893000 false -73.90236106648733 40.815402542289604 681 KELLY STREET Bronx NY 10455
K055 CIP K 23 I.S. 55 SAFETY SYSTEM/EXT MASONRY/WINDOWS 4535000 false -73.91355073965249 40.67414724704465 2021 BERGEN STREET Brooklyn NY 11233
Q059 CIP Q 29 I.S. 59 LIBRARY UPGRADE 408000 false -73.75087393328533 40.66971118122609 132 55 RIDGEDALE STREET SPRINGFIELD GARDENS NY 11413
K061 CIP K 17 I.S. 61 BOILER REPLACEMENT/CONCRETE PAVER/CLIMATE CTRL 5462800 false -73.9494072266281 40.66397432612488 400 EMPIRE BLVD Brooklyn NY 11225
R072 CIP R 31 I.S. 72 ELEVATORS & ESCALATORS 691000 false -74.15872479868553 40.59325258206939 33 FERNDALE AVENUE Staten Island NY 10314
Q849 CIP Q 24 I.S. 77 AUDITORIUM UPGRADE 1588000 false -73.90222734682403 40.699542257956786 976 SENECA AVENUE RIDGEWOOD NY 11385
Q849 CIP Q 24 I.S. 77 EXTERIOR MASONRY/WINDOWS/ROOFS/PARAPETS/AC 12189000 false -73.90222734682403 40.699542257956786 976 SENECA AVENUE RIDGEWOOD NY 11385
K078 CIP K 22 I.S. 78 FLOOD ELMNTN/EXT MASONRY 1589500 false -73.91286070496677 40.62118169409423 1420 68 STREET Brooklyn NY 11234
X084 CIP X 12 I.S. 84 (@X084) PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3997000 false -73.88752511974951 40.830644846579055 1434 LONGFELLOW AVENUE Bronx NY 10459
K043 CIP K 21 I.S. 98 EXT MASONRY/ROOFS/SAFETY SYSTEMS/PARAPETS 4869000 false -73.95376310696645 40.58324060677732 1401 EMMONS AVENUE Brooklyn NY 11235
X098 CIP X 12 I.S. 98 RETAINING WALL 229571 false -73.89054065425974 40.83591680891802 1619 BOSTON ROAD Bronx NY 10460
X139 CIP X 7 INTERNATIONAL COMMUNITY NEW SCIENCE LAB SUITE 1182000 false -73.91782345430987 40.81004862442692 345 BROOK AVENUE Bronx NY 10454
X113 CIP X 11 IS 113 FY07 RES0 A PLAYGROUND REDEVELOPMENT 555000.05 false -73.86088460706405 40.88086639044798 3710 BARNES AVE Bronx NY 10467
X285 CAP X 9 IS 285 New 34111000 false -73.92787186717345 40.838131334426876 200 167th St Bronx NY 10452
Q297 CIP Q 30 IS 297 DEMOLITION FOR IS 297 746444 false -73.88361254528269 40.75163073936716 74 03 34TH AVE JACKSON HEIGHTS NY 11372
X147 CIP X 9 IS 339 (OLD IS 147X) PLANYC BOILER/PLANYC CLIMATE CTRL 7116000 false -73.90441220971972 40.84131870954352 1600 WEBSTER AVENUE Bronx NY 10457
Q404 CAP Q 78 IS/HS 404 New 61098000 false -73.93866902925225 40.74570244980828 1 50 51st Ave Long Island City NY 11101
K422 CAP K 78 IS/HS @ Spring Creek New 72847565 false -73.87479320757765 40.65755969070249 1065 Elton St Brooklyn NY 11208
X475 CIP X 10 J F KENNEDY HS FY09 FINAL C OF O FOR MULTI-CAMPUS 8387000 false -73.91213621128965 40.877210772673564 99 TERRACE VIEW AVENUE Bronx NY 10463
Q141 CIP Q 30 J.H.S. 141 ROOFS/SAFETY/EXT MASONRY/PARAPETS 7459000 false -73.90960650023976 40.780092072491186 37 11 21 AVENUE QUEENS NY 11105
X141 CIP X 10 J.H.S. 141 HEATING PLANT UPGRADE/CLIMATE CONTROL 3967000 false -73.9131873185513 40.88826732332943 660 237 STREET Bronx NY 10463
Q157 CIP Q 28 J.H.S. 157 ROOFS/WDWS/HEATING UPG/FLOOD/MASON/PARAPET/CLIMATE 14279000 false -73.86148084756303 40.72646491702238 63 55 102ND ST QUEENS NY 11374
Q168 CIP Q 25 J.H.S. 168 ACCESSIBILITY/FIRE ALARM/CLIM CTRL/HEAT PL UPG 8877000 false -73.79226817393703 40.72816440726166 158 40 76 ROAD QUEENS NY 11366
Q168 CIP Q 25 J.H.S. 168 SCIENCE LAB UPGRADE 972000 false -73.79226817393703 40.72816440726166 158 40 76 ROAD QUEENS NY 11366
Q180 CIP Q 27 J.H.S. 180 WINDOW/AC RETROFIT/AC SPLIT/MASONRY/PARAPET/ROOFS 22000000 false -73.85077700055808 40.57657830564432 3 20 BEACH 104 STREET ROCKAWAY NY 11694
Q237 CIP Q 25 J.H.S. 237 CEC REQUEST - SCIENCE LAB UPG 1176000 false -73.82147854789662 40.7512997969481 46 21 COLDEN STREET QUEENS NY 11355
Q025 CIP Q 25 J.H.S. 25 SWB-EXT MASONRY/ROOFS/PARAPETS 5618000 false -73.82147854789662 40.7512997969481 34 65 192 STREET QUEENS NY 11355
K303 CIP K 21 J.H.S. 303 FY11 RESO A ELECTRICAL SYSTEM 196000 false -73.9727279509789 40.582102240554626 501 WEST AVENUE Brooklyn NY 11224
K324 CIP K 16 J.H.S. 324 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3819000 false -73.93217356292678 40.68830858053017 800 GATES AVENUE Brooklyn NY 11221
M045 CIP M 4 J.H.S. 45 EXT MASONRY/ROOFS/PARAPETS 6670000 false -73.93335561512028 40.798869844574995 2351 1ST AVENUE New York NY 10035
K057 CIP K 16 J.H.S. 57 GYM ROOF/SEWAGE FLOODING/PARAPETS/EXT MASONRY 8625000 false -73.93365273330902 40.691184878420714 125 STUYVESANT AVENUE Brooklyn NY 11221
M070 CIP M 2 J.H.S. 70 EXTERIOR MASONRY/PARAPETS/ROOFS/WINDOWS 10489000 false -74.00204411405305 40.742083302451746 333 17 STREET NEW YORK NY 10011
Q072 CIP Q 28 J.H.S. 72 EXT MASONRY/ROOFS/FLOOD ELMNTN/PARAPETS 6176000 false -73.77530690169215 40.6769452621142 133 25 ROCHDALE VILLAG NY 11434
X080 CIP X 10 J.H.S. 80/P.S. 280 FLOOD ELIMINATION 1091773 false -73.88147439492262 40.87619978760749 149 MOSHOLU PKWY BRONX NY 10467
Q470 CIP Q 28 JAMAICA HS CLIMATE CONTROL/HEATING PLANT UPGRADE 8100000 false -73.79282099978928 40.71311535449007 167 01 GOTHIC DRIVE QUEENS NY 11432
M440 CIP M 2 JAMES BALDWIN HS LIBRARY UPGRADE 1132000 false -74.00211145861485 40.74287308397775 351 18 STREET New York NY 10011
K425 CIP K 22 JAMES MADISON HS FIRE ALARM 485500 false -73.94845748858913 40.609742865286414 3787 BEDFORD AVENUE Brooklyn NY 11229
K425 CIP K 22 JAMES MADISON HS SCIENCE LAB UPGRADE 985000 false -73.94845748858913 40.609742865286414 3787 BEDFORD AVENUE Brooklyn NY 11229
Q008 CIP Q 28 JHS 8 SCIENCE LAB UPGRADE 1081000 false -73.7875740339145 40.698104881734935 108 35 167 STREET JAMAICA NY 11433
Q425 CIP Q 25 JOHN BOWNE H.S. WIND REPLACE/AC RETROFIT/WIND BOE PORTION/UPG F.A. 27239000 false -73.82610630716033 40.730323085042414 63 25 MAIN STREET FLUSHING NY 11367
K460 CIP K 15 JOHN JAY HS CEC REQUEST-HEAT'G PLANT UPG/ELEC SYS/CLIMATE CTRL 8168000 false -73.97924096910276 40.669623280409056 237 7TH AVENUE Brooklyn NY 11215
K400 CIP K 21 LAFAYETTE HS UPGRADE BOILER PLANT/CLIMATE CONTROL 12400000 false -73.98615807328032 40.59448014682783 2630 BENSON AVENUE Brooklyn NY 11214
Q490 CIP Q 29 LAW, GOVERNMENT & COMMUNITY HS CAMPUS RESTRUCTURING 435000 false -73.73568329125084 40.694293339066405 207 01 116TH AVENUE CAMBRIA HEIGHTS NY 11411
X406 CIP X 8 LEHMAN AF ATHLETIC FIELDS 3748000 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE BRONX NY 10461
X405 CIP X 8 LEHMAN HS FY07 RESO A COMPUTER EQUIPMENT UPGR 75757.5758 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE Bronx NY 10461
X405 CIP X 8 LEHMAN HS STAIR WINDOWS 1087000 false -73.83830582037355 40.840618266233676 3000 TREMONT AVENUE Bronx NY 10461
M645 CIP M 2 LIFE SCIENCE SECONDARY (@M645) FLOOD ELMNTN/EXT MASONRY/PARAPETS/ROOFS 7819500 false -74.03340357628376 40.616237105936534 320 96 STREET New York NY 10028
M490 CIP M 3 MARTIN LUTHER KING HS AUD/ALARM REPLACEMENT/FINAL C OF O/VENTILATION 4647000 false -73.98485156692796 40.77425845083081 122 AMSTERDAM AVENUE New York NY 10023
X099 CIP X 12 METROPOLITAN HS @ FORMER PS99X CODE COMPLIANCE/PA SYSTEM/PARAPET/MASONRY/ROOFS 5186000 false -73.89313106784448 40.82552621616202 1180 REVEREND JAMES POLITE AVE BRONX NY 10459
M081 CIP M 3 MID-MAN ADULT TRAINING CENTER VENTILATION/ELEC SYSTEM 3711000 false -73.95128826417978 40.80602392163958 212 120TH ST NEW YORK NY 10027
Q520 CIP Q 30 MIDDLE COLLEGE HS @LAGUARDIA DEMOLITION FOR MIDDLE COLLEGE HS 13112000 false -73.93866902925225 40.74570244980828 45 35 VAN DAM ST LONG ISLAND CITY NY 11101
K406 CIP K 21 MIDWOOD AF (MAIN) FY11 RESO A ATHLETIC FIELDS 2146000 false -73.95905922151692 40.62291467677543 1124 17TH STREET BROOKLYN NY 11230
M435 CIP M 4 MNHT CENTER FOR MATH & SCIENCE INTERIOR SPACES MARBLE PANELS ONLY 843000 false -73.9336482061862 40.794391919064594 260 PLEASANT AVENUE New York NY 10029
X400 CIP X 9 MORRIS HS CERTIFICATE OF OCCUPANCY 5229000 false -73.90448079300582 40.8276109731601 1110 BOSTON RD BRONX NY 10456
K390 CIP K 17 MS 334 SCIENCE DEMO ROOM UPGRADE 808000 false -73.93695770187597 40.67268717852895 1224 PARK PLACE Brooklyn NY 11213
Q520 CAP Q 78 Middle College HS @ LaGuardia New 27927000 false -73.93866902925225 40.74570244980828 45 35 Van Dam St Long Island City NY 11101
Q520 CAP Q 78 Middle College HS @ LaGuardia Room Conversion 13112000 false -73.93866902925225 40.74570244980828 45 35 Van Dam St Long Island City NY 11101
R435 CIP R 31 NEW DORP HS LL 41/16 COMPLIANCE 10621.99 false -74.10726241466374 40.56922370455037 465 NEW DORP LANE Staten Island NY 10306
K032 CIP K 15 NEW HORIZONS SCHOOL FY11 RESO A AUDITORIUM UPDATE 228000 false -73.99193273420018 40.680429275762485 317 HOYT STREET Brooklyn NY 11231
M868 CIP M 2 NEW HS DEMOLITION FOR IS/HS 868 2182222 false -73.99224802961538 40.73631370241236 10 15TH ST NEW YORK NY 10003
K445 CIP K 20 NEW UTRECHT HS EXT MASONRY/FLOOD ELMNTN/PARAPETS/ROOFS 10570000 false -74.00368977353216 40.61345273159829 1601 80TH ST Brooklyn NY 11214
K445 CIP K 20 NEW UTRECHT HS FY09 RESO A LIBRARY UPGRADE 353250 false -74.00368977353216 40.61345273159829 1601 80TH ST Brooklyn NY 11214
Q450 CIP Q 30 NEWCOMERS HS EXT MASONRY/PARAPETS/FLOOD ELMNTN 8395000 false -73.93866902925225 40.74570244980828 28 01 41ST AVENUE LONG ISLAND CITY NY 11101
Q455 CIP Q 24 NEWTOWN HS FLOORS 2662000 false -73.87475600018911 40.74125600016447 48 01 90 STREET QUEENS NY 11373-4099
M001 CIP M 2 P.S. 1 EXTERIOR MASONRY/PARAPETS/PAVED AREAS-CONCRETE 5139000 false -73.99734184420807 40.712756780441026 8 HENRY STREET New York NY 10038
X001 CIP X 7 P.S. 1 IP SURVEILLANCE CAMERAS 1056000 false -73.91874134609046 40.818762661509254 335 152 STREET Bronx NY 10451
Q100 CIP Q 27 P.S. 100 FLOOD ELMNTN/EXT MASONRY/PARAPETS 3199900 false -73.81770717164864 40.67334524268887 111 11 118 STREET JAMAICA NY 11420
K101 CIP K 21 P.S. 101 RESO A - RESO A SCIENCE LAB 268800 false -73.99175987597347 40.59787681678778 2360 BENSON AVENUE Brooklyn NY 11214
M101 CIP M 4 P.S. 101 ACCESSIBILITY 3689000 false -73.94443112132485 40.79566898981534 141 111 STREET NEW YORK NY 10029
M101 CIP M 4 P.S. 101 ELEC UPGRADE 287950 false -73.94443112132485 40.79566898981534 141 111 STREET NEW YORK NY 10029
X103 CIP X 11 P.S. 103 FY11 RESO A AUDITORIUM UPGRADE 419000 false -73.8614419003563 40.89224585042134 4125 CARPENTER AVENUE Bronx NY 10466
Q105 CIP Q 27 P.S. 105 SWB EXT MASONRY/PARAPETS 1050000 false -73.78189411037111 40.59623844790385 420 BEACH 51 STREET FAR ROCKAWAY NY 11691
K108 CIP K 19 P.S. 108 FY11 RESO A ELECTRICAL SYSTEM 345900 false -73.88403250144414 40.681012991519715 200 LINWOOD STREET Brooklyn NY 11208
Q108 CIP Q 27 P.S. 108 CAFE MULTIPURPOSE ROOM UPG 233000 false -73.81770717164864 40.67334524268887 108 10 109 AVENUE SO OZONE PARK NY 11420
X011 CIP X 9 P.S. 11 FLOOD ELMNTN/ROOFS/MASONRY/PARAPETS 6116000 false -73.92578827979769 40.83927054580515 1257 OGDEN AVENUE Bronx NY 10456
X011 CIP X 9 P.S. 11 SIDEWALK BRIDGE 19442.75 false -73.92578827979769 40.83927054580515 1257 OGDEN AVENUE Bronx NY 10456
K110 CIP K 14 P.S. 110 ROOFS/WINDOWS 3778000 false -73.94223625609604 40.723642548516075 124 MONITOR STREET Brooklyn NY 11222
M110 CIP M 1 P.S. 110 FLOOD ELIMINATION 547000 false -73.97981939917048 40.715620302518175 285 DELANCY STREET New York NY 10002
M111 CIP M 2 P.S. 111 CLIMATE CONTROL/HEATING PLANT UPGRADE 4305729 false -73.98953901918651 40.76616371249781 440 53 STREET New York NY 10019
Q111 CIP Q 30 P.S. 111 HEATING PLANT UPG/CLIMATE CTRL 3811000 false -73.93866902925225 40.74570244980828 37 15 13 STREET QUEENS NY 11101
K112 CIP K 20 P.S. 112 PARAPETS/EXT MASONRY/FLOOD ELMNTN 1420000 false -74.00071660633716 40.619828663672465 7115 15 AVENUE Brooklyn NY 11228
K115 CIP K 18 P.S. 115 EXT MASONRY/ROOFS/PARAPETS 5747000 false -73.89697682968284 40.63477746307819 1500 92ND ST Brooklyn NY 11236
M115 CIP M 6 P.S. 115 EXTERIOR MASONRY/HAZARDOUS-PARAPETS/ROOFS 2979000 false -73.93487128414608 40.84641769845956 586 177 STREET New York NY 10033
K116 CIP K 32 P.S. 116 FY11 RESO A SCIENCE 388000 false -73.91643018838859 40.69774977550555 515 KNICKERBOCKER AVENUE Brooklyn NY 11237
M116 CIP M 2 P.S. 116 FY11 RESO A PLAYGROUND REDEVELOPMENT 300000 false -73.97834193335258 40.74491153710013 210 33 STREET New York NY 10016
X012 CIP X 11 P.S. 12 HEATING PLT UPG/CLIMATE CNTRL/LOW-VOLT ELECTRICAL 5722850 false -73.84450496658253 40.84010546581863 2555 TRATMAN AVENUE Bronx NY 10461
K121 CIP K 21 P.S. 121 SWB-EXT MASONRY 1295000 false -73.97875690985585 40.62330608676003 5301 20TH AVENUE Brooklyn NY 11204
Q121 CIP Q 28 P.S. 121 CLIMATE CONTROL/HEATING PLANT UPGRADE 3305000 false -73.81770717164864 40.67334524268887 126 10 109 AVENUE SO OZONE PARK NY 11420
M123 CIP M 5 P.S. 123 FY10 RESO A SCIENCE LAB UPGRADE 444000 false -73.94425698262674 40.81972211192899 301 140 STREET New York NY 10030
Q124 CIP Q 27 P.S. 124 EXT MASONRY/PARAPETS 3342000 false -73.81770717164864 40.67334524268887 129 15 150 AVENUE SO OZONE PARK NY 11420
M124 CIP M 2 P.S. 124 (ECF) PARAPETS/EXTERIOR MASONRY 1367000 false -73.99579682364542 40.71420254465372 40 DIVISION STREET New York NY 10002
M126 CIP M 2 P.S. 126 FY10 RESO A LIBRARY 415000 false -73.9966721705172 40.710854298398544 80 CATHERINE STREET New York NY 10038
X126 CIP X 9 P.S. 126 (ECF) MASONRY/ROOFS/FLOOD ELMNTN/PARAPETS 5194000 false -73.9283372125368 40.83581122271332 175 166 STREET Bronx NY 10452
K127 CIP K 20 P.S. 127 EXT MASONRY 2149000 false -74.01885662493696 40.62406545959219 7805 7 AVENUE Brooklyn NY 11209
Q127 CIP Q 30 P.S. 127 AUD UPG/CAFETERIA MULTIPURPOSE RM UPG 985000 false -73.8723788986672 40.76341327370369 98 01 25 AVENUE EAST ELMHURST NY 11369
X129 CIP X 12 P.S. 129 (PAIRED W X234) EXTERIOR MASONRY 2598000 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
X129 CIP X 12 P.S. 129 (PAIRED W X234) SIDEWALK BRIDGE (EXT. MASONRY) 32157.31 false -73.8865507352739 40.84549455019818 2055 MAPES AVENUE Bronx NY 10460
K132 CIP K 14 P.S. 132 FLOOD ELMNTN/WINDOWS/PARAPETS 6597000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
K132 CIP K 14 P.S. 132 FY10 RESO A GYM RENOVATION 70000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
K132 CIP K 14 P.S. 132 WORK REQUIRED TO OBTAIN C OF O 932000 false -73.9456777023208 40.71219332880771 320 MANHATTAN AVENUE Brooklyn NY 11206
M132 CIP M 6 P.S. 132 FY11 RESO A SCIENCE LAB 243500 false -73.93432269770818 40.85071645775963 185 WADSWORTH AVENUE New York NY 10033
X132 CIP X 9 P.S. 132 INTERIOR STRUCTURAL INVESTMENT - TEST 5005000 false -73.90656891847989 40.83194251909681 1245 WASHINGTON AVENUE Bronx NY 10456
K135 CIP K 18 P.S. 135 PARAPETS/FLOOD ELMNTN/ROOFS 1784000 false -73.93311810571299 40.65357812334444 684 LINDEN BLVD Brooklyn NY 11203
K138 CIP K 17 P.S. 138 ROOFS/PARAPETS/EXT MASONRY 2793000 false -73.95141196170016 40.674353675202426 760 PROSPECT PLACE Brooklyn NY 11216
K138 CIP K 17 P.S. 138 SCIENCE DEMO ROOM UPGRADE 762000 false -73.95141196170016 40.674353675202426 760 PROSPECT PLACE Brooklyn NY 11216
M844 CIP M 2 P.S. 138 (@M844) SWB - FACADE/PARAPETS/ROOFS 8833000 false -73.97802974198606 40.73757796345728 400 1ST AVENUE New York NY 10010
K849 CIP K 22 P.S. 139 AX (OLD 134) LL 41/16 COMPLIANCE 100000 false -73.97391982714538 40.632244467750226 4001 18 AVENUE Brooklyn NY 11208
R014 CIP R 31 P.S. 14 ROOFS/EXT MASONRY/WINDOWS/FLOORS/SAFETY SYSTEMS 3315000 false -74.07837687526822 40.622148795415534 100 TOMPKINS AVENUE Staten Island NY 10304
Q140 CIP Q 28 P.S. 140 PARAPETS 3269000 false -73.77530690169215 40.6769452621142 116 00 166 ST JAMAICA NY 11434
M142 CIP M 1 P.S. 142 ELEVATORS & ESCALATORS/TOILETS-STUDENTS 2995000 false -73.98376386528082 40.71945606619147 100 ATTORNEY STREET New York NY 10002
K145 CIP K 32 P.S. 145 PARAPETS/FLOOD ELMNTN/EXT MASONRY/EXT LIGHTING 4737575 false -73.93232374110994 40.7016598916867 100 NOLL STREET Brooklyn NY 11206
K142 CIP K 15 P.S. 146 (@K142) PARAPETS/EXTERIOR MASONRY/ROOFS/WINDOWS/FLOOD 13106731 false -74.00136121297172 40.68011121449034 610 HENRY STREET Brooklyn NY 11231
Q147 CIP Q 29 P.S. 147 FLOORS 537000
K015 CIP K 15 P.S. 15 LIBRARY UPGRADE 411054
M153 CIP M 6 P.S. 153 DEFECTIVE MASONRY/ROOFS/DOORS/PARAPETS 4134000 false -73.94689450753023 40.8262600138953 1750 AMSTERDAM AVENUE New York NY 10031
Q154 CIP Q 25 P.S. 154 ACCESSIBILITY/ELEC SYS/MASONRY/ROOFS/FLOOD/PARAPET 6127000 false -73.79226817393703 40.72816440726166 75 02 162 STREET FLUSHING NY 11366
M155 CIP M 4 P.S. 155 FLOOD ELMNTN/PARAPETS/EXT MASONRY 2350000 false -73.93679763009355 40.797501313680264 319 117 STREET New York NY 10035
Q156 CIP Q 29 P.S. 156 SWB - EXT MASONRY/FLOOD ELMNTN/WINDOWS/PARAPETS 7354000 false -73.75087393328533 40.66971118122609 229 02 137 AVENUE SPRINGFIELD GAR NY 11413
X156 CIP X 7 P.S. 156 CINDER BLOCK WALLS & CEILING BEAMS/FLOOD ELIMN 9780000 false -73.92024166597307 40.82226334901861 750 CONCOURSE VILLAGE Bronx NY 10451
K157 CIP K 14 P.S. 157 SWB-MASONRY 1843000 false -73.95959701353979 40.69546110023352 850 KENT AVENUE Brooklyn NY 11205
X157 CIP X 7 P.S. 157 FY11 RESO A LIBRARY UPGRADE 178000 false -73.90861019557366 40.81920242494304 757 CAULDWELL AVENUE Bronx NY 10456
K158 CIP K 19 P.S. 158 EXT MASONRY/FLOOD ELIMINATION 4244000 false -73.88480467674624 40.672471173748015 400 ASHFORD STREET Brooklyn NY 11207
K016 CIP K 14 P.S. 16 CEC REQUEST - STUDENT CAFETERIA UPG 1139000 false -73.96144993294666 40.706051659903764 157 WILSON STREET Brooklyn NY 11211
X160 CIP X 11 P.S. 160 FY11 RESO A LIBRARY 345300 false -73.8242748469253 40.86466106194175 4140 HUTCHINSON RIVER PARKWAY Bronx NY 10475
K161 CIP K 17 P.S. 161 LIBRARY UPGRADE 89500 false -73.94885261044026 40.66615564566118 330 CROWN STREET Brooklyn NY 11225
X163 CIP X 9 P.S. 163 INTERIOR MODERNIZATIONS/ROOFS 3143000 false -73.89841328719618 40.85190466527893 2075 WEBSTER AVENUE Bronx NY 10457
M165 CIP M 3 P.S. 165 ROOF TILES & SNOW GUARD/EXT MASONRY/FLOOD/PARAPETS 2118994.65 false -73.96526411800443 40.80275180384162 234 109 STREET New York NY 10025
K017 CIP K 14 P.S. 17 WINDOWS/EXT MASONRY/FLOOD ELMNTN/ROOFS/PARAPETS 7842000 false -73.95663645640386 40.715277522913524 208 5 STREET Brooklyn NY 11211
M173 CIP M 6 P.S. 173 FIRE ALARM 359900 false -73.94042010106682 40.84561730185351 306 FORT WASHINGTON AVE New York NY 10033
Q174 CIP Q 28 P.S. 174 FY11 RESO A LIBRARY UPGRADE 104000 false -73.86148084756303 40.72646491702238 65 10 DIETERLE CRESCENT REGO PARK NY 11374
Q175 CIP Q 28 P.S. 175 FY11 RESO A FENCING 319571 false -73.86148084756303 40.72646491702238 64 35 102 STREET REGO PARK NY 11374
X175 CIP X 11 P.S. 175 INTERIOR MODERNIZATIONS/WINDOWS 5296000 false -73.78516944174876 40.84381012246547 200 CITY ISLAND AVENUE Bronx NY 10464
K178 CIP K 23 P.S. 178 FLOORS 695000 false -73.9159181765978 40.675074588842676 2163 DEAN STREET Brooklyn NY 11212
Q178 CIP Q 26 P.S. 178 HEATING PLANT UPGRADE/CLIMATE CONTROL/MASONRY 7100000 false -73.7671414999802 40.71722229567246 189 10 RADNOR RD JAMAICA NY 11423
R018 CIP R 31 P.S. 18 BOILER REPLACEMENT 3171000 false -74.11747369098056 40.63603930909672 221 BROADWAY Staten Island NY 10310
X182 CIP X 8 P.S. 182 BRICK MASONRY WATER PENETRATION/WINDOWS 3464027 false -73.85625766017206 40.817936957362555 601 STICKBALL BLVD BRONX NY 10473
Q183 CIP Q 27 P.S. 183 MSNRY/SFTY/WINDOW/LIBRARY UPG/HVAC/ROOF/FIRE ALARM 8248000 false -73.82495531523557 40.6183036047276 2 45 BEACH 79 STREET ROCKAWAY BEACH NY 11693
M137 CIP M 1 P.S. 184 (SHUANG WEN @M137) FY11 RESO A PLAYGROUND REDEVELOPMENT 230000 false -73.98042410080346 40.71217484702834 327 CHERRY ST New York NY 10002
M137 CIP M 1 P.S. 184 (SHUANG WEN @M137) SWB-HAZARDOUS VIOLATION/ROOFS 979000 false -73.98042410080346 40.71217484702834 327 CHERRY ST New York NY 10002
Q186 CIP Q 26 P.S. 186 ACCESSIBILITY/FIRE ALARM SYSTEM/ELECTRICAL SYSTEMS 4577000 false -73.72415699894628 40.73704138495202 252 12 72 AVENUE BELLEROSE NY 11426
Q186 CIP Q 26 P.S. 186 FLOOD ELIMINATION 968000 false -73.72415699894628 40.73704138495202 252 12 72 AVENUE BELLEROSE NY 11426
K188 CIP K 21 P.S. 188 RESO A GYM ADDITION/FY10 RESO A PLAYGROUND 7879007 false -74.00012292790208 40.57720405091032 3314 NEPTUNE AVENUE Brooklyn NY 11224
M188 CIP M 1 P.S. 188 ACCESSIBILITY 6422000 false -73.97792876586212 40.719709960041634 442 HOUSTON STREET New York NY 10002
M188 CIP M 1 P.S. 188 EXTERIOR MASONRY/ROOFS/PARAPETS/WINDOWS 13457000 false -73.97792876586212 40.719709960041634 442 HOUSTON STREET New York NY 10002
K189 CIP K 17 P.S. 189 LOW-VOLT SYSTEM 840000 false -73.92626797722787 40.66553683638519 1100 NEW YORK AVE Brooklyn NY 11212
Q019 CIP Q 24 P.S. 19 SWB - EXT MASONRY/ROOFS/FLOOD ELIMINATION/PARAPETS 16175000 false -73.85304068857687 40.749678220373596 98 02 ROOSEVELT AVE CORONA NY 11368
R019 CIP R 31 P.S. 19 IP SURVEILLANCE CAMERAS 1270000 false -74.127115288525 40.631189624083056 780 POST AVENUE Staten Island NY 10310
K190 CIP K 19 P.S. 190 PARAPETS/ROOFS/EXT MASONRY 6720000 false -73.89448660618348 40.66233878188243 590 SHEFFIELD AVENUE Brooklyn NY 11207
K191 CIP K 17 P.S. 191 SAFETY SYSTEMS 345900 false -73.92433266937152 40.671984269991356 1600 PARK PLACE Brooklyn NY 11233
X198 CIP X 12 P.S. 198 PLANYC BOILER CONVRSN/PLANYC CLIMATE CTRL 3794000 false -73.90058806585479 40.82868626889099 1180 TINTON AVENUE Bronx NY 10456
K199 CIP K 21 P.S. 199 FY11 RESO A LIBRARY 369000 false -73.96308897272426 40.61673348809886 1100 ELM AVENUE Brooklyn NY 11230
R020 CIP R 31 P.S. 20 EXT MASONRY/ROOFS/WINDOWS 3285000 false -74.13295576709373 40.63651173103697 161 PARK AVENUE Staten Island NY 10302
X020 CIP X 10 P.S. 20 ROOFS 1470000 false -73.87958395897564 40.869529034465444 3020 WEBSTER AVENUE BRONX NY 10467
K203 CIP K 22 P.S. 203 EXT MASONRY/ROOFS/PARAPETS/FLOOD ELMNTN 5668000 false -73.92773224974349 40.61636866748006 5101 AVENUE Brooklyn NY 11234
Q206 CIP Q 28 P.S. 206 FLOOD ELIMINATION 283000 false -73.86148084756303 40.72646491702238 61 02 98TH STREET REGO PARK NY 11374
M206 CIP M 4 P.S. 206 (TANDEM PS 112) EXT MASONRY/PARAPETS/FLD ELIMINATION/ROOFS/WALKWAY 5822870 false -73.93112623193574 40.79754733338499 508 120TH STREET New York NY 10035
R021 CIP R 31 P.S. 21 FLOORS 418000 false -74.14676832354822 40.63194814504947 168 HOOKER PLACE Staten Island NY 10303
X021 CIP X 11 P.S. 21 PARAPETS/EXT MASONRY/FLOOD ELIMINATION/ROOFS 5259000 false -73.86044891659131 40.88782430615607 715 225 STREET Bronx NY 10466
K214 CIP K 19 P.S. 214 EXT MASONRY/PARAPETS/FLOOD/WINDOWS/ROOFS 7654000 false -73.8631601400929 40.67649228343164 2944 PITKIN AVENUE Brooklyn NY 11208
Q215 CIP Q 27 P.S. 215 FY11 RESO A SCIENCE LAB UPGRADES 260000 false -73.75832418340367 40.59915376512268 535 BRIAR PLACE FAR ROCKAWAY NY 11691
K219 CIP K 18 P.S. 219 EXT MASONRY/PARAPETS/ROOFS 3079000 false -73.92291949545782 40.65925656671725 1060 CLARKSON AVENUE Brooklyn NY 11212
Q022 CIP Q 25 P.S. 22 FY10 RESO A NEW PLAYGROUND 180000 false -73.82147854789662 40.7512997969481 153 01 SANFORD AVENUE FLUSHING NY 11355
R022 CIP R 31 P.S. 22 LIBRARY UPGRADE 340000 false -74.15109445915424 40.62530363633885 1860 FOREST AVENUE Staten Island NY 10303
K225 CIP K 21 P.S. 225 ACCESSIBILITY/FIRE ALARM/ELECTRICAL SYSTEMS 4105450 false -73.95643350547934 40.5797910944251 1075 OCEAN VIEW AVENUE Brooklyn NY 11235
Q229 CIP Q 24 P.S. 229 SWB - MASONRY/ROOFS 3633000 false -73.9048471440804 40.74519376448069 67 25 51 ROAD WOODSIDE NY 11377
X229 CIP X 9 P.S. 229 ELEVATORS & ESCALATORS 1327150 false -73.92150462714196 40.85261854069672 275 HARLEM RIVER PARK BR Bronx NY 10453
X229 CIP X 9 P.S. 229 PLANYC BOILER/PLANYC CLIMATE CTRL 2910000 false -73.92150462714196 40.85261854069672 275 HARLEM RIVER PARK BR Bronx NY 10453
K230 CIP K 15 P.S. 230 ACCESSIBILITY 4392000 false -73.98088211473515 40.64501828504539 1 ALBEMARLE ROAD Brooklyn NY 11210
Q232 CIP Q 27 P.S. 232 FY11 RESO A SCIENCE LAB UPGRADES 384000 false -73.84496263981396 40.65817022817356 153 23 83 STREET HOWARD BEACH NY 11414
K236 CIP K 22 P.S. 236 EXT MASONRY/FLOOD ELIMINATION 1054000 false -73.92773224974349 40.61636866748006 6302 AVENUE Brooklyn NY 11234
K249 CIP K 17 P.S. 249 EXT MASONRY/ROOFS/PARAPETS 4474000 false -73.96609617601914 40.649842155595174 18 MARLBOROUGH ROAD Brooklyn NY 11226
K249 CIP K 17 P.S. 249 FY11 RESO A AUDITORIUM UPGRADE 198000 false -73.96609617601914 40.649842155595174 18 MARLBOROUGH ROAD Brooklyn NY 11226
K253 CIP K 21 P.S. 253 BOILER PLANT/CLIMATE CONTROL 4282800 false -73.96219337408164 40.579594157400855 601 OCEAN VIEW AVENUE Brooklyn NY 11235
Q816 CIP Q 27 P.S. 256 ANNEX WINDOWS/EXT MASONRY 5282000 false -73.85454217391299 40.576996863641924 445 BEACH 135 STREET QUEENS NY 11694
K026 CIP K 16 P.S. 26 PLANYC BOILER/PLANYC CLIMATE CTRL 3960000 false -73.93167037460694 40.69211086975316 1010 LAFAYETTE AVENUE Brooklyn NY 11221
Q026 CIP Q 26 P.S. 26 ELECTRICAL SYSTEM 594999 false -73.79462153515567 40.73987184371066 195 02 69 AVENUE FLUSHING NY 11365
K262 CIP K 16 P.S. 262 NEW SCIENCE DEMONSTRATION ROOM 534000 false -73.93085733477353 40.68321860795158 500 MACON STREET Brooklyn NY 11233
K273 CIP K 19 P.S. 273 EXT MASONRY/ROOFS/PARAPETS 5335000 false -73.87935692616207 40.65796581134507 923 JEROME STREET Brooklyn NY 11207
X027 CIP X 7 P.S. 277 (@ X027) SWB-ROOF/SWB-EXT MASONRY/WINDOWS/PARAPETS/ HEATING 15843000 false -73.91337206062776 40.813641430845045 519 ST ANNS AVENUE Bronx NY 10451
X279 CIP X 10 P.S. 279 FIRE ALARM UPGRADE 2998000 false -73.90550751626725 40.85444390420279 2100 WALTON AVE BRONX NY 10453
X028 CIP X 9 P.S. 28 EXTERIOR MASONRY/PARAPETS/FLOOD ELIMINATION 5016000 false -73.90357863607737 40.84796917302349 1861 ANTHONY AVENUE Bronx NY 10456
K284 CIP K 23 P.S. 284 SWB-PARAPET-MASONRY/EXTERIOR MASONRY 5680000 false -73.90818838446248 40.66735004908563 213 OSBORN STREET Brooklyn NY 11212
K289 CIP K 17 P.S. 289 WINDOW/CAFE MULTIPURPOSE RM UPG/MASONRY/PARAPET/PA 4440000 false -73.94240595654854 40.67477355898667 900 ST MARKS AVENUE Brooklyn NY 11213
R029 CIP R 31 P.S. 29 PARAPETS/EXT MASONRY/ROOFS 3826000 false -74.11613224214713 40.61361168930647 1581 VICTORY BLVD Staten Island NY 10314
K003 CIP K 13 P.S. 3 PARAPETS/EXT MASONRY/ROOF/PLAYGROUND REDEVELOPMENT 4820800 false -73.9554933572393 40.68262499957862 50 JEFFERSON AVENUE Brooklyn NY 11216
M003 CIP M 2 P.S. 3 FLOORS/INTERIOR SPACES 3824000 false -74.00641883360943 40.73261607852907 490 HUDSON STREET New York NY 10014
R003 CIP R 31 P.S. 3 LIGHTING FIXTURES 934104 false -74.21279962614892 40.52665926345466 80 GOFF AVENUE Staten Island NY 10309
K306 CIP K 19 P.S. 306 PLAYGROUND REDEVELOPMENT 1071501 false -73.88669548652338 40.65614802525013 970 VERMONT STREET Brooklyn NY 11207
K308 CIP K 16 P.S. 308 PAVED AREA-BLACKTOP & TCU 437000 false -73.93578222590314 40.6886393472372 616 QUINCY STREET Brooklyn NY 11221
X122 CIP X 10 P.S. 310 (@ X122) FY10 RESO A AUDITORIUM UPG 205000 false -73.90565533914132 40.873019134707036 260 KINGSBRIDGE RD Bronx NY 10463
K316 CIP K 17 P.S. 316 HOT WATER HEATER 375000 false -73.96025809844292 40.67448517044413 750 CLASSON AVENUE Brooklyn NY 11238
K032 CIP K 15 P.S. 32 FY11 RESO A LIBRARY UPGRADE 357960 false -73.99193273420018 40.680429275762485 317 HOYT STREET Brooklyn NY 11231
X032 CIP X 10 P.S. 32 VINYL FLR/BOILER RM/CLIMATE CTRL/HEAT PLANT 15839000 false -73.88593877891165 40.85208555646217 690 183 STREET Bronx NY 10458
K329 CIP K 21 P.S. 329 WINDOWS/ROOFS 4659000 false -73.99625853857127 40.5746069203897 2929 30 STREET Brooklyn NY 11212
X033 CIP X 10 P.S. 33 GUTTERS, DOWNSPOUTS & DRAINGAGE/FLOOD/EXT MASONRY 2965000 false -73.90165549892143 40.86194912850306 2424 JEROME AVENUE Bronx NY 10468
K034 CIP K 14 P.S. 34 ROOFS 1297000 false -73.94966946764082 40.72614326106391 131 NORMAN AVENUE Brooklyn NY 11222
Q034 CIP Q 29 P.S. 34 PLAYGROUND & TCU REMOVAL 1375500 false -73.74193729726841 40.721396964798146 104 12 SPRINGFIELD BLVD QUEENS VILLAGE NY 11428
M036 CIP M 5 P.S. 36 REINFORCE SUPPRT ELEMT/MASONRY/FLOOD/PARAPET/ ROOF 7179000 false -73.95760614504678 40.81034589186436 123 MORNINGSIDE DRIVE New York NY 10027
R036 CIP R 31 P.S. 36 PARAPETS 617000 false -74.18245006610681 40.54294395216458 255 IONIA AVENUE Staten Island NY 10312
Q037 CIP Q 29 P.S. 37 FLOOD ELMNTN 4627000 false -73.77530690169215 40.6769452621142 179 37 137 AVENUE JAMAICA NY 11434
K370 CIP K 21 P.S. 370 PLAYGROUND REDEVELOPMENT 2587000 false -73.96958337858405 40.577497294548174 3000 1 STREET Brooklyn NY 11224
K370 CIP K 21 P.S. 370 WINDOWS/FLOOD ELIMNTN/MASONRY/ROOFS/PARAPETS 6920000 false -73.96958337858405 40.577497294548174 3000 1 STREET Brooklyn NY 11224
R040 CIP R 31 P.S. 373 (SP ED) @R040 ROOFS/PARAPETS 824000 false -74.09531252948968 40.64071111953775 91 HENDERSON AVENUE Staten Island NY 10301
K384 CIP K 32 P.S. 384 LL 41/16 COMPLIANCE 275000 false -73.90500308262318 40.69009686200851 242 COOPER STREET Brooklyn NY 11221
R004 CIP R 31 P.S. 4 FY09 RESO A TECHNOLOGY 90290.18
Q040 CIP Q 28 P.S. 40 CEC REQUEST-TOILETS STUDENTS 889000
Q040 CIP Q 28 P.S. 40 EXTERIOR MASONRY/PARAPETS 2520000
Q040 CIP Q 28 P.S. 40 PLAYGROUND REDEVELOPMENT 1424537
M041 CIP M 2 P.S. 41 SWB-EXTERIOR MASONRY/WINDOWS/AUD. CEILING/PARAPETS 3447868 false -73.99904466974961 40.735686525332646 116 11 STREET New York NY 10011
Q041 CIP Q 26 P.S. 41 MASONRY SUPPORT REPAIR/PARAPETS 2564500 false -73.77481079967868 40.773606900238235 214 43 35 AVENUE BAYSIDE NY 11261
R041 CIP R 31 P.S. 41 FY10 RESO A PA SYSTEMS 448000 false -74.10928336025026 40.574024158045525 216 CLAWSON STREET Staten Island NY 10306
R045 CIP R 31 P.S. 45 TOILETS STUDENTS 999999 false -74.10718417740732 40.62863428073003 58 LAWRENCE AVENUE Staten Island NY 10310
R045 CIP R 31 P.S. 45 WATER PENETRATION 579900 false -74.10718417740732 40.62863428073003 58 LAWRENCE AVENUE Staten Island NY 10310
K046 CIP K 13 P.S. 46 SCIENCE DEMO ROOM 376999 false -73.9711875089949 40.694634881525445 100 CLERMONT AVENUE Brooklyn NY 11205
M046 CIP M 5 P.S. 46 SCIENCE DEMO LAB 512000
Q046 CIP Q 26 P.S. 46 CORRIDOR SPACES 290000 false -73.75790275560763 40.745924680379744 64 45 218TH STREET QUEENS NY 11364
K048 CIP K 20 P.S. 48 EXT MASONRY/PARAPETS/ROOFS 5315000
Q050 CIP Q 28 P.S. 50 SWB EXT MASONRY/PARAPETS/ROOFS 1900000 false -73.80979665579099 40.70119264912154 143 26 101 AVENUE JAMAICA NY 11435
R050 CIP R 31 P.S. 50 BOILER REPLACEMENT/CLIMATE CONTROL 3330000 false -74.12474473444865 40.561729222740695 200 ADELAIDE AVENUE Staten Island NY 10306
X050 CIP X 12 P.S. 50 FLOOD ELIMINATION 818000 false -73.88769223705626 40.83380386816254 1550 VYSE AVENUE Bronx NY 10460
M050 CIP M 4 P.S. 50 (UDC & ECF) PLANYC BOILER CONVERSION/PLANYC CLIMATE CONTROL 3174000 false -73.94222449721103 40.78556522081211 433 100 STREET New York NY 10029
Q051 CIP Q 27 P.S. 51 (ECC) EXTERIOR MASONRY 1023000 false -73.84031024991805 40.69637041236467 87 45 117TH STREET QUEENS NY 11418
Q052 CIP Q 29 P.S. 52 SWB EXT MASONRY 2700000 false -73.77530690169215 40.6769452621142 178 37 146 TERRACE SPRINGFIELD GARDENS NY 11434
R053 CIP R 31 P.S. 53 FENCING/PAVED AREAS-CONCRETE 675000 false -74.13710643405284 40.55253899268856 330 DURANT AVENUE Staten Island NY 10308
R054 CIP R 31 P.S. 54 PARAPETS/ROOFS/WINDOWS/EXT MASONRY 5847000 false -74.13792964309168 40.60321556338597 1060 WILLOWBROOK RD Staten Island NY 10314
Q055 CIP Q 28 P.S. 55 SWB-BULGING MASONRY/PARAPETS 4795000 false -73.82288833053201 40.68871379040917 131 10 97 AVENUE RICHMOND HILL NY 11419
R055 CIP R 31 P.S. 55 ROOFS/CEC REQUEST-MASONRY/FLOOD ELMNTN/PARAPETS 1890000 false -74.16332659953605 40.53686781464157 54 OSBORNE STREET Staten Island NY 10312
X055 CIP X 9 P.S. 55 EXTERIOR MASONRY/PARAPETS 1285000 false -73.90461113077222 40.836276563944345 450 SAINT PAUL'S PLACE Bronx NY 10456
K056 CIP K 13 P.S. 56 PLANYC CLIMATE/BOILER CONTROL 5240000 false -73.960643681102 40.68503684353989 170 GATES AVENUE Brooklyn NY 11238
R057 CIP R 31 P.S. 57 PLANYC PLAYGROUND 613715.9 false -74.08283106498078 40.61136129612238 140 PALMA DRIVE Staten Island NY 10304
K006 CIP K 17 P.S. 6 (PS 600B) BLDG MANAGEMENT SYSTEM 2269000
K006 CIP K 17 P.S. 6 (PS 600B) EXT MASONRY/ROOFS 773000
X060 CIP X 8 P.S. 60 FLOOD/EXT MASONRY/CEC REQUEST-PARAPET/ROOFS/WINDOW 14619000 false -73.89313106784448 40.82552621616202 888 REV J A POLITE AVE Bronx NY 10459
X061 CIP X 12 P.S. 61 FIRE ALARM 349119 false -73.89295310872916 40.836569959473785 1550 CROTONA PARK Bronx NY 10460
X061 CIP X 12 P.S. 61 IP SURVEILLANCE CAMERAS 1528000 false -73.89295310872916 40.836569959473785 1550 CROTONA PARK Bronx NY 10460
X064 CIP X 9 P.S. 64 BATHROOMS 4TH & 5TH FLR 508499 false -73.91558081775857 40.8401115358764 1425 WALTON AVENUE Bronx NY 10452
Q066 CIP Q 27 P.S. 66 FLOOD ELIMINATION/EXT MASONRY/PARAPETS 1110000 false -73.84031024991805 40.69637041236467 85 11 102 STREET RICHMOND HILL NY 11418
M066 CIP M 2 P.S. 66 (RICHARD R GREEN) CAFE MULTIPURPOSE ROOM 482000 false -74.02858656018857 40.62102637693336 421 88 STREET New York NY 10028
X068 CIP X 11 P.S. 68 ELEVATORS & ESCALATORS 688000 false -73.83837769297637 40.89141479468151 4011 MONTICELLO AVENUE Bronx NY 10466
R069 CIP R 31 P.S. 69 FENCING 234000 false -74.15650379993006 40.59169714382341 144 KEATING PLACE Staten Island NY 10314
X007 CIP X 10 P.S. 7 ROOFS/EXT MASONRY/PARAPETS 4700000 false -73.90547390792568 40.881013909978904 3201 KINGSBRIDGE AVENUE Bronx NY 10463
Q071 CIP Q 24 P.S. 71 FLOOD ELIMINATION 408990 false -73.88334858436963 40.70122489161548 62 85 FOREST AVENUE RIDGEWOOD NY 11385
X072 CIP X 8 P.S. 72 BATHROOM 668000 false -73.81850425419442 40.822539080023574 2951 DEWEY AVENUE Bronx NY 10465
K722 CIP K 21 P.S. 721 OTC TILTED FIELD LIGHTING 1396800 false -73.97331147204676 40.596939623165156 64 AVENUE Brooklyn NY 11223
M641 CIP M 2 P.S. 721 OTC SP ED FLOOD ELIMINATION 1897000 false -74.00542114697957 40.72862785368122 250 HOUSTON ST MANHATTAN NY 10014
K073 CIP K 23 P.S. 73 SWB EXT MSNRY/SWB PARAPETS/SWB FLOOD/ROOFS 3084000 false -73.91089377023927 40.68032732647815 251 MCDOUGAL STREET Brooklyn NY 11233
X075 CIP X 8 P.S. 75 ROOFS/EXT MASONRY 2549000 false -73.88942113898915 40.822818392634325 984 FAILE STREET Bronx NY 10459
X155 CIP X 7 P.S. 754 (@X155) CAFE/MULTIPURPOSE RM UPGRADE/FLOOD ELIMINATION 1230000 false -73.90975689502312 40.81117582303449 470 JACKSON AVENUE BRONX NY 10455
X155 CIP X 7 P.S. 754 (@X155) FY11 REOS A LIBRARY UPGRADE 299155 false -73.90975689502312 40.81117582303449 470 JACKSON AVENUE BRONX NY 10455
Q076 CIP Q 30 P.S. 76 EXTERIOR MASONRY/PARAPETS 2284875 false -73.91327185810974 40.76286893025696 36 36 10 STREET QUEENS NY 11103
X076 CIP X 11 P.S. 76 MASONRY/PARAPETS/FLOOD ELMNTN/ROOFS 4042000 false -73.8614028579785 40.86957454109854 900 ADEE AVENUE Bronx NY 10469
X078 CIP X 11 P.S. 78 AUDITORIUM UPGRADE/STUDENT TOILETS 715000 false -73.8513380848076 40.87847023359842 1400 NEEDHAM AVENUE Bronx NY 10469
Q079 CIP Q 25 P.S. 79 ELEC SYSTEMS 258100 false -73.81123206101074 40.78628404147537 147 27 15 DRIVE WHITESTONE NY 11357
R008 CIP R 31 P.S. 8 ELEC SYSTEM 790000 false -74.1517569152093 40.54764073027023 112 LINDENWOOD ROAD Staten Island NY 10308
R880 CIP R 31 P.S. 80 (PETRIDES BLDG B) WINDOWS/EXT MASONRY 3228000
Q081 CIP Q 24 P.S. 81 FLOOD ELIM/STRUCTURAL:FLOOR SYS/EXT MASONRY 1274800 false -73.91225035614077 40.70373293561221 559 CYPRESS AVENUE RIDGEWOOD NY 11237
X081 CIP X 10 P.S. 81 FLOOD ELIMINATION 474000 false -73.90520839316682 40.903559546831026 5550 RIVERDALE AVENUE Bronx NY 10471
Q848 CIP Q 24 P.S. 81 ANNEX (@Q848) FLOOD ELIMINATION/EXT MASONRY 2390270
Q811 CIP Q 26 P.S. 811 (OL 187 - CMCH) LL 41/16 COMPLIANCE 954000 false -73.73430017711144 40.759074216601846 61 25 MARATHON PKWY QUEENS NY 11362
Q811 CIP Q 26 P.S. 811 (OL 187 - CMCH) LOW VOLTAGE 560000 false -73.73430017711144 40.759074216601846 61 25 MARATHON PKWY QUEENS NY 11362
M841 CIP M 3 P.S. 811(@ M841) WORK REQUIRED TO OBTAIN C OF O 1880750 false -73.96653900057436 40.78362556816552 466 END AVENUE NEW YORK NY 10024
Q082 CIP Q 28 P.S. 82 WATER PENETRATION 1120000 false -73.80979665579099 40.70119264912154 88 02 144 STREET QUEENS NY 11435
X083 CIP X 11 P.S. 83 ACCESSIBILITY 3377000 false -73.85933122663833 40.849332468676785 950 RHINELANDER AVENUE Bronx NY 10462
Q085 CIP Q 30 P.S. 85 FLOOD ELMNTN/ROOFS/EXT MASONRY/PARAPETS 3111000 false -73.90960650023976 40.780092072491186 23 70 31 STREET QUEENS NY 11105
X085 CIP X 10 P.S. 85 RETAINING WALL 1596000 false -73.89472052099663 40.859331900138066 2400 MARION AVENUE Bronx NY 10458
K086 CIP K 32 P.S. 86 FLOOD ELMNTN/EXT MASONRY 4269000 false -73.91749723727719 40.7007452458598 220 IRVING AVENUE Brooklyn NY 11237
X086 CIP X 10 P.S. 86 ELEVATORS & ESCALATORS 747400 false -73.89880422371779 40.869715575827065 2756 RESERVOIR AVENUE Bronx NY 10468
K009 CIP K 13 P.S. 9 PAVED AREA - BLACKTOP 974000
X009 CIP X 10 P.S. 9 (OLD 115) ACCESSIBILITY 6177000 false -73.89936166242526 40.8571875830873 230 183 STREET Bronx NY 10458
Q090 CIP Q 27 P.S. 90 ELEC SYSTEMS 778000 false -73.84031024991805 40.69637041236467 86 50 109 STREET RICHMOND HILL NY 11418
Q090 CIP Q 27 P.S. 90 SWB - EMERGENCY MASONRY REPAIRS/PARAPETS 3769000 false -73.84031024991805 40.69637041236467 86 50 109 STREET RICHMOND HILL NY 11418
X090 CIP X 9 P.S. 90 EXTERIOR MASONRY/RETAINING WALLS 1857000 false -73.91794566527413 40.83197402670032 1116 SHERIDAN AVENUE Bronx NY 10456
K093 CIP K 13 P.S. 93 FLOORS 1748375 false -73.94682098403624 40.679147761017056 31 NEW YORK AVENUE Brooklyn NY 11216
K094 CIP K 15 P.S. 94 PLANYC PLAYGROUND 264500 false -74.0082060957207 40.64372817395559 5010 6TH AVENUE Brooklyn NY 11220
K095 CIP K 21 P.S. 95 EXT MASONRY/WINDOWS 3373000 false -73.97512954825021 40.595683557953876 345 VAN SICKLEN STREET Brooklyn NY 11223
M271 CIP M 2 P.S./I.S. 217 ROOSEVELT ISLAND ROOFS/EXT MASONRY/WINDOWS/PARAPETS 8444000 false -73.94703392787746 40.76494453865442 645 MAIN STREET New York NY 10044
M495 CIP M 4 PARK EAST ALT HS FY10 RESO A SCIENCE LAB 759354 false -73.94403228106489 40.79161072055837 230 34 EAST 105 STREET New York NY 10029
M495 CIP M 4 PARK EAST ALT HS WATER DAMAGE & MASONRY/ROOF/PARAPETS/WINDOWS 2887000 false -73.94403228106489 40.79161072055837 230 34 EAST 105 STREET New York NY 10029
Q102 CAP Q 24 PS 102 Addition Addition 56222000 false -73.87835115518163 40.73871040256307 55 24 Van Horn St Elmhurst NY 11373
Q013 CAP Q 24 PS 13 Addition Addition 41250000 false -73.87835115518163 40.73871040256307 55 01 94th St Elmhurst NY 11373
M130 CIP M 2 PS 130 SWB-WINDOWS 1327000 false -73.99859121725036 40.7186139475248 143 BAXTER STREET New York NY 10013
K317 CAP K 13 PS 133 New 66224000 false -73.98070466529857 40.68047819552629 610 Baltic St Brooklyn NY 11217
Q143 CIP Q 24 PS 143 FY10 RESO A PA SYSTEM 189000 false -73.85304068857687 40.749678220373596 34 74 113 STREET CORONA NY 11368
K160 CAP K 20 PS 160 Annex Addition 38772000 false -73.99911127943953 40.637367859169615 5105 Fort Hamilton Pkwy Brooklyn NY 11219
X136 CIP X 12 PS 186 COMPUTER LAB FLOOD ELIMINATION/EXTERIOR RAMPS & CANOPIES 968700 false -73.89748338090764 40.8318681052202 750 JENNINGS STREET Bronx NY 10459
Q196 CAP Q 28 PS 196 Addition Addition 29800000 false -73.84628429608335 40.720707263029794 71 25 113th St Forest Hills NY 11375
K264 CAP K 20 PS 264 New 39814903 false -74.02907223284222 40.62112765715576 8818 4th Ave Brooklyn NY 11209
Q280 CAP Q 30 PS 280 Lease 6230000 false -73.88361254528269 40.75163073936716 34 20 94th St Jackson Heights NY 11372
Q280 CAP Q 30 PS 280 Lease 7250000 false -73.88361254528269 40.75163073936716 34 20 94th St Jackson Heights NY 11372
Q029 CAP Q 25 PS 29 Addition Addition 20180000 false -73.84181070040347 40.7849280967543 125 10 23rd Ave College Point NY 11356
Q290 CIP Q 24 PS 290 DEMOLITION FOR PS 290 3370000 false -73.88334858436963 40.70122489161548 55 20 METROPOLITAN AVE RIDGEWOOD NY 11385
X292 CAP X 11 PS 292 New 31927000 false -73.86385184249058 40.85441144971648 800 Lydig Ave Bronx NY 10462
K310 CAP K 20 PS 310 New 26400000 false -74.00762713591367 40.632432204151364 942 62nd St Brooklyn NY 11219
K331 CAP K 20 PS 331 New 51133300 false -74.02392108137985 40.633713521609366 7002 4th Ave Brooklyn NY 11209
Q198 CIP Q 27 PS 333 @ 198 SCIENCE DEMO ROOM UPGRADE 670000 false -73.79540208463845 40.593133885620375 3 65 BEACH 56 STREET QUEENS NY 11692
Q042 CAP Q 27 PS 42 Addition Addition 43065000 false -73.79529882397365 40.59475372321819 488 Beach 66th St Arverne NY 11692
Q043 CIP Q 27 PS 43 FIRE ALARM SYSTEM 1982000 false -73.76182654029463 40.594515128003 160 BEACH 29TH STREET ROCKAWAY NY 11691
M338 CAP M 2 PS 51 New 54730000 false -73.99547864190042 40.761366217679694 525 44th St New York NY 10036
R071 CAP R 31 PS 71 New 53450000 false -74.09118595249046 40.60412964758937 1050 Targee St Staten Island NY 10304
K008 CAP K 13 PS 8 Addition Addition 21230000 false -73.9932378538064 40.700668802148385 37 Hicks St Brooklyn NY 11201
M916 CAP M 5 PS 916 Lease 0 false -73.95327141286555 40.81245030541294 168 Morningside Ave New York NY 10027
X177 CAP X 10 PS/IS 177 New 48888000 false -73.8752514350975 40.87277450072955 3177 Webster Ave Bronx NY 10467
Q277 CAP Q 28 PS/IS 277 New 47135000 false -73.79282099978928 40.71311535449007 153 27 88th Ave Jamaica NY 11432
M281 CAP M 2 PS/IS 281 New 47580000 false -73.97273509303172 40.74436150165521 425 35th St New York NY 10016
Q312 CAP Q 30 PS/IS 312 New 47820000 false -73.93866902925225 40.74570244980828 46 08 5th St Long Island City NY 11101
X784 CAP X 11 PS/IS 784 New 0 false -73.84367515955307 40.85710649548991 1500 Pelham Pkwy Bronx NY 10461
K990 CAP K 15 Pave Charter School New 25933333 false -74.00338737261256 40.67592711246962 732 Henry St Brooklyn NY 11231
Q475 CIP Q 27 RICHMOND HILL HS SWB - EXT MASONRY/WINDOWS/ROOFS 9333000 false -73.84031024991805 40.69637041236467 89 30 114 STREET QUEENS NY 11418
K655 CIP K 15 SARAH J HALE VOCATIONAL HS ACCESSIBILITY/SAFETY 2450000 false -73.98061564042008 40.68371105568558 345 DEAN STREET Brooklyn NY 11217
K218 CIP K 19 SCH FOR CLASSICS:ACAD OF THINK NEW SCIENCE LAB SUITE 845000 false -73.8742292684109 40.67070199017694 370 FOUNTAIN AVENUE Brooklyn NY 11208
M660 CIP M 2 SCHOOL OF THE FUTURE @MD BACON FLOOD ELIMINATION 618000 false -73.98552809234425 40.73900208799275 127 22 STREET NEW YORK NY 10010
Q751 CIP Q 30 SCHOOL SAFETY PARKING LOT SCHOOL SAFETY PARKING LOT 2648000 false -73.93866902925225 40.74570244980828 43 30 DUTCH KILLS STREET LONG ISLAND CITY NY 11101
M445 CIP M 2 SEWARD PARK HS CAFETERIA MULTIPURPOSE RM UPG 929000 false -73.98959502962896 40.716852373698316 350 GRAND STREET New York NY 10002
K515 CIP K 18 SOUTH SHORE HS ROOFS/EXT MASONRY/PARAPETS 18887000 false -73.91781691770764 40.63268510415105 6565 FLATLANDS AVENUE BROOKLYN NY 11236
M477 CIP M 2 STUYVESANT HS (NEW) EXT MASONRY/ROOFS 7752000
X240 CAP X 78 Settlement Housing PS/IS/HS New 83300000 false -73.91619367568833 40.84236125885491 1501 Jerome Ave Bronx NY 10452
X988 CAP X 78 Suspension Center - Bronx Lease 7335500 false -73.89020247936504 40.81655388322442 1231 Lafayette Ave Bronx NY 10474
X410 CIP X 9 TAFT HS PLANYC BOILER CONVERSION/PLANYC CLIMATE CTRL 10174000 false -73.9108816444482 40.84038797720987 240 172 STREET BRONX NY 10457
K485 CIP K 20 TELECOM ARTS & TECHNOLOGY H.S. EXT MASONRY 4138000 false -74.02385245520922 40.63726462862678 350 67TH ST Brooklyn NY 11220
X435 CIP X 10 THEODORE ROOSEVELT H.S. FLOORS 1593000 false -73.88817875264016 40.85990614640288 500 FORDHAM ROAD Bronx NY 10458
X435 CIP X 10 THEODORE ROOSEVELT H.S. SWB - COPPER SIDING 1500000 false -73.88817875264016 40.85990614640288 500 FORDHAM ROAD Bronx NY 10458
R455 CIP R 31 TOTTENVILLE H.S. FY10 RESO A AF REPLACEMENT 1452882 false -74.19217697672369 40.52826198723337 100 LUTEN AVENUE Staten Island NY 10312
R455 CIP R 31 TOTTENVILLE HS WINDOWS 7960000 false -74.19217697672369 40.52826198723337 100 LUTEN AVENUE Staten Island NY 10312
M971 CAP M 2 The Spruce Street Educational New 34146385.86 false -74.00596371272646 40.71174136432668 12 Spruce St New York NY 10038
M445 CIP M 2 URBAN ASSEMBLY ACADEMY GIRLS SHOWER ROOM 1014300 false -73.98959502962896 40.716852373698316 350 GRAND STREET New York NY 10002
R460 CIP R 31 WAGNER HS FY06 RESO A ATHLETIC FIELD 5799000 false -74.12366587081469 40.59771088831585 1200 MANOR ROAD Staten Island NY 10314
K805 CIP K 13 WATER'S EDGE EDUCATIONAL COMPL ELEVATOR UPGRADE 764398 false -73.98496543482732 40.69721149151847 49 FLATBUSH AVE EXTENSION BROOKLYN NY 11201
Q680 CIP Q 28 YOUNG WOMENS' LEADERSHIP SCHOO IP SURVEILLANCE CAMERAS 1047000 false -73.7875740339145 40.698104881734935 150 91 87TH ROAD JAMAICA NY 11433

View File

@ -1,4 +1,4 @@
candname officeboro canclass generalpay election totalpay primarypay officedist officecd runoffpay candid
candname officeboro canclass generalpay election totalpay primarypay officedist officecd runoffpay candid
Addabbo, Joseph P P 0 2005 0 0 32 5 0
Akbar, Celestina P 0 2005 0 0 23 5 0 884
Antoine, Royston P 0 2005 59900.00 59900.00 41 5 0 864
@ -34,4 +34,4 @@ de Blasio, Bill P 0 2005 0 0 39 5 0 326
Denis, Nelson A P 0 2005 78562.00 78562.00 8 5 0
Dickens, Inez E P 0 2005 82500.00 82500.00 9 5 0 867
Dilan, Erik M P 0 2005 0 0 37 5 0 444
Doty, Cynthia L P 0 2005 65044.00 65044.00 9 5 0 860
Doty, Cynthia L P 0 2005 65044.00 65044.00 9 5 0 860

Can't render this file because it has a wrong number of fields in line 2.

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,25 @@ p.panel-subheadline {
color: #333;
}
p.sql-statement {
font-size: 1.05em;
color: #004b87;
padding-left: 10px;
padding-top: 10px;
padding-bottom: 5px;
}
p.mimir-statement {
font-size: 1.05em;
color: #004b87;
padding-left: 10px;
padding-top: 10px;
padding-bottom: 5px;
}
h4.modal-subheadline {
}
/*
* Panels
*/

View File

@ -38,8 +38,8 @@
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
//url = "http://localhost:8080/vizier-db/doc/vizier-db.yaml";
url = "http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com/doc/vizier-db.yaml";
url = "http://localhost:8080/vizier-db/doc/vizier-db.yaml";
//url = "http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com/doc/vizier-db.yaml";
}
hljs.configure({

View File

@ -11,8 +11,8 @@ info:
schemes:
- http
host: vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com
#host: localhost:8080/vizier-db
#host: vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com
host: localhost:8080/vizier-db
basePath: /api/v1
paths:
@ -239,7 +239,10 @@ paths:
type: array
items:
$ref: "#/definitions/VizUALOperation"
links:
type: array
items:
$ref: "#/definitions/Reference"
404:
description: Notebook not found
post:
@ -282,6 +285,45 @@ paths:
description: Invalid parameters
404:
description: Notebook or branch not found
/notebooks/{notebookIdentifier}/branches/{branchIdentifier}/script/sql:
get:
summary: Get VizUAL script as SQL
description: List the sequence of operations in the VizUAL script
representing the curation workflow that represented by the
branch as SQL statements
operationId: getBranchScriptSQLExport
tags:
- branch
- script
parameters:
- name: notebookIdentifier
in: path
required: true
description: The unique notbook identifier
type: integer
format: int32
- name: branchIdentifier
in: path
required: true
description: The brnach identifier
type: integer
format: int32
responses:
200:
description: List of operations in curation workflow as SQL
statements
schema:
type: object
properties:
operations:
type: array
items:
properties:
sql:
type: string
404:
description: Notebook not found
/notebooks/{notebookIdentifier}/branches/{branchIdentifier}/script/snapshots/{snapshotIdentifier}:
delete:
summary: Delete snapshot from branch
@ -417,7 +459,11 @@ paths:
properties:
name:
type: string
refName:
label:
type: string
isUniqueName:
type: boolean
uniqueName:
type: string
rows:
type: integer
@ -487,7 +533,14 @@ definitions:
type: integer
format: int32
value:
type: string
type: object
required:
- text
properties:
text:
type: string
formula:
type: string
NotebookObject:
type: object
required:

View File

@ -25,7 +25,7 @@
<script src="./js/ie-emulation-modes-warning.js"></script>
<!-- D3.js -->
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="./js/d3.v3.min.js" charset="utf-8"></script>
<script src="./js/dagre-d3.min.js"></script>
<!-- Bootstrap core JavaScript
@ -291,5 +291,22 @@
});
});
</script>
<!-- SHOW SQL -->
<div class="modal fade" id="modal-show-sql" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">VizUAL Script - SQL Translation</h4>
</div>
<div class="modal-body" id="modal-show-sql-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body></html>

5
src/main/webapp/js/d3.v3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -17,8 +17,8 @@
*
* @type String
*/
var apiUrl = 'http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com//api/v1';
//var apiUrl = 'http://localhost:8080/vizier-db/api/v1';
//var apiUrl = 'http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com//api/v1';
var apiUrl = 'http://localhost:8080/vizier-db/api/v1';
/**
* Maintains global variables for the current notebook
@ -27,7 +27,8 @@ var apiUrl = 'http://vizirdb.7mi5uspdsy.us-west-2.elasticbeanstalk.com//api/v1';
* name: '',
* snapshot: {
* links[],
* columns: []
* columns: [],
* cells: []
* },
* script: {
* operations: []
@ -43,7 +44,58 @@ var scriptOp = -1;
* Keep track of cells being edited
*/
var editedCell = null;
var cellValue = null;
var SpreadsheetCell = function(cell, notebook) {
// Reference to the current notebook
this.notebook = notebook;
// Table cell that is being edits
this.cell = cell;
// Cell column index
this.column = cell.cellIndex - 1;
// Cell row index
this.row = cell.parentNode.rowIndex - 1;
// Set .text, .formula, and .operationType based on whether the updated
// cell is a column header or not
if (this.row === -1) {
this.text = notebook.snapshot.columns[this.column].name;
this.formula = this.text;
this.operationType = 'RENAME_COLUMN';
} else {
var value = notebook.snapshot.cells[this.column + '#' + this.row];
if (value) {
this.text = value.text;
if (value.formula) {
this.formula = value.formula;
} else {
this.formula = this.text;
}
} else {
this.text = '';
this.formula = this.text;
}
this.operationType = 'UPDATE_CELL';
}
// VizUAL statement for update operation with current user input
this.currentScript = function(text) {
switch(this.operationType){
case 'UPDATE_CELL':
var col = this.notebook.snapshot.columns[this.column];
var cellRef;
if (col.isUniqueName) {
cellRef = '[' + col.name + ', ' + this.row + ']';
} else {
cellRef = col.label + this.row;
}
if (text.trim().startsWith('=')) {
return 'UPDATE CELL ' + cellRef + ' ' + text.trim();
} else {
return 'UPDATE CELL ' + cellRef + ' = \'' + text + '\'';
}
case 'RENAME_COLUMN':
return 'RENAME COLUMN ' + this.notebook.snapshot.columns[this.column].uniqueName + ' AS ' + '\'' + text + '\'';
}
};
};
/**
* List of all uploaded files.
@ -95,10 +147,10 @@ $(function(){
$('#column-header').contextMenu({
selector: 'th',
callback: function(key, options) {
var columnIndex = $('body').data($(this).text());
var tableData = this[0];
var columnIndex = tableData.cellIndex - 1;
if (key === 'delete_column') {
var headerTitle = $(this).text();
deleteColumn(headerTitle);
deleteColumn(columnIndex);
} else if (key === 'insert_column_left') {
insertColumn(columnIndex);
} else if (key === 'insert_column_right') {
@ -147,21 +199,6 @@ $(function(){
*
*/
/**
* Get the command text for UPDATE cell command.
*
* @param {type} cell
* @param {type} text
* @returns {String}
*/
function getUpdateCellCmd(cell, text) {
return 'UPDATE CELL [' + notebook.snapshot.columns[cell.cellIndex - 1].refName +','+ (cell.parentNode.rowIndex - 1) + '] = \'' + text + '\'';
}
function getUpdateColumnText(column, text){
return 'RENAME COLUMN ' + notebook.snapshot.columns[column].refName + ' AS ' + '\'' + text + '\'';
}
function deleteRow(index){
var requestBody = {};
requestBody.type = 'DeleteRow';
@ -169,10 +206,10 @@ function deleteRow(index){
postRequest(requestBody);
}
function deleteColumn(header){
function deleteColumn(index){
var requestBody = {};
requestBody.type = 'DeleteColumn';
requestBody.parameters = [{ name: 'column', value: $('body').data(header)}];
requestBody.parameters = [{ name: 'column', value: index}];
postRequest(requestBody);
}
@ -267,19 +304,17 @@ function deleteSnapshot() {
if (op.index > 0) {
var url = getReference('script', op.links);
if (url) {
if (confirm('Do you really want to delete ' + op.text + '?')) {
$.ajax({
url: url,
type: "DELETE",
contentType: "application/json",
success: function(data) {
showNotebook(getReference('notebook', data.links));
},
error: function() {
alert('There was an error');
}
});
}
$.ajax({
url: url,
type: "DELETE",
contentType: "application/json",
success: function(data) {
showNotebook(getReference('notebook', data.links));
},
error: function() {
alert('There was an error');
}
});
}
} else {
alert('Cannot delete ' + op.text);
@ -349,19 +384,20 @@ function showNotebook(href) {
notebook.links = data.links;
// Edit notebook dropdown menu
var notebookDropdown = '<div class="btn-group" id="notebook-dropdown">' +
'<button class="btn btn-white toggle-dropdown" data-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="glyphicon glyphicon-pencil"></span></button>' +
'<button class="btn btn-white toggle-dropdown" data-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="glyphicon glyphicon-cog"></span></button>' +
'<ul class="dropdown-menu">' +
'<li><a href="#" onclick="showEditModal();">Edit Notebook</a></li>' +
'<li><a href="#" onclick="deleteNotebook();">Delete Notebook</a></li>' +
'<li><a href="#" onclick="showEditModal();"><span class="glyphicon glyphicon-pencil"></span> &nbsp;&nbsp;Edit Notebook</a></li>' +
'<li><a href="#" onclick="deleteNotebook();"><span class="glyphicon glyphicon-trash"></span> &nbsp;&nbsp;Delete Notebook</a></li>' +
'</ul>' +
'</div>';
// Textbox for users command input
var cmdInputField = '<div><div class="input-group"><span class="input-group-addon" id="basic-addon1">&gt;</span><input id="script-next-cmd" type="text" class="form-control" aria-describedby="basic-addon1"></div></div>';
// Manipulate script dorpdown menu
var scriptDropdown = '<div class="btn-group" id="script-dropdown">' +
'<button class="btn btn-invert btn-sm toggle-dropdown disabled" id="script-dropdown-btn" data-toggle="dropdown" aria-expanded="false" aria-haspopup="true"> <span class="glyphicon glyphicon-trash"></span></button>' +
'<button class="btn btn-invert btn-sm toggle-dropdown disabled" id="script-dropdown-btn" data-toggle="dropdown" aria-expanded="false" aria-haspopup="true"> <span class="glyphicon glyphicon-cog"></span></button>' +
'<ul class="dropdown-menu dropdown-menu-right">' +
'<li><a href="#" onclick="deleteSnapshot();">Delete Operation</a></li>' +
'<li><a href="#" onclick="deleteSnapshot();"><span class="glyphicon glyphicon-trash"></span> &nbsp;&nbsp;Delete Operation</a></li>' +
'<li><a href="#" onclick="showSQL();"><span class="glyphicon glyphicon-export"></span> &nbsp;&nbsp;Export as SQL</a></li>' +
'</ul>' +
'</div>';
// Put it all together
@ -424,6 +460,7 @@ function showSpreadsheet(url, op, opSize) {
if (status === 'success') {
notebook.snapshot.columns = data.columns;
notebook.snapshot.links = data.links;
notebook.snapshot.cells = {};
// Keep track of the operation in the script that is currently
// being displayed
scriptOp = op;
@ -436,21 +473,19 @@ function showSpreadsheet(url, op, opSize) {
var columns = data.columns;
for (var i_col = 0; i_col < columns.length; i_col++) {
tableHtml = tableHtml + '<th class="spreadsheet-cell">' + columns[i_col].name + '</th>';
$('body').data(columns[i_col].name, i_col);
}
tableHtml = tableHtml + '</thead></tr><tbody>';
var cells = {};
for (var i_cell = 0; i_cell < data.cells.length; i_cell++) {
var cell = data.cells[i_cell];
cells[cell.col + '#' + cell.row] = cell.value;
notebook.snapshot.cells[cell.col + '#' + cell.row] = cell.value;
}
for (var i_row = 0; i_row < data.rows; i_row++) {
tableHtml = tableHtml + '<tr><td class="row-header">' + i_row + '</td>';
for (var i_col = 0; i_col < columns.length; i_col++) {
var key = i_col + '#' + i_row;
tableHtml = tableHtml + '<td class="spreadsheet-cell">';
if (cells[key]) {
tableHtml = tableHtml + cells[key];
if (notebook.snapshot.cells[key]) {
tableHtml = tableHtml + notebook.snapshot.cells[key].text;
}
tableHtml = tableHtml + '</td>';
}
@ -461,7 +496,6 @@ function showSpreadsheet(url, op, opSize) {
$("td.spreadsheet-cell, th.spreadsheet-cell").click(function(){editSpreadsheetCell(this);});
if (op >= 0) {
for (var i_op = 0; i_op < opSize; i_op++) {
var opLink = document.getElementById('script-op-' + i_op);
if (i_op === op) {
$('#script-op-' + i_op).addClass('list-group-item-info');
} else {
@ -572,6 +606,36 @@ function showVersionGraph(url, head) {
});
}
function showSQL() {
var url = getReference('sql', notebook.script.links);
if (url) {
$.get(url, function(data, status) {
if (status === 'success') {
//var innerHtml = '<div class="sql-statement"><h4 class="modal-subheadline">SQL Statements</h4>';
var sql = '';
for (var iOp = 0; iOp < data.operations.length; iOp++) {
sql += '<p class="sql-statement">' + data.operations[iOp].sql + '</p>';
}
//innerHtml += '<h4 class="modal-subheadline">Table Statement</h4><p class="mimir-statement">' + data.mimir + '</p>';
//innerHtml += '</div>';
var innerHtml = '<div class="sql-statement"><ul class="nav nav-tabs" role="tablist">';
innerHtml += '<li role="presentation" class="active"><a href="#sql-script" aria-controls="sql-script" role="tab" data-toggle="tab">SQL Statements</a></li>';
innerHtml += '<li role="presentation"><a href="#sql-table" aria-controls="sql-table" role="tab" data-toggle="tab">Table statement</a></li>';
innerHtml += '</ul>';
innerHtml += '<div class="tab-content">';
innerHtml += '<div role="tabpanel" class="tab-pane active" id="sql-script">' + sql + '</div>';
innerHtml += '<div role="tabpanel" class="tab-pane" id="sql-table"><p class="mimir-statement">' + data.mimir + '</p></div>';
innerHtml += '</div>';
innerHtml += '</div>';
$("#modal-show-sql-body").html(innerHtml);
$('#modal-show-sql').modal('show');
}
});
}
}
/*
*
* Modify Spreadsheety (UPDATE CELL)
@ -588,10 +652,6 @@ function showVersionGraph(url, head) {
function editSpreadsheetCell(cell) {
//console.log(cell);
var operationType = 'UPDATE_CELL';
var currentScript = '';
/*
* Reset any cell that previously has been edited.
@ -600,65 +660,43 @@ function editSpreadsheetCell(cell) {
undoCellUpdate();
}
editedCell = cell;
cellValue = $(cell).html();
editedCell = new SpreadsheetCell(cell, notebook);
$(cell).off('click')
.addClass('cell')
.html('<input id="cell-textbox" class="cell form-control" type="text"/>');
$("#cell-textbox").focus().val(cellValue);
$("#cell-textbox").focus().val(editedCell.formula);
$("#cell-textbox").focusout(function() {
if ($("#cell-textbox").val() === cellValue) {
if ($("#cell-textbox").val() === editedCell.formula) {
undoCellUpdate();
} else {
submitCellUpdate(operationType);
submitCellUpdate();
}
});
$("#cell-textbox").bind('keydown', function(e) {
if(editedCell.parentNode.rowIndex === 0){
operationType = 'RENAME_COLUMN';
}
/* UNDO changes if ESC is pressed */
if (e.keyCode === 27) {
undoCellUpdate();
} else if (e.keyCode === 13) {
if ($("#cell-textbox").val() === cellValue) {
if ($("#cell-textbox").val() === editedCell.formula) {
undoCellUpdate();
} else {
submitCellUpdate(operationType);
submitCellUpdate();
}
} else {
switch(operationType){
case 'UPDATE_CELL':
currentScript = getUpdateCellCmd(editedCell, $(this).val());
break;
case 'RENAME_COLUMN':
currentScript = getUpdateColumnText($('body').data(cellValue), $(this).val());
break;
}
$('#script-next-cmd').val(currentScript);
$('#script-next-cmd').val(editedCell.currentScript($(this).val()));
}
});
$("#cell-textbox").bind('keyup', function(e) {
if (editedCell) {
switch(operationType){
case 'UPDATE_CELL':
currentScript = getUpdateCellCmd(editedCell, $(this).val());
break;
case 'RENAME_COLUMN':
currentScript = getUpdateColumnText($('body').data(cellValue), $(this).val());
break;
}
$('#script-next-cmd').val(currentScript);
$('#script-next-cmd').val(editedCell.currentScript($(this).val()));
}
});
$('#script-next-cmd').val(currentScript);
}
function submitCellUpdate(type) {
function submitCellUpdate() {
if (!editedCell) {
return;
@ -667,20 +705,16 @@ function submitCellUpdate(type) {
var requestBody = {};
requestBody.parameters = [];
if(type === 'UPDATE_CELL') {
if(editedCell.operationType === 'UPDATE_CELL') {
requestBody.type = 'UpdateCell';
requestBody.parameters[0] = {'name': 'column', 'value': (editedCell.cellIndex - 1)};
requestBody.parameters[1] = {'name': 'row', 'value': (editedCell.parentNode.rowIndex - 1)};
requestBody.parameters[0] = {'name': 'column', 'value': (editedCell.column)};
requestBody.parameters[1] = {'name': 'row', 'value': (editedCell.row)};
requestBody.parameters[2] = {'name': 'value', 'value': $("#cell-textbox").val()};
}
else if(type === 'RENAME_COLUMN'){
} else if(editedCell.operationType === 'RENAME_COLUMN'){
requestBody.type = 'RenameColumn';
var columnID = $('body').data(cellValue);
var updatedValue = $('#cell-textbox').val();
requestBody.parameters[0] = {name: 'column', value: columnID};
requestBody.parameters[1] = {name: 'name', value: updatedValue};
requestBody.parameters[0] = {name: 'column', value: editedCell.column};
requestBody.parameters[1] = {name: 'name', value: $('#cell-textbox').val()};
}
//console.log(requestBody);
undoCellUpdate();
$('body').removeData();
@ -693,12 +727,11 @@ function undoCellUpdate() {
return;
}
$(editedCell).click(function(){editSpreadsheetCell(this);})
$(editedCell.cell).click(function(){editSpreadsheetCell(this);})
.removeClass('cell')
.html(cellValue);
.html(editedCell.text);
$('#script-next-cmd').val('');
editedCell = null;
cellValue = null;
}

View File

@ -0,0 +1,102 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizier.test.database;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import java.io.File;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.SimpleVizierDBM;
import org.vizierdb.database.VizierDB;
import org.vizierdb.database.history.VersionGraph;
import org.vizierdb.database.script.VizUALScript;
import org.vizierdb.database.script.op.*;
import org.vizierdb.resources.ResourceManager;
import org.vizierdb.sql.MimirAdaptor;
import mimir.sql.SqlToRA;
/**
*
* @author oliver
*/
public class ConstructSQL {
public static final Map<String, List<String>> schemas = new HashMap<>();
public static void main(String[] args) {
JsonObject op;
// JsonObject opMoveRow = new JsonParser().parse("{\"type\":\"MoveRow\", \"parameters\": [{\"name\" : \"position\", \"value\" : \"0\"}, {\"name\" : \"row\", \"value\" : \"2\"}]}").getAsJsonObject();;
schemas.put("dual", new ArrayList<String>());
schemas.put("simple", Arrays.asList("Name","Age","Department"));
try {
SimpleVizierDBM vdb = new SimpleVizierDBM(new ResourceManager(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources")));
Notebook nb = vdb.createNotebook("My Notebook");
// 0 - LoadFile
op = new JsonParser().parse("{\"type\":\"LoadFile\", \"parameters\": [{\"name\" : \"file\", \"value\" : \"simple.csv\"}, {\"name\" : \"format\", \"value\" : \"RFC4180\"}, {\"name\" : \"headline\", \"value\" : \"true\"}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 1 - UpdateCell
op = new JsonParser().parse("{\"type\":\"UpdateCell\", \"parameters\": [{\"name\" : \"row\", \"value\" : \"0\"}, {\"name\" : \"column\", \"value\" : \"0\"}, {\"name\" : \"value\", \"value\" : \"99\" }]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 2 - DeleteColumn
op = new JsonParser().parse("{\"type\":\"DeleteColumn\", \"parameters\": [{\"name\" : \"column\", \"value\" : \"1\"}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 3 - InsertColumn
op = new JsonParser().parse("{\"type\":\"InsertColumn\", \"parameters\": [{\"name\" : \"name\", \"value\" : \"Derived\"},{\"name\" : \"position\", \"value\" : 2}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 4 - ColumnRename
op = new JsonParser().parse("{\"type\":\"RenameColumn\", \"parameters\": [{\"name\" : \"column\", \"value\" : \"1\"},{\"name\" : \"name\", \"value\" : \"Steve\"}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 5 - RowDelete
op = new JsonParser().parse("{\"type\":\"DeleteRow\", \"parameters\": [{\"name\" : \"row\", \"value\" : \"2\"}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
// 6 - RowInsert
op = new JsonParser().parse("{\"type\":\"InsertRow\", \"parameters\": [{\"name\" : \"position\", \"value\" : \"1\"}]}").getAsJsonObject();
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, op));
printSQL(nb);
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static void printSQL(Notebook notebook) {
VersionGraph history = notebook.getHistory();
VizUALScript script = notebook.getHistory().getScript(history.getCurrentBranch().getIdentifier());
System.out.println("------------");
mimir.algebra.Operator raTree = MimirAdaptor.compileToRA(script, schemas);
System.out.println(raTree.toString());
String sql = MimirAdaptor.compileToSQL(raTree, schemas);
System.out.println(sql);
}
}

View File

@ -0,0 +1,58 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizier.test.database;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.csv.CSVFormat;
import org.vizierdb.RequestParameterException;
import org.vizierdb.VizirDBException;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.SimpleVizierDBM;
import org.vizierdb.database.script.op.CSVFileLoad;
import org.vizierdb.database.script.op.CellUpdate;
import org.vizierdb.database.script.op.ColumnDelete;
import org.vizierdb.database.script.op.ColumnInsert;
import org.vizierdb.resources.ResourceManager;
import org.vizierdb.server.URLFactory;
import org.vizierdb.server.io.ResourceStreamWriter;
/**
*
* @author heiko
*/
public class DivideByZero {
public static void main(String[] args) {
try {
SimpleVizierDBM vdb = new SimpleVizierDBM(new ResourceManager(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources")));
Notebook nb = vdb.createNotebook("My Notebook");
int snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CSVFileLoad(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources/files/simple.csv"), CSVFormat.RFC4180, true)).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new ColumnInsert(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 2, "Salary")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CellUpdate(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 2, 0, "=1000/[Age,0]")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CellUpdate(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 1, 0, "0")).getHead();
StringWriter buf = new StringWriter();
try (ResourceStreamWriter writer = new ResourceStreamWriter(new OutputStreamWriter(System.out, "UTF-8"), " ")) {
writer.writeSnapshot(vdb.getSnapshot(nb.getIdentifier(), snapshotId), nb.getIdentifier(), new URLFactory("localhost"));
}
} catch (IOException | VizirDBException | RequestParameterException ex) {
Logger.getLogger(DivideByZero.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizier.test.database;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.csv.CSVFormat;
import org.vizierdb.RequestParameterException;
import org.vizierdb.VizirDBException;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.SimpleVizierDBM;
import org.vizierdb.database.script.op.CSVFileLoad;
import org.vizierdb.database.script.op.CellUpdate;
import org.vizierdb.database.script.op.ColumnDelete;
import org.vizierdb.database.script.op.ColumnInsert;
import org.vizierdb.resources.ResourceManager;
import org.vizierdb.server.URLFactory;
import org.vizierdb.server.io.ResourceStreamWriter;
/**
*
* @author heiko
*/
public class FormulaDependencies {
public static void main(String[] args) {
try {
SimpleVizierDBM vdb = new SimpleVizierDBM(new ResourceManager(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources")));
Notebook nb = vdb.createNotebook("My Notebook");
int snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CSVFileLoad(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources/files/simple.csv"), CSVFormat.RFC4180, true)).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new ColumnInsert(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 2, "Salary")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CellUpdate(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 2, 0, "=[Age,0]*1000")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new ColumnInsert(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 3, "Tax")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new CellUpdate(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 3, 0, "=[Salary,0]*0.001")).getHead();
snapshotId = vdb.executeOperation(nb.getIdentifier(), 0, new ColumnDelete(vdb.getSnapshot(nb.getIdentifier(), snapshotId), 1)).getHead();
/*StringWriter buf = new StringWriter();
try (ResourceStreamWriter writer = new ResourceStreamWriter(new OutputStreamWriter(System.out, "UTF-8"), " ")) {
writer.writeSnapshot(vdb.getSnapshot(nb.getIdentifier(), snapshotId), nb.getIdentifier(), new URLFactory("localhost"));
}*/
} catch (IOException | VizirDBException | RequestParameterException ex) {
Logger.getLogger(FormulaDependencies.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

View File

@ -0,0 +1,43 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizier.test.database;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import org.vizierdb.database.Notebook;
import org.vizierdb.database.SimpleVizierDBM;
import org.vizierdb.database.VizierDB;
import org.vizierdb.resources.ResourceManager;
/**
*
* @author heiko
*/
public class LoadCampaignPayments {
public static void main(String[] args) {
JsonObject opLoadFile = new JsonParser().parse("{\"type\":\"LoadFile\", \"parameters\": [{\"name\" : \"file\", \"value\" : \"9mjx-v8ip.tsv\"}, {\"name\" : \"format\", \"value\" : \"TDF\"}, {\"name\" : \"headline\", \"value\" : \"true\"}]}").getAsJsonObject();
try {
SimpleVizierDBM vdb = new SimpleVizierDBM(new ResourceManager(new File("/home/heiko/work/src/curation/vizir/vizier-db/src/main/webapp/WEB-INF/resources")));
Notebook nb = vdb.createNotebook("My Notebook");
// 0
vdb.executeOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), vdb.createOperation(nb.getIdentifier(), nb.getHistory().getCurrentBranch().getIdentifier(), VizierDB.UNKNOWN_SNAPSHOT, opLoadFile));
} catch (Exception exception) {
exception.printStackTrace();
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vizier.test.database;
import org.vizierdb.database.Column;
/**
*
* @author heiko
*/
public class ValidColumnName {
public static void main(String[] args) {
System.out.println(Column.VALID_NAME_REGEX.matcher("candname").matches());
}
}