-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #184 from jphp-compiler/dbal-extension
Implement basic sql extension.
- Loading branch information
Showing
30 changed files
with
1,430 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule docs
updated
from 99e969 to 3fe946
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
jphp-runtime/src/php/runtime/memory/support/operation/map/PropertiesMemoryOperation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package php.runtime.memory.support.operation.map; | ||
|
||
import php.runtime.Memory; | ||
import php.runtime.common.HintType; | ||
import php.runtime.env.Environment; | ||
import php.runtime.env.TraceInfo; | ||
import php.runtime.lang.ForeachIterator; | ||
import php.runtime.memory.ArrayMemory; | ||
import php.runtime.memory.StringMemory; | ||
import php.runtime.memory.support.MemoryOperation; | ||
import php.runtime.reflection.ParameterEntity; | ||
|
||
import java.util.Map; | ||
import java.util.Properties; | ||
|
||
public class PropertiesMemoryOperation extends MemoryOperation<Properties> { | ||
@Override | ||
public Class<?>[] getOperationClasses() { | ||
return new Class<?>[] { Properties.class }; | ||
} | ||
|
||
@Override | ||
public Properties convert(Environment env, TraceInfo trace, Memory arg) throws Throwable { | ||
Properties properties = new Properties(); | ||
|
||
ForeachIterator iterator = arg.getNewIterator(env); | ||
|
||
while (iterator.next()) { | ||
if (iterator.getValue().isNull()) { | ||
properties.setProperty(iterator.getKey().toString(), null); | ||
} else { | ||
properties.setProperty(iterator.getKey().toString(), iterator.getValue().toString()); | ||
} | ||
} | ||
|
||
return properties; | ||
} | ||
|
||
@Override | ||
public Memory unconvert(Environment env, TraceInfo trace, Properties arg) throws Throwable { | ||
ArrayMemory result = new ArrayMemory(true); | ||
|
||
for (Map.Entry<Object, Object> entry : arg.entrySet()) { | ||
result.putAsKeyString( | ||
entry.getKey().toString(), | ||
entry.getValue() == null ? Memory.NULL : StringMemory.valueOf(entry.getValue().toString()) | ||
); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
public void applyTypeHinting(ParameterEntity parameter) { | ||
parameter.setType(HintType.ARRAY); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
dependencies { | ||
compile project(':jphp-runtime') | ||
compile 'org.apache.commons:commons-lang3:3.4' | ||
|
||
testCompile 'org.xerial:sqlite-jdbc:3.8.7' | ||
testCompile 'junit:junit:4.+' | ||
testCompile project(':jphp-zend-ext') | ||
testCompile project(':jphp-core').sourceSets.test.output | ||
} |
26 changes: 26 additions & 0 deletions
26
jphp-sql-ext/src/main/java/org/develnext/jphp/ext/sql/SqlExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.develnext.jphp.ext.sql; | ||
|
||
import org.develnext.jphp.ext.sql.classes.*; | ||
import php.runtime.env.CompileScope; | ||
import php.runtime.ext.support.Extension; | ||
|
||
import java.sql.SQLException; | ||
|
||
public class SqlExtension extends Extension { | ||
public static final String NS = "php\\sql"; | ||
|
||
@Override | ||
public Status getStatus() { | ||
return Status.EXPERIMENTAL; | ||
} | ||
|
||
@Override | ||
public void onRegister(CompileScope scope) { | ||
registerJavaException(scope, WrapSqlException.class, SQLException.class); | ||
|
||
registerClass(scope, PSqlResult.class); | ||
registerClass(scope, PSqlStatement.class); | ||
registerClass(scope, PSqlConnection.class); | ||
registerClass(scope, PSqlDriverManager.class); | ||
} | ||
} |
198 changes: 198 additions & 0 deletions
198
jphp-sql-ext/src/main/java/org/develnext/jphp/ext/sql/classes/PSqlConnection.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
package org.develnext.jphp.ext.sql.classes; | ||
|
||
import org.develnext.jphp.ext.sql.SqlExtension; | ||
import php.runtime.Memory; | ||
import php.runtime.annotation.Reflection.*; | ||
import php.runtime.env.Environment; | ||
import php.runtime.lang.BaseObject; | ||
import php.runtime.memory.ArrayMemory; | ||
import php.runtime.memory.LongMemory; | ||
import php.runtime.memory.ReferenceMemory; | ||
import php.runtime.reflection.ClassEntity; | ||
|
||
import java.sql.*; | ||
|
||
@Abstract | ||
@Name("SqlConnection") | ||
@Namespace(SqlExtension.NS) | ||
public class PSqlConnection extends BaseObject { | ||
public static final int TRANSACTION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED; | ||
public static final int TRANSACTION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED; | ||
public static final int TRANSACTION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ; | ||
public static final int TRANSACTION_NONE = Connection.TRANSACTION_NONE; | ||
public static final int TRANSACTION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE; | ||
|
||
protected Connection connection; | ||
protected DatabaseMetaData metaData; | ||
|
||
public PSqlConnection(Environment env, Connection connection) { | ||
super(env); | ||
this.connection = connection; | ||
try { | ||
this.metaData = connection.getMetaData(); | ||
} catch (SQLException e) { | ||
throw new WrapSqlException(env, e); | ||
} | ||
} | ||
|
||
public PSqlConnection(Environment env, ClassEntity clazz) { | ||
super(env, clazz); | ||
} | ||
|
||
@Setter | ||
public void setAutoCommit(boolean value) throws SQLException { | ||
connection.setAutoCommit(value); | ||
} | ||
|
||
@Getter | ||
public boolean getAutoCommit() throws SQLException { | ||
return connection.getAutoCommit(); | ||
} | ||
|
||
@Setter | ||
public void setReadOnly(boolean value) throws SQLException { | ||
connection.setReadOnly(value); | ||
} | ||
|
||
@Getter | ||
public boolean getReadOnly() throws SQLException { | ||
return connection.isReadOnly(); | ||
} | ||
|
||
@Setter | ||
public void setTransactionIsolation(int value) throws SQLException { | ||
connection.setTransactionIsolation(value); | ||
} | ||
|
||
@Getter | ||
public int getTransactionIsolation() throws SQLException { | ||
return connection.getTransactionIsolation(); | ||
} | ||
|
||
@Setter | ||
public void setCatalog(String value) throws SQLException { | ||
connection.setCatalog(value); | ||
} | ||
|
||
@Getter | ||
public String getCatalog() throws SQLException { | ||
return connection.getCatalog(); | ||
} | ||
|
||
@Signature | ||
public Memory getCatalogs(Environment env) throws SQLException { | ||
ResultSet catalogs = metaData.getCatalogs(); | ||
ArrayMemory r = new ArrayMemory(); | ||
|
||
while (catalogs.next()) { | ||
r.add(new PSqlResult(env, catalogs).toArray(env)); | ||
} | ||
|
||
return r.toConstant(); | ||
} | ||
|
||
@Signature | ||
public Memory getSchemas(Environment env) throws SQLException { | ||
ResultSet schemas = metaData.getSchemas(); | ||
ArrayMemory r = new ArrayMemory(); | ||
|
||
while (schemas.next()) { | ||
r.add(new PSqlResult(env, schemas).toArray(env)); | ||
} | ||
|
||
return r.toConstant(); | ||
} | ||
|
||
@Signature | ||
public Memory getMetaData() throws SQLException { | ||
ArrayMemory r = new ArrayMemory(); | ||
r.refOfIndex("userName").assign(metaData.getUserName()); | ||
|
||
r.refOfIndex("driverName").assign(metaData.getDriverName()); | ||
r.refOfIndex("driverVersion").assign(metaData.getDriverVersion()); | ||
r.refOfIndex("databaseName").assign(metaData.getDatabaseProductName()); | ||
r.refOfIndex("databaseVersion").assign(metaData.getDatabaseProductVersion()); | ||
|
||
r.refOfIndex("catalogSeparator").assign(metaData.getCatalogSeparator()); | ||
r.refOfIndex("catalogTerm").assign(metaData.getCatalogTerm()); | ||
r.refOfIndex("schemaTerm").assign(metaData.getSchemaTerm()); | ||
r.refOfIndex("procedureTerm").assign(metaData.getProcedureTerm()); | ||
r.refOfIndex("searchStringEscape").assign(metaData.getSearchStringEscape()); | ||
|
||
r.refOfIndex("numericFunctions").assign(metaData.getNumericFunctions()); | ||
r.refOfIndex("stringFunctions").assign(metaData.getStringFunctions()); | ||
r.refOfIndex("timeDateFunctions").assign(metaData.getTimeDateFunctions()); | ||
r.refOfIndex("systemFunctions").assign(metaData.getSystemFunctions()); | ||
|
||
r.refOfIndex("defaultTransactionIsolation").assign(metaData.getDefaultTransactionIsolation()); | ||
r.refOfIndex("identifierQuoteString").assign(metaData.getIdentifierQuoteString()); | ||
|
||
r.refOfIndex("maxBinaryLiteralLength").assign(metaData.getMaxBinaryLiteralLength()); | ||
r.refOfIndex("maxCatalogNameLength").assign(metaData.getMaxCatalogNameLength()); | ||
r.refOfIndex("maxCharLiteralLength").assign(metaData.getMaxCharLiteralLength()); | ||
r.refOfIndex("maxConnections").assign(metaData.getMaxConnections()); | ||
|
||
r.refOfIndex("maxColumnNameLength").assign(metaData.getMaxColumnNameLength()); | ||
r.refOfIndex("maxColumnsInGroupBy").assign(metaData.getMaxColumnsInGroupBy()); | ||
r.refOfIndex("maxColumnsInIndex").assign(metaData.getMaxColumnsInIndex()); | ||
r.refOfIndex("maxColumnsInOrderBy").assign(metaData.getMaxColumnsInOrderBy()); | ||
r.refOfIndex("maxColumnsInSelect").assign(metaData.getMaxColumnsInSelect()); | ||
r.refOfIndex("maxColumnsInTable").assign(metaData.getMaxColumnsInTable()); | ||
|
||
r.refOfIndex("maxCursorNameLength").assign(metaData.getMaxCursorNameLength()); | ||
r.refOfIndex("maxIndexLength").assign(metaData.getMaxIndexLength()); | ||
r.refOfIndex("maxProcedureNameLength").assign(metaData.getMaxProcedureNameLength()); | ||
r.refOfIndex("maxRowSize").assign(metaData.getMaxRowSize()); | ||
r.refOfIndex("maxSchemaNameLength").assign(metaData.getMaxSchemaNameLength()); | ||
r.refOfIndex("maxStatementLength").assign(metaData.getMaxStatementLength()); | ||
|
||
r.refOfIndex("maxTableNameLength").assign(metaData.getMaxTableNameLength()); | ||
r.refOfIndex("maxTablesInSelect").assign(metaData.getMaxTablesInSelect()); | ||
|
||
return r.toConstant(); | ||
} | ||
|
||
@Signature | ||
public PSqlStatement query(Environment env, String sql) throws Throwable { | ||
return query(env, sql, null); | ||
} | ||
|
||
@Signature | ||
public PSqlStatement query(Environment env, String sql, @Nullable ArrayMemory args) throws Throwable { | ||
PreparedStatement statement = connection.prepareStatement(sql); | ||
PSqlStatement sqlStatement = new PSqlStatement(env, statement); | ||
|
||
if (args != null) { | ||
int index = 0; | ||
|
||
for (ReferenceMemory arg : args) { | ||
env.invokeMethod(sqlStatement, "bind", LongMemory.valueOf(index), arg.value); | ||
index += 1; | ||
} | ||
} | ||
|
||
return sqlStatement; | ||
} | ||
|
||
@Signature | ||
public String identifier(String value) throws SQLException { | ||
String identifierQuoteString = connection.getMetaData().getIdentifierQuoteString(); | ||
|
||
return identifierQuoteString + value + identifierQuoteString; | ||
} | ||
|
||
@Signature | ||
public void close() throws SQLException { | ||
connection.close(); | ||
} | ||
|
||
@Signature | ||
public void rollback() throws SQLException { | ||
connection.rollback(); | ||
} | ||
|
||
@Signature | ||
public void commit() throws SQLException { | ||
connection.commit(); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
jphp-sql-ext/src/main/java/org/develnext/jphp/ext/sql/classes/PSqlDriverManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.develnext.jphp.ext.sql.classes; | ||
|
||
import org.develnext.jphp.ext.sql.SqlExtension; | ||
import php.runtime.annotation.Reflection; | ||
import php.runtime.annotation.Reflection.Signature; | ||
import php.runtime.env.Environment; | ||
import php.runtime.lang.BaseObject; | ||
import php.runtime.reflection.ClassEntity; | ||
|
||
import java.sql.DriverManager; | ||
import java.sql.SQLException; | ||
import java.util.Properties; | ||
|
||
@Reflection.Name("SqlDriverManager") | ||
@Reflection.Namespace(SqlExtension.NS) | ||
final public class PSqlDriverManager extends BaseObject { | ||
public PSqlDriverManager(Environment env, ClassEntity clazz) { | ||
super(env, clazz); | ||
} | ||
|
||
@Signature | ||
private void __construct() {} | ||
|
||
@Signature | ||
public static void install(String dbName) throws SQLException { | ||
dbName = dbName.toLowerCase(); | ||
|
||
String driverClass; | ||
|
||
if ("db2".equals(dbName)) { | ||
driverClass = "COM.ibm.db2.jdbc.app.DB2Driver"; | ||
} else if ("mysql".equals(dbName)) { | ||
driverClass = "com.mysql.jdbc.Driver"; | ||
} else if ("psql".equals(dbName) || "postgres".equals(dbName) || "postgresql".equals(dbName)) { | ||
driverClass = "org.postgresql.Driver"; | ||
} else if ("mssql".equals(dbName)) { | ||
driverClass = "com.microsoft.jdbc.sqlserver.SQLServerDriver"; | ||
} else if ("sybase".equals(dbName)) { | ||
driverClass = "ncom.sybase.jdbc2.jdbc.SybDriver"; | ||
} else if ("firebird".equals(dbName)) { | ||
driverClass = "org.firebirdsql.jdbc.FBDriver"; | ||
} else if ("hsql".equals(dbName)) { | ||
driverClass = "org.hsql.jdbcDriver"; | ||
} else if ("interbase".equals(dbName)) { | ||
driverClass = "interbase.interclient.Driver"; | ||
} else if ("sqlite".equals(dbName)) { | ||
driverClass = "org.sqlite.JDBC"; | ||
} else { | ||
driverClass = dbName; | ||
} | ||
|
||
try { | ||
Class.forName(driverClass); | ||
} catch (ClassNotFoundException e) { | ||
throw new SQLException("Driver class '" + driverClass + "' is not found in classpath"); | ||
} | ||
} | ||
|
||
@Signature | ||
public static PSqlConnection getConnection(Environment env, String url) throws SQLException { | ||
return getConnection(env, url, null); | ||
} | ||
|
||
@Signature | ||
public static PSqlConnection getConnection(Environment env, String url, Properties properties) throws SQLException { | ||
return new PSqlConnection(env, DriverManager.getConnection("jdbc:" + url, properties == null ? new Properties() : properties)); | ||
} | ||
} |
Oops, something went wrong.