I'm using Zend Framework version 1.7.8.
I am trying to create a class that extends from Zend_Db_Table_Abstract:
class My_Model_Table extends Zend_Db_Table_Abstract {
public function __construct($tableName) {
parent::__construct(array('name' => $tableName, 'primary' => 'dummy', 'db' => Zend_Registry::get('dbAdapter')));
}
}
However, when I try to fetch from this table:
$table = new My_Model_Table('dual');
Zend_Debug::dump($table->fetchAll());
I am getting this exception:
Primary key column(s) (dummy) are not columns in this table (DUMMY)
For those of you not familiar with Oracle, the DUAL table is a standard Oracle table which has only one column: DUMMY. From what I can see in the error message, ZF is trying to fetch from the "DUMMY" table which doesn't exist. Am I right? What am I doing wrong?
Thanks!
Have you tried:
Class VCCE_Model_Table extends Zend_Db_Table_Abstract {
protected $_name = 'DUAL';
}
$table = new VCCE_Model_Table();
Zend_Debug::dump($table->fetchAll());
Note: in your example you use two different names for your table VCCE_Model_Table and My_Model_Table.
Did you check the configuration settings for dbAdapter?
Related
I'm developing my first Shopware 6 admin plugin, for which is required to extend one of the existing Shopware plugins - Custom products.
I want to add a relation between already existing entities - TemplateExclusion and TemplateOptionDefinition. When I select from the UI my options, TemplateExclusion entity its getting saved in the database, without any problems.
When I save the Template entity (parent of TemplateExclusion), my "excluded_option_id" its getting overwritten with the 1st possible option from TemplateOptionDefinition entities.
I have notice that this is happening on "mergeVersion". Also when I try to save the Template entity with debug mode enabled and profiler, I'm getting an error during saving, that "excludedOptionId" is blank when merging, which is not true.
Error in profiler
Following the documentation I made first the migration:
class Migration1643023742TemplateExclusionRelation extends MigrationStep
{
public function getCreationTimestamp(): int
{
return 1643023742;
}
public function update(Connection $connection): void
{
$connection->executeStatement('ALTER TABLE `swag_customized_products_template_exclusion` ADD COLUMN `excluded_option_id` BINARY(16) AFTER `template_version_id`;');
$connection->executeStatement('ALTER TABLE `swag_customized_products_template_exclusion` ADD COLUMN `excluded_option_version_id` BINARY(16) AFTER `excluded_option_id`;');
$connection->executeStatement('ALTER TABLE `swag_customized_products_template_exclusion` ADD CONSTRAINT `fk.swag_cupr_template_exclusion.excluded_option_id` FOREIGN KEY (`excluded_option_id`, `excluded_option_version_id`)
REFERENCES `swag_customized_products_template_option` (`id`, `version_id`) ON DELETE CASCADE ON UPDATE CASCADE;');
}
then I made an entity extension, where to define the new fields.
class TemplateExclusionExtension extends EntityExtension
{
public function extendFields(FieldCollection $collection): void
{
$collection->add(
(new FkField('excluded_option_id', 'excludedOptionId', TemplateOptionDefinition::class))
->addFlags(new Required(), new ApiAware())
);
$collection->add(
(new ManyToOneAssociationField('excludedOption', 'excluded_option_id', TemplateOptionDefinition::class))
->addFlags(new ApiAware())
);
$collection->add(
(new ReferenceVersionField(TemplateOptionDefinition::class, 'excluded_option_version_id'))
->addFlags(new Required(), new ApiAware()),
);
}
public function getDefinitionClass(): string
{
return TemplateExclusionDefinition::class;
}
}
Solved:
It was wrong definition from my side:
public function extendFields(FieldCollection $collection): void
{
$collection->add(
(new FkField('excluded_option_id', 'excludedOptionId', TemplateOptionDefinition::class))
->addFlags(new Required(), new ApiAware())
);
$collection->add(
(new OneToOneAssociationField(
EasyExtendCustomizedProducts::TEMPLATE_EXCLUSION_EXCLUDED_OPTION_EXTENSION,
'excluded_option_id',
'id',
TemplateOptionDefinition::class,
false
))->addFlags(new CascadeDelete(), new ApiAware())
);
}
public function getDefinitionClass(): string
{
return TemplateExclusionDefinition::class;
}
If I'm not mistaken the issue was the missing CascadeDelete delete flag.
To versionize the entity it is first fetched including its associated data and is then persisted with new primary keys, so basically it gets cloned. However not all associations are taken into account when fetching the data to be cloned. You can find the responsible code here, where the affected associations get filtered by the existence of the CascadeDelete flag. If they miss the flag they will be ignored for creating the cloned version. This behavior still needs to be documented more prominently.
I have this PostFactory.php file in database->factories directory:
<?php
namespace Database\Factories;
use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Post::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'title' => $this->faker->sentence,
'message' => $this->faker->paragraph
];
}
}
Now, when I run this command
Post::factory()->create();
from the tinker
I got that error message
Class 'Database/Factories/User' not found
:( Is there anything I am missing?
You need to import the User Model.
For Laravel 8, Your PostFactory.php file should look like so;
<?php
namespace Database\Factories;
use App\Models\User;
use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Post::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'title' => $this->faker->sentence,
'message' => $this->faker->paragraph
];
}
}
check laravel docs on writing factories for more info.
UPDATE:
As for the error here on prnt (picked it up in the comments), You will need to provide more information.
However to start you up consider checking your database for:
A post that does not have a user_id. I.e one that you might have added before adding the foreign key constraint and therefore does not belong to any user.
If that's the case consider removing it or use tinker to manually assign a foreign key(i.e associate the post with a user) then try and create factories again. As you are trying to enforce a required column to existing data that does not already have it.
FYI just run:
composer dump-autoload
It can be that the class is not autoloaded.
As i Also had same Issue .First i changed my factory name same as name of model . Like if we have Blog Model .. We will make BlogFactory . so it can find the name of factory .
So I have a very simple table I made in SQL using h2
CREATE TABLE USERS(
username varchar(255) NOT NULL,
password varchar(255),
);
I'm trying to use javalite to add an entry to it so I made this following the instructions on the site.
package DBTEST;
import org.javalite.activejdbc.Base;
public class makeDB {
public static void main(String[] args) {
Base.open("org.h2.Driver", "jdbc:h2:./test", "sa", "");
User e = new User();
e.set("username", "John");
e.set("password", "Doe");
e.saveIt();
User.findAll().dump();
Base.close();
}
}
I have a class Users for this table
package DBTEST;
import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.annotations.Table;
#Table("USERS")
public class User extends Model {
}
I keep getting this exception
Exception in thread "main" org.javalite.activejdbc.DBException: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "USERS" not found; SQL statement:
Can anyone help? I have no idea why this is happening
First, your SQL has an extra comma in "CREATE USERS" statement. The errors says: "able "USERS" not found" - this mean you simply do not have a table!
Second, the table definition is missing an id, please see https://javalite.io/surrogate_primary_keys
Third, I created a simple example project and added your code there. It is working as expected. The project can be found here: https://github.com/javalite/h2-example
The output from running this program looks like this:
Model: activejdbc.examples.simple.User, table: 'users', attributes: {ID=1, PASSWORD=Doe, USERNAME=John}
which is exactly as expected.
Additionally, the #Table annotation is not necessary: https://javalite.io/english_inflections
I'm very new to Laravel and Database and I'm trying to understand how to insert data into my database. Please be patient the question can sounds dummy for you.
STEP
I created a table in migrations. Example of a table:
public function up(){
Schema::create('job-urls', function (Blueprint $table) {
$table->increments('id');
$table->foreign('job_id')->references('id')->on('jobs');
$table->string('url')->index();
$table->string('hash');
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
STEP
I have two csv file that correspond to the field url and hash and I want to insert them. I created a new file in migration called populate_jobs_url
class PopulateJoburls extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up(){
$fileurls = fopen('../data/urls.csv', 'r');
$filehash = fopen('../data/urls_hash.csv', 'r');
while (($row = fgetcsv($fileurls, 0, ',')) !=FALSE){
DB::table('joburls')->insert(
array(
'url' => $row,
)
);
}
while (($row = fgetcsv($filehash, 0, ',')) !=FALSE){
DB::table('joburls')->insert(
array(
'hash' => $row,
)
);
}
}
Can you help me to understand how I check if the table is correctly filled? Is this approach correct? How could I insert data otherwise in my Database? Unfortunately all examples on the web deal with inserting manually data with a form.
Thanks
Seeding the table inside of a migration file is not the best practise. You can take advantage of Seeders, which is right way to fill your table with test or actual data.
First, create a seeder file with php artisan make:seeder PopulateJobUrls command. Then you can arrange your seeder like this:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PopulateJobUrls extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$fileurls = fopen('../data/urls.csv', 'r');
$filehash = fopen('../data/urls_hash.csv', 'r');
// Rest of your seeding logic...
}
}
You should reference your seeder from database/seeds/DatabaseSeeder.php in the run method:
$this->call(PopulateJobUrls::class);
Run php artisan db:seed or if you want to be more specific, php artisan db:seed --class=PopulateJobUrls and you are good to go with your correctly filled data!
I am developing a site in which nhibernate is using. that is working fine for static mapping. but problem that i apply this application on existing database. so is there any way that mapping of classes took place at run time. i mean user provide tables and column names for mapping. Thanks
From your question I interpret you saying that the POCO classes exists, but you don't know the table or column names at build time.
So, if you already had this class:
public class MyGenericClass
{
public virtual long Id { get; set; }
public virtual string Title { get; set; }
}
You could bind it to a table and columns at runtime:
string tableName; // Set somewhere else by user input
string idColumnName; // Set somewhere else by user input
string titleColumnName; // Set somewhere else by user input
var configuration = new NHibernate.Cfg.Configuration();
configuration.Configure();
var mapper = new NHibernate.Mapping.ByCode.ModelMapper();
mapper.Class<MyGenericClass>(
classMapper =>
{
classMapper.Table(tableName);
classMapper.Id(
myGenericClass => myGenericClass.Id,
idMapper =>
{
idMapper.Column(idColumnName);
idMapper.Generator(Generators.Identity);
}
);
classMapper.Property(c => c.Title,
propertyMapper =>
{
propertyMapper.Column(titleColumnName);
}
);
}
);
ISessionFactory sessionFactory = configuration.BuildSessionFactory();
ISession session = sessionFactory.OpenSession();
////////////////////////////////////////////////////////////////////
// Now we can run an SQL query over this newly specified table
//
List<MyGenericClass> items = session.QueryOver<MyGenericClass>().List();
I don't think that could be possibly with NHibernate, but you could use a workaround.
You could use a view instead a table for the NHibernate mapping.
And in runtime, you could create that View or update it with the especified user mapping you need.
For example, you define a mapping in NHibernate to a view named ViewMapped with two columns Name and Mail.
And in the other hand, the user has a table with three columns Name, SecondName, EMail.
you can create a view on runtime with the following select:
(SELECT Name + ' ' + SecondName as Name, EMail as Mail FROM tableName) AS ViewMapped
I hope that helps you, or at least leads you to a solution.